This commit is contained in:
扶桑花间 2025-08-25 23:02:55 +08:00
parent 5acd35774f
commit b9b3c7f186
4 changed files with 208 additions and 170 deletions

View File

@ -12,6 +12,7 @@ export interface Config {
itemStyle?: string; itemStyle?: string;
itemBind?: string; itemBind?: string;
itemClass?: string; itemClass?: string;
option?: string;
} }
/** /**

View File

@ -3,6 +3,9 @@
<template v-if="props.type === 'text'"> <template v-if="props.type === 'text'">
<el-input v-model="dataValue" :placeholder="'请输入' + props.title" v-bind="itemBind"/> <el-input v-model="dataValue" :placeholder="'请输入' + props.title" v-bind="itemBind"/>
</template> </template>
<template v-if="props.type === 'json'">
<el-input v-model="props.value" :placeholder="'请输入' + props.title" v-bind="itemBind"/>
</template>
<template v-else-if="props.type === 'textarea'"> <template v-else-if="props.type === 'textarea'">
<el-input type="textarea" <el-input type="textarea"
v-model="dataValue" v-model="dataValue"
@ -75,7 +78,7 @@
<script setup lang="ts"> <script setup lang="ts">
import {ref, onMounted} from "vue"; import {ref, onMounted} from "vue";
import {strToBind, strToOption, strToValue} from "@/utils/sys-config"; import { strToValue} from "@/utils/sys-config";
const props = defineProps<{ const props = defineProps<{
name: string; name: string;

View File

@ -3,7 +3,7 @@
<ele-modal <ele-modal
form form
destroy-on-close destroy-on-close
:width="960" :width="980"
v-model="visible" v-model="visible"
:title="isUpdate ? '修改配置' : '添加配置'" :title="isUpdate ? '修改配置' : '添加配置'"
> >
@ -17,7 +17,7 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="上级" prop="pid"> <el-form-item label="上级" prop="pid">
<config-select :model-value="form.pid" :group="form.group" disabled /> <config-select :model-value="form.pid" :group="form.group" disabled/>
</el-form-item> </el-form-item>
<el-form-item label="类型" prop="type"> <el-form-item label="类型" prop="type">
<el-select <el-select
@ -78,17 +78,10 @@
placeholder="请输入配置项" placeholder="请输入配置项"
/> />
</el-form-item> </el-form-item>
<el-form-item label="配置说明">
<el-input
:rows="4"
type="textarea"
v-model="form.tips"
placeholder="请输入配置说明"
/>
</el-form-item>
</template> </template>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="11" :offset="1">
<el-form-item label="BIND"> <el-form-item label="BIND">
<el-input <el-input
:rows="4" :rows="4"
@ -112,15 +105,38 @@
placeholder="请输入渲染框Style样式" placeholder="请输入渲染框Style样式"
/> />
</el-form-item> </el-form-item>
<el-divider/>
<el-card header="样式预览:" style="margin-bottom: 30px;">
<config-form-item
:name="preview.name"
:title="preview.title"
:type="preview.type"
:value="preview.value"
:option="preview.option"
:item-bind="preview.bind"
:key="preview.id"
/>
<el-form-item v-if="preview.tips">
<ele-text type="placeholder" style="line-height: 1.6">
{{ preview.tips }}
</ele-text>
</el-form-item>
</el-card>
</el-col> </el-col>
</el-row> </el-row>
<el-form-item label="配置说明">
<el-form-item label="备注" v-if="false"> <el-input
type="textarea"
v-model="form.tips"
placeholder="请输入配置说明(在配置页简短提示作用)"
/>
</el-form-item>
<el-divider/>
<el-form-item label="备注">
<el-input <el-input
:rows="4"
type="textarea" type="textarea"
v-model="form.comments" v-model="form.comments"
placeholder="请输入备注" placeholder="请输入备注(详细描述此配置的功能和作用) - 此备注仅开发人员可见"
/> />
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -134,162 +150,172 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, reactive, watch, computed } from 'vue'; import {ref, reactive, watch, computed} from 'vue';
import type { FormInstance, FormRules } from 'element-plus'; import type {FormInstance, FormRules} from 'element-plus';
import { EleMessage } from 'ele-admin-plus'; import {EleMessage} from 'ele-admin-plus';
import { useFormData } from '@/utils/use-form-data'; import {useFormData} from '@/utils/use-form-data';
import type { Config } from '@/api/system/config/model'; import type {Config} from '@/api/system/config/model';
import { addConfig, updateConfig } from '@/api/system/config'; import {addConfig, updateConfig} from '@/api/system/config';
import ConfigSelect from './config-select.vue'; import ConfigSelect from './config-select.vue';
import { ItemType, getItemLabel } from '@/enum/config-item-type.ts'; import {ItemType, getItemLabel} from '@/enum/config-item-type.ts';
const HIDE_FORM_ITEM_WHERE: any = { import ConfigFormItem from "@/views/system/config-set/components/config-form-item.vue";
name: () => { import {strToBind, strToOption} from "@/utils/sys-config";
return ['tabs', 'tabs_item','alert','card','separator'].indexOf(<string>form.type) == -1;
},
value: ()=>{
return ['tabs', 'tabs_item'].indexOf(<string>form.type) == -1
},
option: ()=>{
return ['tabs', 'tabs_item'].indexOf(<string>form.type) == -1
}
};
const configItemType: any = computed(() => {
let list = {};
if (props.parent) {
if (props.parent.type == 'tabs') {
list[ItemType.TABS_ITEM] = ItemType.TABS_ITEM;
} else if (props.parent.type == 'tabs_item') {
for (const name in ItemType) {
if (
[ItemType.TABS_ITEM, ItemType.TABS].indexOf(ItemType[name]) == -1
) {
list[name] = ItemType[name];
}
}
}
}
if (Object.keys(list).length == 0) {
return ItemType;
} else {
return list;
}
});
const props = defineProps<{
/** 修改回显的数据 */
data?: Config | null;
/** 父级元素 */
parent?: Config | null;
/** 配置所属组 */
group?: string | null;
}>();
const emit = defineEmits<{ const HIDE_FORM_ITEM_WHERE: any = {
(e: 'done'): void; name: () => {
}>(); return ['tabs', 'tabs_item', 'alert', 'card', 'separator'].indexOf(<string>form.type) == -1;
},
/** 弹窗是否打开 */ value: () => {
const visible = defineModel({ type: Boolean }); return ['tabs', 'tabs_item'].indexOf(<string>form.type) == -1
},
/** 是否是修改 */ option: () => {
const isUpdate = ref(false); return ['tabs', 'tabs_item'].indexOf(<string>form.type) == -1
/** 提交状态 */
const loading = ref(false);
/** 表单实例 */
const formRef = ref<FormInstance | null>(null);
interface ConfigEdit extends Config {
_type_readonly: boolean;
} }
};
/** 表单数据 */ const preview = computed(() => {
const [form, resetFields, assignFields] = useFormData<ConfigEdit>({ return {
id: void 0, ...form,
pid: 0, bind: strToBind(<string>form.type, <string>form.itemBind),
_type_readonly: false, option: strToOption(<string>form.type, <string>form.option)
type: '', }
comments: '', })
group: '', const configItemType: any = computed(() => {
title: '', let list = {};
name: '', if (props.parent) {
tips: '', if (props.parent.type == 'tabs') {
option: '', list[ItemType.TABS_ITEM] = ItemType.TABS_ITEM;
value: '', } else if (props.parent.type == 'tabs_item') {
itemBind: '', for (const name in ItemType) {
itemStyle: '', if (
itemClass: '' [ItemType.TABS_ITEM, ItemType.TABS].indexOf(ItemType[name]) == -1
}); ) {
list[name] = ItemType[name];
/** 表单验证规则 */
const rules = reactive<FormRules>({
name: [
{
required: true,
message: '请输入配置名称',
type: 'string',
trigger: 'blur'
}
],
title: [
{
required: true,
message: '请输入配置标题',
type: 'string',
trigger: 'blur'
}
]
});
/** 关闭弹窗 */
const handleCancel = () => {
visible.value = false;
};
/** 保存编辑 */
const save = () => {
formRef.value?.validate?.((valid) => {
if (!valid) {
return;
}
loading.value = true;
const saveOrUpdate = isUpdate.value ? updateConfig : addConfig;
saveOrUpdate(form)
.then((msg) => {
loading.value = false;
EleMessage.success({ message: msg, plain: true });
handleCancel();
emit('done');
})
.catch((e) => {
loading.value = false;
EleMessage.error({ message: e.message, plain: true });
});
});
};
/** 监听弹窗打开 */
watch(visible, () => {
if (visible.value) {
if (props.data) {
assignFields(props.data);
isUpdate.value = true;
} else {
resetFields();
isUpdate.value = false;
if (props.parent) {
let data: any = { pid: props.parent.id };
if (props.parent.type == 'tabs') {
data.type = 'tabs_item';
data._type_readonly = true;
}
assignFields(data);
} }
} }
if (form.type == 'tabs_item') {
form._type_readonly = true;
}
form.group = props.group;
} }
}
if (Object.keys(list).length == 0) {
return ItemType;
} else {
return list;
}
});
const props = defineProps<{
/** 修改回显的数据 */
data?: Config | null;
/** 父级元素 */
parent?: Config | null;
/** 配置所属组 */
group?: string | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
}>();
/** 弹窗是否打开 */
const visible = defineModel({type: Boolean});
/** 是否是修改 */
const isUpdate = ref(false);
/** 提交状态 */
const loading = ref(false);
/** 表单实例 */
const formRef = ref<FormInstance | null>(null);
interface ConfigEdit extends Config {
_type_readonly: boolean;
}
/** 表单数据 */
const [form, resetFields, assignFields] = useFormData<ConfigEdit>({
id: void 0,
pid: 0,
_type_readonly: false,
type: '',
comments: '',
group: '',
title: '',
name: '',
tips: '',
option: '',
value: '',
itemBind: '',
itemStyle: '',
itemClass: ''
});
/** 表单验证规则 */
const rules = reactive<FormRules>({
name: [
{
required: true,
message: '请输入配置名称',
type: 'string',
trigger: 'blur'
}
],
title: [
{
required: true,
message: '请输入配置标题',
type: 'string',
trigger: 'blur'
}
]
});
/** 关闭弹窗 */
const handleCancel = () => {
visible.value = false;
};
/** 保存编辑 */
const save = () => {
formRef.value?.validate?.((valid) => {
if (!valid) {
return;
}
loading.value = true;
const saveOrUpdate = isUpdate.value ? updateConfig : addConfig;
saveOrUpdate(form)
.then((msg) => {
loading.value = false;
EleMessage.success({message: msg, plain: true});
handleCancel();
emit('done');
})
.catch((e) => {
loading.value = false;
EleMessage.error({message: e.message, plain: true});
});
}); });
};
/** 监听弹窗打开 */
watch(visible, () => {
if (visible.value) {
if (props.data) {
assignFields(props.data);
isUpdate.value = true;
} else {
resetFields();
isUpdate.value = false;
if (props.parent) {
let data: any = {pid: props.parent.id};
if (props.parent.type == 'tabs') {
data.type = 'tabs_item';
data._type_readonly = true;
}
assignFields(data);
}
}
if (form.type == 'tabs_item') {
form._type_readonly = true;
}
form.group = props.group;
}
});
</script> </script>

View File

@ -55,6 +55,10 @@
删除 删除
</el-link> </el-link>
</template> </template>
<el-divider direction="vertical" />
<el-link type="primary" underline="never" @click="openLog(row)" title="查看配置变更日志记录">
日志
</el-link>
</template> </template>
<template #status="{ row }"> <template #status="{ row }">
<el-switch <el-switch
@ -155,7 +159,7 @@
{ {
columnKey: 'action', columnKey: 'action',
label: '操作', label: '操作',
width: 200, width: 280,
align: 'right' /* , align: 'right' /* ,
fixed: 'right' */, fixed: 'right' */,
slot: 'action', slot: 'action',
@ -203,7 +207,11 @@
showEdit.value = true; showEdit.value = true;
parent.value = parentRow; parent.value = parentRow;
}; };
const showLog = ref(false);
const openLog = (row?:Config)=>{
current.value = row ?? null;
showLog.value = true;
}
/** 删除单个 */ /** 删除单个 */
const remove = (row?: Config) => { const remove = (row?: Config) => {
const rows = row == null ? selections.value : [row]; const rows = row == null ? selections.value : [row];