Commit 85b6cf69633b5fce386e09d5c9e8256ca770cdcd
1 parent
1beb681a
feat: support publish page !#zh: 支持发布页面
Showing
6 changed files
with
64 additions
and
17 deletions
back-end/h5-api/api/work/controllers/Work.js
| ... | ... | @@ -11,6 +11,10 @@ |
| 11 | 11 | 'use strict'; |
| 12 | 12 | const request = require('request'); |
| 13 | 13 | const _ = require('lodash'); |
| 14 | +// 浏览模式 | |
| 15 | +const VIEW_MODE = { | |
| 16 | + PREVIEW: 'preview' // 预览 | |
| 17 | +} | |
| 14 | 18 | |
| 15 | 19 | /** |
| 16 | 20 | * Read the documentation (https://strapi.io/documentation/3.0.0-beta.x/guides/controllers.html#core-controllers) |
| ... | ... | @@ -21,7 +25,12 @@ module.exports = { |
| 21 | 25 | // GET /previewOne |
| 22 | 26 | // strapi-hook-ejs: https://github.com/strapi/strapi/tree/master/packages/strapi-hook-ejs |
| 23 | 27 | previewOne: async (ctx) => { |
| 28 | + const { mode } = ctx.request.query | |
| 24 | 29 | const work = await strapi.services.work.findOne(ctx.params); |
| 30 | + // 非发布状态, 查看不到内容 | |
| 31 | + // 非预览模式, 查看不到内容 | |
| 32 | + const canRender = mode === VIEW_MODE.PREVIEW || work.is_publish | |
| 33 | + if (!canRender) work.pages = [] | |
| 25 | 34 | return ctx.render('engine', { work }); |
| 26 | 35 | }, |
| 27 | 36 | submitForm: async (ctx) => { | ... | ... |
front-end/h5/src/components/core/editor/index.js
| ... | ... | @@ -42,7 +42,7 @@ const fixedTools = [ |
| 42 | 42 | { |
| 43 | 43 | i18nTooltip: 'editor.fixedTool.preview', |
| 44 | 44 | icon: 'eye', |
| 45 | - action: function () { this.previewVisible = true } | |
| 45 | + action: function () { this.previewDialogVisible = true } | |
| 46 | 46 | }, |
| 47 | 47 | { |
| 48 | 48 | i18nTooltip: 'editor.fixedTool.copyCurrentPage', |
| ... | ... | @@ -95,7 +95,7 @@ export default { |
| 95 | 95 | activeMenuKey: 'pluginList', |
| 96 | 96 | isPreviewMode: false, |
| 97 | 97 | activeTabKey: '属性', |
| 98 | - previewVisible: false, | |
| 98 | + previewDialogVisible: false, | |
| 99 | 99 | scaleRate: 1, |
| 100 | 100 | propsPanelWidth: 320 |
| 101 | 101 | }), |
| ... | ... | @@ -121,6 +121,7 @@ export default { |
| 121 | 121 | 'saveWork', |
| 122 | 122 | 'createWork', |
| 123 | 123 | 'fetchWork', |
| 124 | + 'updateWork', | |
| 124 | 125 | 'setWorkAsTemplate', |
| 125 | 126 | 'setEditingElement', |
| 126 | 127 | 'setEditingPage' |
| ... | ... | @@ -188,6 +189,18 @@ export default { |
| 188 | 189 | </a-tab-pane> |
| 189 | 190 | </a-tabs> |
| 190 | 191 | ) |
| 192 | + }, | |
| 193 | + handlePreview () { | |
| 194 | + this.saveWork({ loadingName: 'previewWork_loading' }).then(() => { | |
| 195 | + this.previewDialogVisible = true | |
| 196 | + }) | |
| 197 | + }, | |
| 198 | + handleSave () { | |
| 199 | + this.saveWork({ isSaveCover: true }) | |
| 200 | + }, | |
| 201 | + handlePublish () { | |
| 202 | + this.updateWork({ is_publish: true }) | |
| 203 | + this.saveWork({ successMsg: '发布成功' }) | |
| 191 | 204 | } |
| 192 | 205 | }, |
| 193 | 206 | mounted () { |
| ... | ... | @@ -213,11 +226,28 @@ export default { |
| 213 | 226 | style={{ lineHeight: '64px', float: 'right', background: 'transparent' }} |
| 214 | 227 | > |
| 215 | 228 | {/* 保存、预览、发布、设置为模板 */} |
| 216 | - <a-menu-item key="1" class="transparent-bg"><a-button type="primary" size="small" onClick={() => { this.saveWork({ loadingName: 'previewWork_loading' }).then(() => { this.previewVisible = true }) }} loading={this.previewWork_loading}>{this.$t('editor.header.preview')}</a-button></a-menu-item> | |
| 217 | - <a-menu-item key="2" class="transparent-bg"><a-button size="small" onClick={() => this.saveWork({ isSaveCover: true })} loading={this.saveWork_loading || this.uploadWorkCover_loading}>{this.$t('editor.header.save')}</a-button></a-menu-item> | |
| 229 | + <a-menu-item key="1" class="transparent-bg"> | |
| 230 | + <a-button | |
| 231 | + type="primary" | |
| 232 | + size="small" | |
| 233 | + onClick={this.handlePreview} | |
| 234 | + loading={this.previewWork_loading} | |
| 235 | + >{this.$t('editor.header.preview')}</a-button> | |
| 236 | + </a-menu-item> | |
| 237 | + <a-menu-item key="2" class="transparent-bg"> | |
| 238 | + <a-button | |
| 239 | + size="small" | |
| 240 | + onClick={this.handleSave} | |
| 241 | + loading={this.saveWork_loading || this.uploadWorkCover_loading} | |
| 242 | + >{this.$t('editor.header.save')}</a-button> | |
| 243 | + </a-menu-item> | |
| 218 | 244 | {/* <a-menu-item key="3" class="transparent-bg"><a-button size="small">发布</a-button></a-menu-item> */} |
| 219 | 245 | <a-menu-item key="3" class="transparent-bg"> |
| 220 | - <a-dropdown-button onClick={() => {}} size="small"> | |
| 246 | + <a-dropdown-button | |
| 247 | + size="small" | |
| 248 | + onClick={this.handlePublish} | |
| 249 | + loading={this.saveWork_loading || this.uploadWorkCover_loading} | |
| 250 | + > | |
| 221 | 251 | {/* 发布 */} |
| 222 | 252 | {this.$t('editor.header.publish')} |
| 223 | 253 | <a-menu slot="overlay" onClick={({ key }) => { |
| ... | ... | @@ -343,8 +373,8 @@ export default { |
| 343 | 373 | { |
| 344 | 374 | <PreviewDialog |
| 345 | 375 | work={this.work} |
| 346 | - visible={this.previewVisible} | |
| 347 | - handleClose={() => { this.previewVisible = false }} | |
| 376 | + visible={this.previewDialogVisible} | |
| 377 | + handleClose={() => { this.previewDialogVisible = false }} | |
| 348 | 378 | /> |
| 349 | 379 | } |
| 350 | 380 | <Feedback /> | ... | ... |
front-end/h5/src/components/core/editor/modals/preview.vue
| ... | ... | @@ -22,7 +22,7 @@ export default { |
| 22 | 22 | // work: state => state.work |
| 23 | 23 | // }), |
| 24 | 24 | releaseUrl () { |
| 25 | - return `${window.location.origin}/works/preview/${this.work.id}` | |
| 25 | + return `${window.location.origin}/works/preview/${this.work.id}?mode=preview` | |
| 26 | 26 | } |
| 27 | 27 | }, |
| 28 | 28 | data () { |
| ... | ... | @@ -67,7 +67,7 @@ export default { |
| 67 | 67 | }, |
| 68 | 68 | openNewTab (urlType) { |
| 69 | 69 | switch (urlType) { |
| 70 | - case 'previewDebug': | |
| 70 | + case 'openPreviewPage': | |
| 71 | 71 | window.open(this.releaseUrl) |
| 72 | 72 | break |
| 73 | 73 | case 'buildEngineDocs': |
| ... | ... | @@ -152,7 +152,7 @@ export default { |
| 152 | 152 | </div> |
| 153 | 153 | </div> |
| 154 | 154 | <div style="background: #fafafa;"> |
| 155 | - <a-button type="link" icon="link" onClick={() => this.openNewTab('previewDebug')}>打开预览 URL(For Debug) </a-button> | |
| 155 | + <a-button type="link" icon="link" onClick={() => this.openNewTab('openPreviewPage')}>打开预览页面</a-button> | |
| 156 | 156 | <a-button type="link" icon="link" onClick={() => this.openNewTab('buildEngineDocs')}>如果本地预览显示空白,点此查看文档</a-button> |
| 157 | 157 | </div> |
| 158 | 158 | </div> | ... | ... |
front-end/h5/src/components/core/models/work.js
| ... | ... | @@ -30,7 +30,7 @@ class Work { |
| 30 | 30 | // this.created_at = new Date() |
| 31 | 31 | // this.updated_at = new Date() |
| 32 | 32 | |
| 33 | - this.is_publish = false | |
| 33 | + this.is_publish = !!work.is_publish | |
| 34 | 34 | this.is_template = false |
| 35 | 35 | this.height = work.height || 568 |
| 36 | 36 | this.mode = work.mode || PAGE_MODE.SWIPPER_PAGE | ... | ... |
front-end/h5/src/engine-entry.js
| ... | ... | @@ -38,6 +38,7 @@ const Engine = { |
| 38 | 38 | }, |
| 39 | 39 | methods: { |
| 40 | 40 | renderLongPage () { |
| 41 | + if (!window.__work.pages.length) return | |
| 41 | 42 | const work = window.__work |
| 42 | 43 | return this.renderPreview(work.pages[0].elements) |
| 43 | 44 | }, |
| ... | ... | @@ -59,10 +60,9 @@ const Engine = { |
| 59 | 60 | </div> |
| 60 | 61 | ) |
| 61 | 62 | }, |
| 62 | - renderPreview (pageElements) { | |
| 63 | + renderPreview (pageElements = []) { | |
| 63 | 64 | const pageWrapperStyle = this.isLongPage ? { |
| 64 | 65 | height: window.__work.height + 'px' |
| 65 | - | |
| 66 | 66 | } : {} |
| 67 | 67 | |
| 68 | 68 | const elements = pageElements.map(element => new Element(element)) |
| ... | ... | @@ -88,12 +88,20 @@ const Engine = { |
| 88 | 88 | containerStyle['overflow-y'] = 'scroll' |
| 89 | 89 | } |
| 90 | 90 | return containerStyle |
| 91 | - } | |
| 91 | + }, | |
| 92 | + renderUnPublishTip() { | |
| 93 | + return <div style="box-sizing: border-box;min-height: 568px;line-height: 568px;text-align: center;">页面可能暂未发布</div> | |
| 94 | + }, | |
| 92 | 95 | }, |
| 93 | 96 | render (h) { |
| 94 | 97 | const work = window.__work |
| 95 | - const containerStyle = this.getContainerStyle(work) | |
| 96 | 98 | |
| 99 | + // 预览模式 或者 已经发布 的页面可以正常渲染,否则提示用户暂未发布 | |
| 100 | + const query = new URLSearchParams(window.location.search) | |
| 101 | + const canRender = query.get('mode') === 'preview' || work.is_publish | |
| 102 | + if (!canRender) return this.renderUnPublishTip() | |
| 103 | + | |
| 104 | + const containerStyle = this.getContainerStyle(work) | |
| 97 | 105 | return <div id="work-container" data-work-id={work.id} style={containerStyle}> |
| 98 | 106 | { |
| 99 | 107 | this.isLongPage ? this.renderLongPage() : this.renderSwiperPage() | ... | ... |
front-end/h5/src/store/modules/work.js
| ... | ... | @@ -39,13 +39,13 @@ export const actions = { |
| 39 | 39 | * 预览作品之前需要先保存,但希望 用户点击保存按钮 和 点击预览按钮 loading_name 能够不同(虽然都调用了 saveWork) |
| 40 | 40 | * 因为 loading 效果要放在不同的按钮上 |
| 41 | 41 | */ |
| 42 | - saveWork ({ commit, dispatch, state }, { isSaveCover = false, loadingName = 'saveWork_loading' } = {}) { | |
| 42 | + saveWork ({ commit, dispatch, state }, { isSaveCover = false, loadingName = 'saveWork_loading', successMsg="保存作品成功" } = {}) { | |
| 43 | 43 | const fn = (callback) => { |
| 44 | 44 | new AxiosWrapper({ |
| 45 | 45 | dispatch, |
| 46 | 46 | commit, |
| 47 | 47 | loading_name: loadingName, |
| 48 | - successMsg: '保存作品成功', | |
| 48 | + successMsg, | |
| 49 | 49 | customRequest: strapi.updateEntry.bind(strapi) |
| 50 | 50 | }).put('works', state.work.id, state.work).then(callback) |
| 51 | 51 | } | ... | ... |