automated_admin/src/modules/fixtures/components/config.vue
2025-01-09 16:40:36 +08:00

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>