Skip to content

Commit dbf78ab

Browse files
committed
feat(feat): 用户素材
1 parent 964977d commit dbf78ab

16 files changed

+749
-44
lines changed

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
"@vueuse/core": "^10.1.0",
2222
"axios": "^1.3.4",
2323
"color-gradient-picker-vue3": "^2.0.7",
24+
"dayjs": "^1.11.11",
2425
"events": "^3.3.0",
2526
"fabric": "^5.2.1",
2627
"fontfaceobserver": "^2.1.0",
2728
"lodash-es": "^4.17.21",
2829
"number-precision": "^1.6.0",
30+
"qs": "^6.12.1",
2931
"uuid": "^8.3.2",
3032
"view-ui-plus": "^1.3.7",
3133
"vue": "^3.2.25",

packages/core/ServersPlugin.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @Author: 秦少卫
33
* @Date: 2023-06-20 12:52:09
44
* @LastEditors: 秦少卫
5-
* @LastEditTime: 2024-04-29 11:56:32
5+
* @LastEditTime: 2024-05-11 14:19:33
66
* @Description: 内部插件
77
*/
88
import { v4 as uuid } from 'uuid';
@@ -274,6 +274,7 @@ class ServersPlugin {
274274
this.canvas.remove(obj);
275275
}
276276
});
277+
this.editor?.setWorkspaseBg('#fff');
277278
this.canvas.discardActiveObject();
278279
this.canvas.renderAll();
279280
}

packages/core/plugin/MaterialPlugin.ts

+34-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @Author: 秦少卫
33
* @Date: 2023-08-04 21:13:16
44
* @LastEditors: 秦少卫
5-
* @LastEditTime: 2024-05-09 15:03:37
5+
* @LastEditTime: 2024-05-11 14:20:26
66
* @Description: 素材插件
77
*/
88

@@ -16,7 +16,13 @@ class MaterialPlugin {
1616
public canvas: fabric.Canvas;
1717
public editor: IEditor;
1818
static pluginName = 'MaterialPlugin';
19-
static apis = ['getTemplTypeList', 'getTemplList', 'getMaterialTypeList', 'getMaterialList'];
19+
static apis = [
20+
'getTemplTypeList',
21+
'getTemplList',
22+
'getMaterialTypeList',
23+
'getMaterialList',
24+
'getSizeList',
25+
];
2026
apiMapUrl: { [propName: string]: string };
2127
repoSrc: string;
2228
constructor(canvas: fabric.Canvas, editor: IEditor, config: { repoSrc: string }) {
@@ -139,6 +145,32 @@ class MaterialPlugin {
139145
});
140146
}
141147

