|
@@ -6,40 +6,52 @@
|
|
</div>
|
|
</div>
|
|
<t-input placeholder="搜索" />
|
|
<t-input placeholder="搜索" />
|
|
</div>
|
|
</div>
|
|
- <div class="groups">
|
|
|
|
- <div class="sub-groups">
|
|
|
|
|
|
+ <div class="groups-panel">
|
|
|
|
+ <div class="groups">
|
|
<div
|
|
<div
|
|
v-for="group in groups"
|
|
v-for="group in groups"
|
|
- :class="group.name === activeGroup ? 'active' : ''"
|
|
|
|
|
|
+ :class="group.name === activedGroup ? 'active' : ''"
|
|
@click="groupChange(group.name)"
|
|
@click="groupChange(group.name)"
|
|
>
|
|
>
|
|
<t-icon :name="group.icon" />
|
|
<t-icon :name="group.icon" />
|
|
{{ group.name }}
|
|
{{ group.name }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- <div class="list" :class="showType === 1 ? 'two-list' : ''">
|
|
|
|
- <t-collapse v-model:value="panelValue">
|
|
|
|
|
|
+ <div class="list" :class="groupType ? 'two-list' : ''">
|
|
|
|
+ <t-collapse v-model:value="activedPanel">
|
|
<t-collapse-panel
|
|
<t-collapse-panel
|
|
:value="item.name"
|
|
:value="item.name"
|
|
:header="item.name"
|
|
:header="item.name"
|
|
- v-for="item in showList"
|
|
|
|
|
|
+ v-for="item in subGroups"
|
|
:key="item.name"
|
|
:key="item.name"
|
|
>
|
|
>
|
|
<div
|
|
<div
|
|
class="show-item"
|
|
class="show-item"
|
|
- v-for="iItem in item.list"
|
|
|
|
- :draggable="true"
|
|
|
|
- @dragstart="dragStart($event, iItem)"
|
|
|
|
- @drag="drag($event, iItem)"
|
|
|
|
|
|
+ v-for="subItem in item.list"
|
|
|
|
+ :draggable="!groupType || groupType >= 10"
|
|
|
|
+ @dragstart="dragStart($event, subItem)"
|
|
|
|
+ @drag="drag($event, subItem)"
|
|
@dragend="dragEnd()"
|
|
@dragend="dragEnd()"
|
|
- @click.stop="dragStart($event, iItem)"
|
|
|
|
|
|
+ @click.stop="dragStart($event, subItem)"
|
|
|
|
+ @dblclick.stop="open(subItem)"
|
|
>
|
|
>
|
|
- <t-image v-if="iItem.image" :src="iItem.image" fit="cover" />
|
|
|
|
- <div class="svg-box" v-else-if="iItem.svg" v-html="iItem.svg" />
|
|
|
|
|
|
+ <t-image v-if="subItem.image" :src="subItem.image" fit="cover" />
|
|
|
|
+ <div
|
|
|
|
+ class="svg-box"
|
|
|
|
+ v-else-if="subItem.svg"
|
|
|
|
+ v-html="subItem.svg"
|
|
|
|
+ />
|
|
<svg v-else class="l-icon" aria-hidden="true">
|
|
<svg v-else class="l-icon" aria-hidden="true">
|
|
- <use :xlink:href="'#' + iItem.icon"></use>
|
|
|
|
|
|
+ <use :xlink:href="'#' + subItem.icon"></use>
|
|
</svg>
|
|
</svg>
|
|
- <p :title="iItem.name">{{ iItem.name }}</p>
|
|
|
|
|
|
+ <p :title="subItem.name">{{ subItem.name }}</p>
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ v-if="!item.list || !item.list.length"
|
|
|
|
+ class="gray center"
|
|
|
|
+ style="white-space: nowrap; margin-left: 32px"
|
|
|
|
+ >
|
|
|
|
+ 暂无数据,待更新
|
|
</div>
|
|
</div>
|
|
</t-collapse-panel>
|
|
</t-collapse-panel>
|
|
</t-collapse>
|
|
</t-collapse>
|
|
@@ -50,15 +62,19 @@
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
|
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
|
-import { shapeLib, chartLib, formLib } from '@/services/defaults';
|
|
|
|
|
|
+import axios from 'axios';
|
|
|
|
+
|
|
|
|
+import { cases, shapes, charts, formComponents } from '@/services/defaults';
|
|
import { getPngFolders, getPngs } from '@/services/png';
|
|
import { getPngFolders, getPngs } from '@/services/png';
|
|
import { getIconFolders, getIcons } from '@/services/icons';
|
|
import { getIconFolders, getIcons } from '@/services/icons';
|
|
import { getComponents, getComponentsList } from '@/services/api';
|
|
import { getComponents, getComponentsList } from '@/services/api';
|
|
import { convertPen } from '@/services/upgrade';
|
|
import { convertPen } from '@/services/upgrade';
|
|
import { deepClone } from '@meta2d/core';
|
|
import { deepClone } from '@meta2d/core';
|
|
import { isGif } from '@/services/utils';
|
|
import { isGif } from '@/services/utils';
|
|
|
|
+import { autoSave } from '@/services/common';
|
|
|
|
+
|
|
|
|
+const activedGroup = ref('图形');
|
|
|
|
|
|
-const activeGroup = ref('图形');
|
|
|
|
const groups = reactive([
|
|
const groups = reactive([
|
|
{
|
|
{
|
|
icon: 'desktop',
|
|
icon: 'desktop',
|
|
@@ -101,10 +117,87 @@ const groups = reactive([
|
|
key: '',
|
|
key: '',
|
|
},
|
|
},
|
|
]);
|
|
]);
|
|
|
|
+const subGroups = ref<any[]>([]);
|
|
|
|
+const groupType = ref(0);
|
|
|
|
+const activedPanel = ref([]);
|
|
|
|
|
|
-const getSceneLib = () => {};
|
|
|
|
|
|
+const templates = reactive<any>({});
|
|
|
|
+const materials = reactive([]);
|
|
|
|
+const icons = reactive([]);
|
|
|
|
+
|
|
|
|
+const groupChange = async (name: string) => {
|
|
|
|
+ activedPanel.value = [];
|
|
|
|
+ activedGroup.value = name;
|
|
|
|
+ groupType.value = 0;
|
|
|
|
+ switch (name) {
|
|
|
|
+ case '场景':
|
|
|
|
+ groupType.value = 1;
|
|
|
|
+ subGroups.value = cases;
|
|
|
|
+ if (!templates[name + cases[0].name]) {
|
|
|
|
+ templates[name + cases[0].name] = await getCaseProjects(
|
|
|
|
+ name,
|
|
|
|
+ cases[0].name
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ subGroups.value[0].list = templates[name + cases[0].name];
|
|
|
|
+ break;
|
|
|
|
+ case '模板':
|
|
|
|
+ groupType.value = 2;
|
|
|
|
+ subGroups.value = cases;
|
|
|
|
+ if (!templates[name + cases[0].name]) {
|
|
|
|
+ templates[name + cases[0].name] = await getCaseProjects(
|
|
|
|
+ name,
|
|
|
|
+ cases[0].name
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ subGroups.value[0].list = templates[name + cases[0].name];
|
|
|
|
+ break;
|
|
|
|
+ case '图表':
|
|
|
|
+ subGroups.value = charts;
|
|
|
|
+ break;
|
|
|
|
+ case '控件':
|
|
|
|
+ subGroups.value = formComponents;
|
|
|
|
+ break;
|
|
|
|
+ case '素材':
|
|
|
|
+ if (!materials.length) {
|
|
|
|
+ materials.push(...(await getPngFolders()));
|
|
|
|
+ }
|
|
|
|
+ subGroups.value = materials;
|
|
|
|
+ break;
|
|
|
|
+ case '图标':
|
|
|
|
+ if (!icons.length) {
|
|
|
|
+ icons.push(...(await getIconFolders()));
|
|
|
|
+ }
|
|
|
|
+ subGroups.value = icons;
|
|
|
|
+ break;
|
|
|
|
+ case '图形':
|
|
|
|
+ subGroups.value = shapes;
|
|
|
|
+ break;
|
|
|
|
+ case '我的':
|
|
|
|
+ subGroups.value = await getPrivateCommponents();
|
|
|
|
+ groupType.value = 10;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ activedPanel.value = [subGroups.value[0].name];
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const getCaseProjects = async (name: string, group: string) => {
|
|
|
|
+ const ret: any = await axios.post(
|
|
|
|
+ '/api/data/le5leV/list?current=1&pageSize=1000',
|
|
|
|
+ {
|
|
|
|
+ query: { tags: name, case: group },
|
|
|
|
+ shared: 'true',
|
|
|
|
+ projection: { _id: 1, name: 1, image: 1 },
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ if (!ret) {
|
|
|
|
+ return [];
|
|
|
|
+ }
|
|
|
|
+ return ret.list;
|
|
|
|
+};
|
|
|
|
|
|
-const getCommponentsLib = async () => {
|
|
|
|
|
|
+const getPrivateCommponents = async () => {
|
|
const data = {
|
|
const data = {
|
|
projection: {
|
|
projection: {
|
|
image: 1,
|
|
image: 1,
|
|
@@ -141,65 +234,8 @@ const getCommponentsLib = async () => {
|
|
return list;
|
|
return list;
|
|
};
|
|
};
|
|
|
|
|
|
-const getMaterialLib = async () => {
|
|
|
|
- const pngs = await getPngFolders();
|
|
|
|
- return pngs;
|
|
|
|
-};
|
|
|
|
-let materialLib: any[] = [];
|
|
|
|
-
|
|
|
|
-const getIconsLib = async () => {
|
|
|
|
- const icons = await getIconFolders();
|
|
|
|
- return icons;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-let iconsLib: any[] = [];
|
|
|
|
-
|
|
|
|
-const groupChange = async (name: string) => {
|
|
|
|
- panelValue.value = [];
|
|
|
|
- activeGroup.value = name;
|
|
|
|
- showType.value = 0;
|
|
|
|
- switch (name) {
|
|
|
|
- case '场景':
|
|
|
|
- showList.value = [];
|
|
|
|
- break;
|
|
|
|
- case '模板':
|
|
|
|
- showList.value = [];
|
|
|
|
- break;
|
|
|
|
- case '图表':
|
|
|
|
- showList.value = chartLib;
|
|
|
|
- break;
|
|
|
|
- case '控件':
|
|
|
|
- showList.value = formLib;
|
|
|
|
- break;
|
|
|
|
- case '素材':
|
|
|
|
- if (materialLib.length === 0) {
|
|
|
|
- materialLib = await getMaterialLib();
|
|
|
|
- }
|
|
|
|
- showList.value = materialLib;
|
|
|
|
- break;
|
|
|
|
- case '图标':
|
|
|
|
- if (iconsLib.length === 0) {
|
|
|
|
- iconsLib = await getIconsLib();
|
|
|
|
- }
|
|
|
|
- showList.value = iconsLib;
|
|
|
|
- break;
|
|
|
|
- case '图形':
|
|
|
|
- showList.value = shapeLib;
|
|
|
|
- panelValue.value = ['基本形状'];
|
|
|
|
- break;
|
|
|
|
- case '我的':
|
|
|
|
- showList.value = await getCommponentsLib();
|
|
|
|
- showType.value = 1;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-const showList = ref<any[]>([]);
|
|
|
|
-const showType = ref(0);
|
|
|
|
-const panelValue = ref([]);
|
|
|
|
-
|
|
|
|
watch(
|
|
watch(
|
|
- () => panelValue.value,
|
|
|
|
|
|
+ () => activedPanel.value,
|
|
async (newV: any[], oldV: any[]) => {
|
|
async (newV: any[], oldV: any[]) => {
|
|
const newOpen: any = [];
|
|
const newOpen: any = [];
|
|
for (let v of newV) {
|
|
for (let v of newV) {
|
|
@@ -208,28 +244,32 @@ watch(
|
|
if (newOpen.length === 0) {
|
|
if (newOpen.length === 0) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- if (activeGroup.value === '素材') {
|
|
|
|
- const data: any = materialLib.find((item) => item.name === newOpen[0]); // materialLib[newOpen[0]];
|
|
|
|
|
|
+ if (activedGroup.value === '素材') {
|
|
|
|
+ const data: any = materials.find((item) => item.name === newOpen[0]);
|
|
if (!data.list || data.list.length === 0) {
|
|
if (!data.list || data.list.length === 0) {
|
|
data.list = await getPngs(
|
|
data.list = await getPngs(
|
|
globalThis.folderJson ? data.pinyin : data.name
|
|
globalThis.folderJson ? data.pinyin : data.name
|
|
);
|
|
);
|
|
- showList.value = deepClone(materialLib);
|
|
|
|
|
|
+ subGroups.value = deepClone(materials);
|
|
}
|
|
}
|
|
- } else if (activeGroup.value === '图标') {
|
|
|
|
- const data: any = iconsLib.find((item) => item.name === newOpen[0]); // iconsLib[newOpen[0]];
|
|
|
|
|
|
+ } else if (activedGroup.value === '图标') {
|
|
|
|
+ const data: any = icons.find((item) => item.name === newOpen[0]);
|
|
if (!data.list || data.list.length === 0) {
|
|
if (!data.list || data.list.length === 0) {
|
|
data.list = await getIcons(
|
|
data.list = await getIcons(
|
|
globalThis.folderJson ? data.pinyin : data.name
|
|
globalThis.folderJson ? data.pinyin : data.name
|
|
);
|
|
);
|
|
- showList.value = deepClone(iconsLib);
|
|
|
|
|
|
+ subGroups.value = deepClone(icons);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
);
|
|
);
|
|
|
|
|
|
const dragStart = async (event: DragEvent | MouseEvent, item: any) => {
|
|
const dragStart = async (event: DragEvent | MouseEvent, item: any) => {
|
|
- if (!item || (event instanceof DragEvent && !event.dataTransfer)) {
|
|
|
|
|
|
+ if (
|
|
|
|
+ (groupType.value > 0 && groupType.value < 10) ||
|
|
|
|
+ !item ||
|
|
|
|
+ (event instanceof DragEvent && !event.dataTransfer)
|
|
|
|
+ ) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
let data = null;
|
|
let data = null;
|
|
@@ -291,22 +331,20 @@ const dragend = (event: any) => {
|
|
event.target.style.opacity = 1;
|
|
event.target.style.opacity = 1;
|
|
};
|
|
};
|
|
|
|
|
|
-//获取所有图形库
|
|
|
|
-const getGraphics = async () => {
|
|
|
|
- // if (!materialLib.length) {
|
|
|
|
- // materialLib = await getPngFolders();
|
|
|
|
- // }
|
|
|
|
|
|
+const open = (item: any) => {
|
|
|
|
+ console.log(item);
|
|
|
|
+ autoSave();
|
|
};
|
|
};
|
|
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
- groupChange('图形');
|
|
|
|
- document.removeEventListener('dragstart', dragstart);
|
|
|
|
- document.removeEventListener('dragend', dragend);
|
|
|
|
|
|
+ groupChange('场景');
|
|
|
|
+ document.addEventListener('dragstart', dragstart, false);
|
|
|
|
+ document.addEventListener('dragend', dragend, false);
|
|
});
|
|
});
|
|
|
|
|
|
onUnmounted(() => {
|
|
onUnmounted(() => {
|
|
- document.addEventListener('dragstart', dragstart, false);
|
|
|
|
- document.addEventListener('dragend', dragend, false);
|
|
|
|
|
|
+ document.removeEventListener('dragstart', dragstart);
|
|
|
|
+ document.removeEventListener('dragend', dragend);
|
|
});
|
|
});
|
|
</script>
|
|
</script>
|
|
<style lang="postcss" scoped>
|
|
<style lang="postcss" scoped>
|
|
@@ -319,7 +357,7 @@ onUnmounted(() => {
|
|
height: 40px;
|
|
height: 40px;
|
|
}
|
|
}
|
|
|
|
|
|
- .groups {
|
|
|
|
|
|
+ .groups-panel {
|
|
display: grid;
|
|
display: grid;
|
|
grid-template-columns: 50px 1fr;
|
|
grid-template-columns: 50px 1fr;
|
|
border-top: 1px solid var(--color-background-input);
|
|
border-top: 1px solid var(--color-background-input);
|
|
@@ -327,7 +365,7 @@ onUnmounted(() => {
|
|
overflow-y: auto;
|
|
overflow-y: auto;
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
|
|
|
|
- .sub-groups {
|
|
|
|
|
|
+ .groups {
|
|
& > div {
|
|
& > div {
|
|
display: flex;
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
@@ -397,7 +435,7 @@ onUnmounted(() => {
|
|
p {
|
|
p {
|
|
text-align: center;
|
|
text-align: center;
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
- height: 14px;
|
|
|
|
|
|
+ height: 12px;
|
|
line-height: 1;
|
|
line-height: 1;
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
text-overflow: ellipsis;
|
|
@@ -446,7 +484,6 @@ onUnmounted(() => {
|
|
:deep(.t-collapse-panel__content) {
|
|
:deep(.t-collapse-panel__content) {
|
|
padding: 8px;
|
|
padding: 8px;
|
|
grid-template-columns: 116px 116px;
|
|
grid-template-columns: 116px 116px;
|
|
- grid-template-rows: 136px;
|
|
|
|
}
|
|
}
|
|
.show-item {
|
|
.show-item {
|
|
p {
|
|
p {
|