automated_admin/src/modules/fixtures/components/lump.vue

213 lines
3.6 KiB
Vue
Raw Normal View History

2025-01-09 16:40:36 +08:00
<template>
<div class="dp-lump">
<el-scrollbar>
<div class="group" v-for="(item, index) in tab.list" :key="index">
<p class="label">{{ item.label }}</p>
<draggable
v-model="item.children"
class="list"
item-key="label"
:sort="false"
:group="{
name: 'A',
pull: 'clone',
put: false
}"
:clone="onClone"
@end="onEnd"
>
<template #item="{ element: item }">
<div class="item" @click="add(item)">
<img :src="icons[item.name]" />
<span>{{ item.label }}</span>
</div>
</template>
</draggable>
</div>
</el-scrollbar>
</div>
</template>
<script lang="tsx" setup>
import { ElMessage } from "element-plus";
import { cloneDeep } from "lodash-es";
import { reactive } from "vue";
import Draggable from "vuedraggable/src/vuedraggable";
import { useDp } from "../hooks";
import { Dp } from "../types";
import { useCool } from "/@/cool";
import { uuid } from "/@/cool/utils";
import { useData } from "../data";
const { mitt } = useCool();
const { dp } = useDp();
const { Base, Marketing, Ability, Other } = useData();
// 图标
const files: any = import.meta.glob("/src/modules/fixtures/static/icon/*", {
eager: true
});
const icons = reactive<any>({});
for (const i in files) {
icons[i.replace("/src/modules/fixtures/static/icon/", "").replace(".png", "")] =
files[i].default;
}
// 数据
const tab = reactive<{ list: { label: string; children: Dp.Item[] }[] }>({
list: [
{
label: "基础组件",
children: Base
},
{
label: "营销组件",
children: Marketing
},
{
label: "功能组件",
children: Ability
},
{
label: "其他组件",
children: Other
}
]
});
// 解析
function parse(item: Dp.Item) {
function next(data: Dp.Item, options: any = {}) {
const { autoInc = true } = options;
const d: Dp.Item = cloneDeep({
...data,
id: uuid()
});
if (autoInc) {
// 序号
data._index = data._index !== undefined ? data._index + 1 : 0;
if (data._index > 0) {
d.label += data._index;
}
}
return d;
}
let v: any = null;
if (item.isOnly) {
if (dp.hasTemp(item.name)) {
ElMessage.warning("该组件只可以添加一个");
return undefined;
}
v = next(item);
} else {
v = next(item);
}
return v;
}
// 获取配置
function getConfig(name: string) {
let d: any = null;
tab.list.find((e) => {
d = e.children?.find((a) => a.name == name);
return !!d;
});
return d ? parse(d)?.config : {};
}
// 复制
let _d: any = null;
function onClone(item: any) {
if (item.name === "suspension" && dp.hasSuspension()) {
return;
}
// 记录复制的数据
_d = parse(item);
return _d;
}
function add(item: any) {
dp.add(parse(item));
dp.scrollToBottom();
}
function onEnd() {
if (_d) {
mitt.emit("dp.setActive", _d.id);
}
}
defineExpose({
getConfig
});
</script>
<style lang="scss" scoped>
.dp-lump {
width: 350px;
background-color: #fff;
border-radius: 5px;
.group {
.label {
font-size: 15px;
padding: 15px 20px;
}
.list {
display: flex;
flex-wrap: wrap;
padding: 0 8px;
.item {
display: flex;
align-items: center;
height: 40px;
width: calc(50% - 16px);
margin: 0 8px 6px 8px;
padding: 0 8px 0 18px;
box-sizing: border-box;
border: 1px dashed currentColor;
border-radius: 3px;
cursor: pointer;
color: #bfbfbf;
img {
height: 20px;
width: 20px;
margin-right: 14px;
}
span {
font-size: 15px;
}
&:hover {
border-color: var(--color-primary);
}
}
}
&:last-child {
.list {
padding-bottom: 20px;
}
}
}
}
</style>