227 lines
4.3 KiB
Vue
227 lines
4.3 KiB
Vue
<template>
|
|
<div class="dp-config">
|
|
<div class="head" v-show="t">
|
|
<span>{{ t }}</span>
|
|
<el-button text type="danger" @click="del" v-if="showDel">删除</el-button>
|
|
</div>
|
|
|
|
<div class="tips" v-if="tips">
|
|
<el-icon>
|
|
<warning-filled />
|
|
</el-icon>
|
|
<span>{{ tips }}</span>
|
|
</div>
|
|
|
|
<el-scrollbar class="scrollbar" v-if="visible">
|
|
<div class="form">
|
|
<cl-form inner ref="Form"> </cl-form>
|
|
|
|
<el-empty :image-size="100" v-show="!t" description="未选择组件" />
|
|
</div>
|
|
</el-scrollbar>
|
|
</div>
|
|
</template>
|
|
<script lang="tsx" setup>
|
|
import { useForm } from "@cool-vue/crud";
|
|
import { WarningFilled } from "@element-plus/icons-vue";
|
|
import { computed, nextTick, ref, watch } from "vue";
|
|
import { useCool } from "/@/cool";
|
|
import { useDp } from "../hooks";
|
|
|
|
const { mitt } = useCool();
|
|
const { dp } = useDp();
|
|
const Form = useForm();
|
|
const visible = ref(true);
|
|
const t = ref("");
|
|
const data = ref<Record<string, any>>({});
|
|
const tips = ref("");
|
|
|
|
// 是否显示删除套件
|
|
const showDel = computed(() => data.value.id !== "header");
|
|
|
|
// 删除操作
|
|
function del() {
|
|
clear();
|
|
if (data.value.name === "suspension") {
|
|
dp.removeSuspension();
|
|
} else {
|
|
dp.removeBy({ id: data.value.id });
|
|
}
|
|
}
|
|
|
|
// 清空表单
|
|
function clear() {
|
|
Form.value?.close();
|
|
t.value = "";
|
|
tips.value = "";
|
|
}
|
|
|
|
// 处理嵌套属性
|
|
function assignNestedProperties(obj: Record<string, any>) {
|
|
Object.keys(obj).forEach((key) => {
|
|
if (key.includes("-")) {
|
|
const [parentKey, childKey] = key.split("-");
|
|
if (!obj[parentKey]) {
|
|
obj[parentKey] = {};
|
|
}
|
|
obj[parentKey][childKey] = obj[key];
|
|
}
|
|
});
|
|
}
|
|
|
|
// 刷新表单
|
|
function refresh(options: any) {
|
|
data.value = options;
|
|
const { title, items = [] } = options.config;
|
|
t.value = title || "未配置";
|
|
tips.value = options.config.tips;
|
|
Form.value?.open({
|
|
form: options.component.props,
|
|
items,
|
|
props: {
|
|
labelPosition: "top"
|
|
},
|
|
op: {
|
|
hidden: true
|
|
}
|
|
});
|
|
}
|
|
|
|
// 用于停止当前的 watch 监听器
|
|
let stopWatch: (() => void) | null = null;
|
|
|
|
// 判断是否为空对象
|
|
function isEmpty(obj: Object) {
|
|
return Object.keys(obj).length === 0;
|
|
}
|
|
/**
|
|
* 设置新的 watch 监听器
|
|
* @param {Function} callback - 监听到数据变化时调用的回调函数
|
|
*/
|
|
function setupWatch(callback: (val: any) => void) {
|
|
stopWatch?.();
|
|
stopWatch = watch(
|
|
() => Form.value?.form,
|
|
(val) => {
|
|
if (val && !isEmpty(val)) {
|
|
assignNestedProperties(val);
|
|
callback(val);
|
|
}
|
|
},
|
|
{
|
|
immediate: true,
|
|
deep: true
|
|
}
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 处理配置设置
|
|
* @param {Object} data - 包含 options 和 cb 的配置对象
|
|
*/
|
|
function onSetConfig({ options, cb }: { options: any; cb: (val: any) => void }) {
|
|
visible.value = false;
|
|
nextTick(() => {
|
|
visible.value = true;
|
|
nextTick(() => {
|
|
refresh(options || {});
|
|
setupWatch(cb);
|
|
});
|
|
});
|
|
}
|
|
|
|
// 监听清除配置
|
|
function onClearConfig() {
|
|
clear();
|
|
}
|
|
|
|
mitt.on("dp.setConfig", onSetConfig);
|
|
mitt.on("dp.clearConfig", onClearConfig);
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.dp-config {
|
|
height: 680px;
|
|
width: 350px;
|
|
overflow: hidden;
|
|
background-color: #fff;
|
|
border-radius: 5px;
|
|
|
|
.head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
height: 54px;
|
|
font-size: 18px;
|
|
color: #262626;
|
|
padding: 0 15px;
|
|
border-bottom: 1px solid #ebeef5;
|
|
}
|
|
|
|
.tips {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
background-color: #fff8d5;
|
|
color: #ffbb00;
|
|
margin: 10px 24px 0 24px;
|
|
padding: 0 20px 0 4px;
|
|
border-radius: 4px;
|
|
|
|
.el-icon {
|
|
margin: 5px;
|
|
font-size: 15px;
|
|
}
|
|
|
|
span {
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
|
|
.scrollbar {
|
|
height: calc(100% - 55px);
|
|
}
|
|
|
|
.form {
|
|
padding: 16px 24px;
|
|
box-sizing: border-box;
|
|
|
|
:deep(.form-label) {
|
|
font-size: 16px;
|
|
color: #000;
|
|
|
|
span {
|
|
font-size: 12px;
|
|
color: #bfbfbf;
|
|
margin-left: 10px;
|
|
}
|
|
.text-warning {
|
|
color: var(--el-color-warning);
|
|
}
|
|
.text-success {
|
|
color: var(--el-color-success);
|
|
}
|
|
.text-primary {
|
|
color: var(--el-color-primary);
|
|
}
|
|
.text-danger {
|
|
color: var(--el-color-danger);
|
|
}
|
|
}
|
|
|
|
:deep(.el-form-item__label) {
|
|
color: #000;
|
|
font-size: 16px;
|
|
}
|
|
:deep(.cl-form-card__container > .cl-form-item__children) {
|
|
overflow: hidden;
|
|
}
|
|
:deep(.cl-form-card) {
|
|
background-color: #fff;
|
|
}
|
|
:deep(.el-form-item) {
|
|
margin-bottom: 18px;
|
|
}
|
|
}
|
|
}
|
|
</style>
|