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;
itemBind?: string;
itemClass?: string;
option?: string;
}
/**

View File

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

View File

@ -3,7 +3,7 @@
<ele-modal
form
destroy-on-close
:width="960"
:width="980"
v-model="visible"
:title="isUpdate ? '修改配置' : '添加配置'"
>
@ -17,7 +17,7 @@
<el-row>
<el-col :span="12">
<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 label="类型" prop="type">
<el-select
@ -78,17 +78,10 @@
placeholder="请输入配置项"
/>
</el-form-item>
<el-form-item label="配置说明">
<el-input
:rows="4"
type="textarea"
v-model="form.tips"
placeholder="请输入配置说明"
/>
</el-form-item>
</template>
</el-col>
<el-col :span="12">
<el-col :span="11" :offset="1">
<el-form-item label="BIND">
<el-input
:rows="4"
@ -112,15 +105,38 @@
placeholder="请输入渲染框Style样式"
/>
</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-row>
<el-form-item label="备注" v-if="false">
<el-form-item label="配置说明">
<el-input
type="textarea"
v-model="form.tips"
placeholder="请输入配置说明(在配置页简短提示作用)"
/>
</el-form-item>
<el-divider/>
<el-form-item label="备注">
<el-input
:rows="4"
type="textarea"
v-model="form.comments"
placeholder="请输入备注"
placeholder="请输入备注(详细描述此配置的功能和作用) - 此备注仅开发人员可见"
/>
</el-form-item>
</el-form>
@ -134,162 +150,172 @@
</template>
<script lang="ts" setup>
import { ref, reactive, watch, computed } from 'vue';
import type { FormInstance, FormRules } from 'element-plus';
import { EleMessage } from 'ele-admin-plus';
import { useFormData } from '@/utils/use-form-data';
import type { Config } from '@/api/system/config/model';
import { addConfig, updateConfig } from '@/api/system/config';
import ConfigSelect from './config-select.vue';
import { ItemType, getItemLabel } from '@/enum/config-item-type.ts';
const HIDE_FORM_ITEM_WHERE: any = {
name: () => {
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;
}>();
import {ref, reactive, watch, computed} from 'vue';
import type {FormInstance, FormRules} from 'element-plus';
import {EleMessage} from 'ele-admin-plus';
import {useFormData} from '@/utils/use-form-data';
import type {Config} from '@/api/system/config/model';
import {addConfig, updateConfig} from '@/api/system/config';
import ConfigSelect from './config-select.vue';
import {ItemType, getItemLabel} from '@/enum/config-item-type.ts';
import ConfigFormItem from "@/views/system/config-set/components/config-form-item.vue";
import {strToBind, strToOption} from "@/utils/sys-config";
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 HIDE_FORM_ITEM_WHERE: any = {
name: () => {
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 [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);
};
const preview = computed(() => {
return {
...form,
bind: strToBind(<string>form.type, <string>form.itemBind),
option: strToOption(<string>form.type, <string>form.option)
}
})
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 (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>

View File

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