148+
getSizeList() {
149+
return axios.get(`${this.repoSrc}/api/sizes?pagination[pageSize]=100`).then((res) => {
150+
const list = res.data.data.map((item: any) => {
151+
return {
152+
value: item.id,
153+
name: item.attributes.name,
154+
width: Number(item.attributes.width),
155+
height: Number(item.attributes.height),
156+
unit: item.attributes.unit,
157+
};
158+
});
159+
return list;
160+
});
161+
}
162+
getFontList() {
163+
return axios.get(`${this.repoSrc}/api/fonts?pagination[pageSize]=100`).then((res) => {
164+
const list = res.data.data.map((item: any) => {
165+
return {
166+
value: item.id,
167+
label: item.attributes.name,
168+
};
169+
});
170+
return list;
171+
});
172+
}
173+
142174
_getMaterialInfoUrl(info: any) {
143175
const imgUrl = info?.data?.attributes?.url || '';
144176
return this.repoSrc + imgUrl;

packages/core/plugin/WorkspacePlugin.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @Author: 秦少卫
33
* @Date: 2023-06-27 12:26:41
44
* @LastEditors: 秦少卫
5-
* @LastEditTime: 2024-05-07 16:28:40
5+
* @LastEditTime: 2024-05-11 14:18:13
66
* @Description: 画布区域插件
77
*/
88

@@ -16,7 +16,7 @@ class WorkspacePlugin {
1616
public editor: IEditor;
1717
static pluginName = 'WorkspacePlugin';
1818
static events = ['sizeChange'];
19-
static apis = ['big', 'small', 'auto', 'one', 'setSize', 'getWorkspase'];
19+
static apis = ['big', 'small', 'auto', 'one', 'setSize', 'getWorkspase', 'setWorkspaseBg'];
2020
workspaceEl!: HTMLElement;
2121
workspace: null | fabric.Rect;
2222
option: any;
@@ -198,6 +198,11 @@ class WorkspacePlugin {
198198
this.canvas.requestRenderAll();
199199
}
200200

201+
setWorkspaseBg(color: string) {
202+
const workspase = this.getWorkspase();
203+
workspase?.set('fill', color);
204+
}
205+
201206
_bindWheel() {
202207
this.canvas.on('mouse:wheel', function (this: fabric.Canvas, opt) {
203208
const delta = opt.e.deltaY;

src/api/user.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @Author: 秦少卫
33
* @Date: 2024-04-24 14:07:06
44
* @LastEditors: 秦少卫
5-
* @LastEditTime: 2024-04-29 12:13:51
5+
* @LastEditTime: 2024-05-11 14:47:44
66
* @Description: 用户接口登录
77
*/
88

@@ -51,3 +51,18 @@ export const createdMaterial = (data: any) => instance.post('/api/user-materials
5151

5252
// 删除素材
5353
export const removeMaterial = (id: any) => instance.delete('/api/user-materials/' + id);
54+
55+
// 创建模板
56+
export const createdTempl = (data: any) => instance.post('/api/user-templs', data);
57+
58+
// 删除素材
59+
export const removeTempl = (data: any) => instance.delete(`/api/user-templs/${data}`);
60+
61+
// 更新素材
62+
export const updataTempl = (id: any, data: any) => instance.put(`/api/user-templs/${id}`, data);
63+
64+
// 查询素材列表
65+
export const getTmplList = (data: any) => instance.get(`/api/user-templs?${data}`);
66+
67+
// 查询素材列表
68+
export const getTmplInfo = (data: any) => instance.get(`/api/user-templs/${data}`);

src/components/importJSON.vue

+103-5
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,119 @@
22
* @Author: 秦少卫
33
* @Date: 2022-09-03 19:16:55
44
* @LastEditors: 秦少卫
5-
* @LastEditTime: 2024-04-22 16:26:27
5+
* @LastEditTime: 2024-05-11 13:34:51
66
* @Description: 导入JSON文件
77
-->
88

99
<template>
1010
<div style="display: inline-block">
11-
<Button @click="insert" type="text" size="small">{{ $t('import_files') }}</Button>
11+
<Dropdown @on-click="clickHandler">
12+
<a href="javascript:void(0)">
13+
{{ $t('importFiles.file') }}
14+
<Icon type="ios-arrow-down"></Icon>
15+
</a>
16+
<template #list>
17+
<DropdownMenu>
18+
<DropdownItem name="createDesign">
19+
{{ $t('importFiles.createDesign.title') }}
20+
</DropdownItem>
21+
<DropdownItem name="importFiles">{{ $t('importFiles.importFiles') }}</DropdownItem>
22+
</DropdownMenu>
23+
</template>
24+
</Dropdown>
25+
26+
<!-- 创建设计 -->
27+
<Modal v-model="modal" :title="$t('importFiles.createDesign.title')" footer-hide>
28+
<h3>
29+
{{ $t('importFiles.createDesign.customSize') }}
30+
</h3>
31+
<Form ref="formInline" inline :label-width="40">
32+
<FormItem label="宽度">
33+
<InputNumber v-model="width" :min="1" placeholder="请输入"></InputNumber>
34+
</FormItem>
35+
<FormItem label="高度">
36+
<InputNumber v-model="height" :min="1" placeholder="请输入"></InputNumber>
37+
</FormItem>
38+
<FormItem :label-width="0">
39+
<Button type="primary" @click="customSizeCreate">
40+
{{ $t('importFiles.createDesign.create') }}
41+
</Button>
42+
</FormItem>
43+
</Form>
44+
<Divider class="divider" />
45+
<h3>
46+
{{ $t('importFiles.createDesign.systemSize') }}
47+
</h3>
48+
<CellGroup @on-click="setSize">
49+
<Cell
50+
:title="item.name"
51+
:label="`${item.width}x${item.height}${item.unit}`"
52+
:arrow="false"
53+
:key="item.name"
54+
:name="`${item.width}x${item.height}x${item.unit}`"
55+
v-for="item in sizeList"
56+
>
57+
<template #extra>
58+
<Icon type="md-add" />
59+
</template>
60+
</Cell>
61+
</CellGroup>
62+
</Modal>
1263
</div>
1364
</template>
1465

1566
<script name="ImportJson" setup>
1667
import useSelect from '@/hooks/select';
17-
68+
import useMaterial from '@/hooks/useMaterial';
69+
import { Message } from 'view-ui-plus';
1870
const { canvasEditor } = useSelect();
19-
const insert = () => {
20-
canvasEditor.insert();
71+
const { createTmpl, routerToId } = useMaterial();
72+
73+
const clickHandler = (type) => {
74+
const handleMap = {
75+
// 导入文件
76+
importFiles: canvasEditor.insert,
77+
// 创建文件
78+
createDesign,
79+
};
80+
handleMap[type]?.();
81+
};
82+
83+
const modal = ref(false);
84+
const width = ref(null);
85+
const height = ref(null);
86+
const sizeList = ref([]);
87+
const createDesign = () => {
88+
width.value = null;
89+
height.value = null;
90+
// 获取素材
91+
canvasEditor.getSizeList().then((res) => {
92+
sizeList.value = res;
93+
});
94+
modal.value = true;
95+
};
96+
const setSize = (itemString) => {
97+
const [w, h] = itemString.split('x');
98+
width.value = Number(w);
99+
height.value = Number(h);
100+
};
101+
102+
const customSizeCreate = async () => {
103+
if (width.value && height.value) {
104+
const res = await createTmpl(width.value, height.value);
105+
routerToId(res.data.data.id);
106+
modal.value = false;
107+
Message.success('创建成功');
108+
} else {
109+
Message.warning('请检查尺寸');
110+
}
21111
};
22112
</script>
113+
<style scoped lang="less">
114+
h3 {
115+
margin-bottom: 10px;
116+
}
117+
.divider {
118+
margin-top: 0;
119+
}
120+
</style>

src/components/importTmpl.vue

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @Author: 秦少卫
33
* @Date: 2022-09-03 19:16:55
44
* @LastEditors: 秦少卫
5-
* @LastEditTime: 2024-05-09 14:51:32
5+
* @LastEditTime: 2024-05-11 14:07:09
66
* @Description: 导入模板
77
-->
88

@@ -72,7 +72,8 @@
7272
import useSelect from '@/hooks/select';
7373
import { Spin, Modal } from 'view-ui-plus';
7474
import { useI18n } from 'vue-i18n';
75-
75+
import { useRouter } from 'vue-router';
76+
const router = useRouter();
7677
const { t } = useI18n();
7778
const { canvasEditor } = useSelect();
7879

@@ -163,6 +164,7 @@ const getTempData = (json) => {
163164
Spin.show({
164165
render: (h) => h('div', t('alert.loading_data')),
165166
});
167+
router.replace('/');
166168
canvasEditor.loadJSON(JSON.stringify(json), Spin.hide);
167169
};
168170
</script>

src/components/myMaterial/index.vue

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<!--
2+
* @Author: 秦少卫
3+
* @Date: 2024-04-25 15:30:54
4+
* @LastEditors: 秦少卫
5+
* @LastEditTime: 2024-05-11 15:50:32
6+
* @Description: 我的素材
7+
-->
8+
9+
<template>
10+
<div class="my-material" v-if="isLogin">
11+
<Tabs size="small" v-model="type">
12+
<TabPane label="模板" name="templ">
13+
<myTempl v-if="type === 'templ'"></myTempl>
14+
</TabPane>
15+
<TabPane label="图片" name="img">
16+
<uploadMaterial v-if="type === 'img'"></uploadMaterial>
17+
</TabPane>
18+
</Tabs>
19+
</div>
20+
<div class="tip" v-else>请先登录</div>
21+
</template>
22+
23+
<script setup name="ImportTmpl">
24+
import { getFileList } from '@/api/user';
25+
import uploadMaterial from './uploadMaterial';
26+
import myTempl from './myTempl';
27+
28+
const type = ref('templ');
29+
const isLogin = ref(false);
30+
const getFileListHandle = () => {
31+
// 获取素材列表
32+
getFileList()
33+
.then((res) => {
34+
isLogin.value = true;
35+
})
36+
.catch(() => {
37+
isLogin.value = false;
38+
});
39+
};
40+
41+
getFileListHandle();
42+
</script>
43+
44+
<style scoped lang="less">
45+
.my-material {
46+
padding-top: 10px;
47+
}
48+
.tip {
49+
padding: 20px;
50+
text-align: center;
51+
}
52+
</style>

0 commit comments

Comments
 (0)