Skip to content

Commit 3d455d7

Browse files
committed
feat: support work template
1 parent 4aac184 commit 3d455d7

File tree

12 files changed

+350
-23
lines changed

12 files changed

+350
-23
lines changed

back-end/h5-api/api/work/config/routes.json

+16
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,22 @@
7171
"config": {
7272
"policies": []
7373
}
74+
},
75+
{
76+
"method": "POST",
77+
"path": "/works/set-as-template/:id",
78+
"handler": "Work.setAsTemplate",
79+
"config": {
80+
"policies": []
81+
}
82+
},
83+
{
84+
"method": "POST",
85+
"path": "/works/use-template/:id",
86+
"handler": "Work.useTemplate",
87+
"config": {
88+
"policies": []
89+
}
7490
}
7591
]
7692
}

back-end/h5-api/api/work/controllers/Work.js

+16
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,20 @@ module.exports = {
4949
// eslint-disable-next-line require-atomic-updates
5050
return ctx.body = { uuidMap2Name, formDetails };
5151
},
52+
setAsTemplate: async (ctx) => {
53+
let work = await strapi.services.work.findOne(ctx.params);
54+
work = work.toJSON();
55+
56+
// eslint-disable-next-line no-unused-vars
57+
const templateWork = await strapi.services.work.create();
58+
return strapi.services.work.update({id: templateWork.id}, { pages: work.pages, is_template: true });
59+
},
60+
useTemplate: async (ctx) => {
61+
let templateWork = await strapi.services.work.findOne(ctx.params);
62+
templateWork = templateWork.toJSON();
63+
64+
// eslint-disable-next-line no-unused-vars
65+
const work = await strapi.services.work.create();
66+
return strapi.services.work.update({id: work.id}, { pages: templateWork.pages, is_template: false });
67+
},
5268
};

back-end/h5-api/api/work/models/Work.js

+24-13
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@
77
module.exports = {
88
// Before saving a value.
99
// Fired before an `insert` or `update` query.
10-
beforeSave: async (model, attrs, options) => {
11-
// https://github.com/strapi/strapi/issues/2882
12-
// need to remove this after this pr will be merged(https://github.com/strapi/strapi/pull/3664)
13-
Object.keys(model.constructor.attributes).forEach(k => {
14-
if (model.constructor.attributes[k].type === 'json') {
15-
const value = model.get(k);
10+
// beforeSave: async (model, attrs, options) => {
11+
// // https://github.com/strapi/strapi/issues/2882
12+
// // need to remove this after this pr will be merged(https://github.com/strapi/strapi/pull/3664)
13+
// Object.keys(model.constructor.attributes).forEach(k => {
14+
// if (model.constructor.attributes[k].type === 'json') {
15+
// const value = model.get(k);
1616

17-
if (Array.isArray(value)) {
18-
model.set(k, JSON.stringify(value));
19-
}
20-
}
21-
});
22-
},
17+
// if (Array.isArray(value)) {
18+
// model.set(k, JSON.stringify(value));
19+
// }
20+
// }
21+
// });
22+
// },
2323

2424
// After saving a value.
2525
// Fired after an `insert` or `update` query.
@@ -48,6 +48,7 @@ module.exports = {
4848
elements: []
4949
}];
5050
model.set('pages', JSON.stringify(defaultPages));
51+
model.set('is_template', false);
5152
},
5253

