Commit 39d9f8fdcce6dcbaafd765986a55ffeaa58e4b6a

Authored by ly525
1 parent 1102fe32

feat(preview): build preview engine

back-end/h5-api/api/work/config/routes.json
... ... @@ -47,6 +47,14 @@
47 47 "config": {
48 48 "policies": []
49 49 }
  50 + },
  51 + {
  52 + "method": "GET",
  53 + "path": "/works/preview/:id",
  54 + "handler": "Work.previewOne",
  55 + "config": {
  56 + "policies": []
  57 + }
50 58 }
51 59 ]
52 60 }
... ...
back-end/h5-api/api/work/controllers/Work.js
... ... @@ -5,4 +5,10 @@
5 5 * to customize this controller
6 6 */
7 7  
8   -module.exports = {};
  8 +module.exports = {
  9 + // GET /previewOne
  10 + // strapi-hook-ejs: https://github.com/strapi/strapi/tree/master/packages/strapi-hook-ejs
  11 + previewOne: async (ctx) => {
  12 + return ctx.render('engine', {work: { page2: []}});
  13 + }
  14 +};
... ...
back-end/h5-api/config/hook.json
... ... @@ -6,5 +6,13 @@
6 6 "Define the hooks' load order by putting their names in this array in the right order"
7 7 ],
8 8 "after": []
  9 + },
  10 + "ejs": {
  11 + "enabled": true,
  12 + "viewExt": "ejs",
  13 + "partial": true,
  14 + "cache": false,
  15 + "debug": true,
  16 + "layout": false
9 17 }
10 18 }
... ...
back-end/h5-api/package.json
... ... @@ -18,20 +18,22 @@
18 18 "eslint-plugin-react": "^7.14.0"
19 19 },
20 20 "dependencies": {
  21 + "ejs": "^2.6.2",
  22 + "knex": "latest",
21 23 "lodash": "^4.17.5",
  24 + "sqlite3": "latest",
22 25 "strapi": "3.0.0-beta.13",
23 26 "strapi-admin": "3.0.0-beta.13",
24   - "strapi-utils": "3.0.0-beta.13",
25   - "strapi-plugin-settings-manager": "3.0.0-beta.13",
26   - "strapi-plugin-content-type-builder": "3.0.0-beta.13",
  27 + "strapi-hook-bookshelf": "3.0.0-beta.13",
  28 + "strapi-hook-ejs": "^3.0.0-alpha.26.2",
  29 + "strapi-hook-knex": "3.0.0-beta.13",
27 30 "strapi-plugin-content-manager": "3.0.0-beta.13",
28   - "strapi-plugin-users-permissions": "3.0.0-beta.13",
  31 + "strapi-plugin-content-type-builder": "3.0.0-beta.13",
29 32 "strapi-plugin-email": "3.0.0-beta.13",
  33 + "strapi-plugin-settings-manager": "3.0.0-beta.13",
30 34 "strapi-plugin-upload": "3.0.0-beta.13",
31   - "strapi-hook-bookshelf": "3.0.0-beta.13",
32   - "strapi-hook-knex": "3.0.0-beta.13",
33   - "knex": "latest",
34   - "sqlite3": "latest"
  35 + "strapi-plugin-users-permissions": "3.0.0-beta.13",
  36 + "strapi-utils": "3.0.0-beta.13"
35 37 },
36 38 "author": {
37 39 "name": "A Strapi developer"
... ...
back-end/h5-api/views/engine-example.ejs 0 → 100644
  1 +<html>
  2 + <head>
  3 + <title>Luban H5 Preview</title>
  4 + </head>
  5 + <script>window.__work = <%- JSON.stringify(work) %></script>
  6 + <body>
  7 + Q: What's this?
  8 + A: A tiny render engine based on ejs for Luban H5 work
  9 + </body>
  10 +</html>
0 11 \ No newline at end of file
... ...
front-end/h5/public/engine-example.html 0 → 100644
  1 +<!DOCTYPE html>
  2 +<html lang="en">
  3 + <head>
  4 + <meta charset="utf-8">
  5 + <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6 + <meta name="viewport" content="width=device-width,initial-scale=1.0">
  7 + <title>work.html</title>
  8 + <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  9 + <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
  10 + <meta content="yes" name="apple-mobile-web-app-capable">
  11 + <meta content="black" name="apple-mobile-web-app-status-bar-style">
  12 + <meta content="telephone=no" name="format-detection">
  13 + <meta content="email=no" name="format-detection">
  14 + <script type="text/javascript" src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/flexible.js"></script>
  15 + <!-- <link rel="stylesheet" href="/be-static/be-static-luban-h5/engine/engine.css"> -->
  16 + <!-- <script src="/be-static/be-static-luban-h5/engine/engine.js"></script> -->
  17 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/css/swiper.min.css">
  18 + <link rel="stylesheet" href="https://meyerweb.com/eric/tools/css/reset/reset.css">
  19 + <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/js/swiper.min.js"></script>
  20 + <style>
  21 + .swiper-container {
  22 + width: 100%;
  23 + height: 100vh;
  24 + }
  25 + </style>
  26 + <script>
  27 + window.__work = {"id":12,"title":"default title","description":"default desc","cover_image_url":null,"is_publish":null,"create_time":"2019-07-21 06:07:44","update_time":"2019-07-21 06:07:44","pages":[{"elements":[{"name":"lbp-button","uuid":1563721976946,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]},{"elements":[]},{"elements":[]},{"elements":[{"name":"lbp-button","uuid":1563721991112,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]},{"elements":[{"name":"lbp-button","uuid":1563721995650,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]}],"created_at":"2019-07-21T06:07:44.636Z","updated_at":"2019-07-21T06:07:44.636Z"}
  28 + </script>
  29 + </head>
  30 + <body>
  31 + <noscript>
  32 + <strong>We're sorry but luban-h5 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
  33 + </noscript>
  34 + <div id="app"></div>
  35 + <!-- built files will be auto injected -->
  36 + <script>
  37 + var mySwiper = new Swiper('.swiper-container', {
  38 + // Optional parameters
  39 + direction: 'vertical',
  40 + loop: false,
  41 + // If we need pagination
  42 + pagination: {
  43 + el: '.swiper-pagination',
  44 + },
  45 + // Navigation arrows
  46 + navigation: {
  47 + nextEl: '.swiper-button-next',
  48 + prevEl: '.swiper-button-prev',
  49 + },
  50 + // And if we need scrollbar
  51 + scrollbar: {
  52 + el: '.swiper-scrollbar',
  53 + },
  54 + });
  55 + </script>
  56 + </body>
  57 +</html>
... ...
front-end/h5/public/engine.html 0 → 100644
  1 +<!DOCTYPE html>
  2 +<html lang="en">
  3 + <head>
  4 + <meta charset="utf-8">
  5 + <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6 + <meta name="viewport" content="width=device-width,initial-scale=1.0">
  7 + <title>work.html</title>
  8 + <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  9 + <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
  10 + <meta content="yes" name="apple-mobile-web-app-capable">
  11 + <meta content="black" name="apple-mobile-web-app-status-bar-style">
  12 + <meta content="telephone=no" name="format-detection">
  13 + <meta content="email=no" name="format-detection">
  14 + <script type="text/javascript" src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/flexible.js"></script>
  15 + <!-- <link rel="stylesheet" href="/be-static/be-static-luban-h5/engine/engine.css"> -->
  16 + <!-- <script src="/be-static/be-static-luban-h5/engine/engine.js"></script> -->
  17 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/css/swiper.min.css">
  18 + <link rel="stylesheet" href="https://meyerweb.com/eric/tools/css/reset/reset.css">
  19 + <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/js/swiper.min.js"></script>
  20 + <style>
  21 + .swiper-container {
  22 + width: 100%;
  23 + height: 100vh;
  24 + }
  25 + </style>
  26 + <!-- <script>
  27 + window.__work = {"id":12,"title":"default title","description":"default desc","cover_image_url":null,"is_publish":null,"create_time":"2019-07-21 06:07:44","update_time":"2019-07-21 06:07:44","pages":[{"elements":[{"name":"lbp-button","uuid":1563721976946,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]},{"elements":[]},{"elements":[]},{"elements":[{"name":"lbp-button","uuid":1563721991112,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]},{"elements":[{"name":"lbp-button","uuid":1563721995650,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]}],"created_at":"2019-07-21T06:07:44.636Z","updated_at":"2019-07-21T06:07:44.636Z"}
  28 + </script> -->
  29 + </head>
  30 + <body>
  31 + <noscript>
  32 + <strong>We're sorry but luban-h5 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
  33 + </noscript>
  34 + <div id="app"></div>
  35 + <!-- built files will be auto injected -->
  36 + <script>
  37 + var mySwiper = new Swiper('.swiper-container', {
  38 + // Optional parameters
  39 + direction: 'vertical',
  40 + loop: false,
  41 + // If we need pagination
  42 + pagination: {
  43 + el: '.swiper-pagination',
  44 + },
  45 + // Navigation arrows
  46 + navigation: {
  47 + nextEl: '.swiper-button-next',
  48 + prevEl: '.swiper-button-prev',
  49 + },
  50 + // And if we need scrollbar
  51 + scrollbar: {
  52 + el: '.swiper-scrollbar',
  53 + },
  54 + });
  55 + </script>
  56 + </body>
  57 +</html>
... ...
front-end/h5/src/components/core/editor/engine/index.js 0 → 100644
  1 +/**
  2 + * 作品预览的渲染引擎,其实就是简单遍历 pages 以及 elements,显示即可
  3 + */
  4 +import Vue from 'vue'
  5 +import Antd from 'ant-design-vue'
  6 +import 'ant-design-vue/dist/antd.css'
  7 +import 'font-awesome/css/font-awesome.min.css'
  8 +import loadPluginMixin from '../../../../mixins/load-plugins.js'
  9 +import Element from '../../models/element'
  10 +
  11 +Vue.config.productionTip = false
  12 +Vue.use(Antd)
  13 +const Engine = {
  14 + name: 'engine',
  15 + mixins: [loadPluginMixin],
  16 + methods: {
  17 + renderPreview (h, _elements) {
  18 + const elements = _elements.map(element => new Element(element))
  19 + return (
  20 + <div style={{ height: '100%', position: 'relative' }}>
  21 + {
  22 + elements.map((element, index) => {
  23 + const style = element.getStyle({ position: 'absolute' })
  24 + const data = {
  25 + style,
  26 + props: element.getProps({ mode: 'preview' })
  27 + }
  28 + return h(element.name, data)
  29 + })
  30 + }
  31 + </div>
  32 + )
  33 + }
  34 + },
  35 + render (h) {
  36 + const work = window.__work
  37 + return (
  38 + <div id="work-container" data-work-id={work.id}>
  39 + <div class="swiper-container">
  40 + <div class="swiper-wrapper">{
  41 + work.pages.map(page => {
  42 + return (
  43 + <section class="swiper-slide flat">
  44 + {/* this.walk(h, page.elements) */}
  45 + { this.renderPreview(h, page.elements) }
  46 + </section>
  47 + )
  48 + })
  49 + }</div>
  50 + <div class="swiper-pagination"></div>
  51 + </div>
  52 + </div>
  53 + )
  54 + }
  55 +}
  56 +
  57 +new Vue({
  58 + components: {
  59 + engine: Engine
  60 + },
  61 + render: h => h('engine')
  62 +}).$mount('#app')
... ...
front-end/h5/vue.config.js
... ... @@ -5,5 +5,16 @@ module.exports = {
5 5 : '/',
6 6 devServer: {
7 7 proxy: 'http://localhost:1337'
  8 + },
  9 + pages: {
  10 + index: {
  11 + entry: 'src/main.js',
  12 + template: 'public/index.html',
  13 + filename: 'index.html',
  14 + title: 'Index Page'
  15 + },
  16 + engine: {
  17 + entry: 'src/components/core/editor/engine/index.js'
  18 + }
8 19 }
9 20 }
... ...