5354
// After creating a value.
@@ -56,7 +57,17 @@ module.exports = {
5657

5758
// Before updating a value.
5859
// Fired before an `update` query.
59-
// beforeUpdate: async (model, attrs, options) => {},
60+
// beforeUpdate: async (model, attrs, options) => {
61+
// Object.keys(model.constructor.attributes).forEach(k => {
62+
// if (model.constructor.attributes[k].type === 'json') {
63+
// const value = model.get(k);
64+
65+
// if (Array.isArray(value)) {
66+
// model.set(k, JSON.stringify(value));
67+
// }
68+
// }
69+
// });
70+
// },
6071

6172
// After updating a value.
6273
// Fired after an `update` query.

back-end/h5-api/api/work/models/Work.settings.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@
3535
"update_time": {
3636
"type": "date"
3737
},
38-
"pages": {
38+
"formData": {
3939
"type": "json"
4040
},
41-
"formData": {
41+
"is_template": {
42+
"type": "boolean"
43+
},
44+
"pages": {
4245
"type": "json"
4346
}
4447
}

front-end/h5/src/components/core/editor/index.js

+30-3
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ export default {
100100
work: state => state.work
101101
}),
102102
...mapState('loading', {
103-
saveWork_loading: state => state.saveWork_loading
103+
saveWork_loading: state => state.saveWork_loading,
104+
setWorkAsTemplate_loading: state => state.setWorkAsTemplate_loading
104105
})
105106
},
106107
methods: {
@@ -109,8 +110,12 @@ export default {
109110
'pageManager',
110111
'saveWork',
111112
'createWork',
112-
'fetchWork'
113+
'fetchWork',
114+
'setWorkAsTemplate'
113115
]),
116+
...mapActions('loading', {
117+
updateLoading: 'update'
118+
}),
114119
/**
115120
* !#zh 点击插件,copy 其基础数据到组件树(中间画布)
116121
* #!en click the plugin shortcut, create new Element with the plugin's meta data
@@ -165,7 +170,29 @@ export default {
165170
>
166171
<a-menu-item key="1" class="transparent-bg"><a-button type="primary" size="small" onClick={() => { this.previewVisible = true }}>预览</a-button></a-menu-item>
167172
<a-menu-item key="2" class="transparent-bg"><a-button size="small" onClick={() => this.saveWork()} loading={this.saveWork_loading}>保存</a-button></a-menu-item>
168-
<a-menu-item key="3" class="transparent-bg"><a-button size="small">发布</a-button></a-menu-item>
173+
{/* <a-menu-item key="3" class="transparent-bg"><a-button size="small">发布</a-button></a-menu-item> */}
174+
<a-menu-item key="3" class="transparent-bg">
175+
<a-dropdown-button onClick={() => {}} size="small">
176+
发布
177+
<a-menu slot="overlay" onClick={({ key }) => {
178+
switch (key) {
179+
case 'setAsTemplate':
180+
this.updateLoading({ type: 'setWorkAsTemplate_loading', value: true })
181+
this.saveWork().then(() => {
182+
this.setWorkAsTemplate()
183+
})
184+
}
185+
}}>
186+
<a-menu-item key="setAsTemplate">
187+
<a-spin spinning={this.setWorkAsTemplate_loading} size="small">
188+
<a-icon type="cloud-upload" />设置为模板
189+
</a-spin>
190+
</a-menu-item>
191+
{/* <a-menu-item key="2"><a-icon type="user" />2nd menu item</a-menu-item> */}
192+
{/* <a-menu-item key="3"><a-icon type="user" />3rd item</a-menu-item> */}
193+
</a-menu>
194+
</a-dropdown-button>
195+
</a-menu-item>
169196
</a-menu>
170197
<ExternalLinksOfHeader />
171198
</a-layout-header>

front-end/h5/src/router.js

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ export default new Router({
2020
name: 'work-manager-list',
2121
component: () => import('@/views/work-manager/list.vue')
2222
},
23+
{
24+
path: '/work-manager/templates',
25+
name: 'work-manager-templates',
26+
component: () => import('@/views/work-manager/templates.vue')
27+
},
2328
{
2429
path: '/work-manager/form-stat',
2530
name: 'form-stat',

front-end/h5/src/store/modules/editor.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ const state = {
1313
formDetailOfWork: {
1414
uuidMap2Name: {},
1515
formDetails: []
16-
}
16+
},
17+
workTemplates: []
1718
}
1819

1920
// getters

front-end/h5/src/store/modules/loading.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// initial state
22
const state = {
33
saveWork_loading: false,
4-
fetchWorks_loading: false
4+
fetchWorks_loading: false,
5+
setWorkAsTemplate_loading: false,
6+
fetchWorkTemplates_loading: false,
7+
useTemplate_loading: false
58
}
69

710
// getters

front-end/h5/src/store/modules/work.js

+41-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const actions = {
1313
},
1414
createWork ({ commit }, payload) {
1515
strapi.createEntry('works').then(entry => {
16+
commit('setWork', entry)
1617
router.replace({ name: 'editor', params: { workId: entry.id } })
1718
// window.location = `${window.location.origin}/#/editor/${entry.id}`
1819
})
@@ -35,7 +36,7 @@ export const actions = {
3536
...payload
3637
}
3738

38-
new AxiosWrapper({
39+
return new AxiosWrapper({
3940
dispatch,
4041
commit,
4142
loading_name: 'saveWork_loading',
@@ -57,7 +58,17 @@ export const actions = {
5758
loading_name: 'fetchWorks_loading',
5859
successMsg: '获取作品列表成功',
5960
customRequest: strapi.getEntries.bind(strapi)
60-
}).get('works', {})
61+
}).get('works', { is_template: false })
62+
},
63+
fetchWorkTemplates ({ commit, dispatch, state }, workId) {
64+
new AxiosWrapper({
65+
dispatch,
66+
commit,
67+
name: 'editor/setWorkTemplates',
68+
loading_name: 'fetchWorkTemplates_loading',
69+
successMsg: '获取模板列表成功',
70+
customRequest: strapi.getEntries.bind(strapi)
71+
}).get('works', { is_template: true })
6172
},
6273
/**
6374
*
@@ -128,6 +139,24 @@ export const actions = {
128139
loading_name: 'queryFormsOfWork_loading',
129140
successMsg: '表单查询完毕'
130141
}).get(`/works/form/query/${workId}`)
142+
},
143+
setWorkAsTemplate ({ commit, state, dispatch }, workId) {
144+
new AxiosWrapper({
145+
dispatch,
146+
commit,
147+
// name: 'editor/formDetailOfWork',
148+
loading_name: 'setWorkAsTemplate_loading',
149+
successMsg: '设置为模板成功'
150+
}).post(`/works/set-as-template/${workId || state.work.id}`)
151+
},
152+
useTemplate ({ commit, state, dispatch }, workId) {
153+
return new AxiosWrapper({
154+
dispatch,
155+
commit,
156+
// name: 'editor/formDetailOfWork',
157+
loading_name: 'useTemplate_loading',
158+
successMsg: '使用模板成功'
159+
}).post(`/works/use-template/${workId}`)
131160
}
132161
}
133162

@@ -143,6 +172,16 @@ export const mutations = {
143172
value.sort((a, b) => b.id - a.id)
144173
state.works = value
145174
},
175+
/**
176+
* payload: {
177+
* type: @params {String} "editor/setWorks",
178+
* value: @params {Array} work list
179+
* }
180+
*/
181+
setWorkTemplates (state, { type, value }) {
182+
value.sort((a, b) => b.id - a.id)
183+
state.workTemplates = value
184+
},
146185
setWork (state, work) {
147186
window.__work = work
148187
work.pages = work.pages.map(page => {

front-end/h5/src/utils/http.js

+9
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ export class AxiosWrapper {
4343
this.setDefaultLoadingName(args)
4444

4545
this.setLoadingValue(true)
46+
if (this.customRequest) {
47+
return this.customRequest(...args)
48+
.then(data => {
49+
const handler = this.getCommonResponseHandler({ failMsg: 'Save Failed.' })
50+
handler.call(this, { status: 200, data })
51+
})
52+
.finally(() => this.setLoadingValue(false))
53+
}
4654
return this.instance.get(...args).then(response => {
4755
const handler = this.getCommonResponseHandler({ failMsg: 'Query Failed.' })
4856
handler.call(this, response)
@@ -59,6 +67,7 @@ export class AxiosWrapper {
5967
return this.instance.post(...args).then(response => {
6068
const handler = this.getCommonResponseHandler({ failMsg: 'Save Failed.' })
6169
handler.call(this, response)
70+
return response.data
6271
}).catch(error => {
6372
// handle error
6473
myMessage.error(error.message)

front-end/h5/src/views/work-manager/index.vue

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ const sidebarMenus = [
3838
label: '免费模板',
3939
value: 'freeTemplates',
4040
antIcon: 'snippets',
41-
key: '3-1'
41+
key: '3-1',
42+
routerName: 'work-manager-templates'
4243
}
4344
]
4445
},

0 commit comments

Comments
 (0)