优化字典数据处理逻辑,支持树形结构字典接口并修复自定义属性字段映射关系
This commit is contained in:
@@ -8,7 +8,7 @@ export function getDicts(dictType :string,defaultValue?:string):Promise<any> {
|
|||||||
defaultValue:dv
|
defaultValue:dv
|
||||||
}
|
}
|
||||||
return request({
|
return request({
|
||||||
url: '/api/v1/system/dict/data/getDictData',
|
url: '/api/v1/system/dict/data/getDictDataTree',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params:params
|
params:params
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
<!-- 单选/多选时显示字典类型选择 -->
|
<!-- 单选/多选时显示字典类型选择 -->
|
||||||
<el-select
|
<el-select
|
||||||
v-if="attr.type === 'select' || attr.type === 'multi_select'"
|
v-if="attr.type === 'select' || attr.type === 'multi_select'"
|
||||||
v-model="attr.dictKey"
|
v-model="attr.description"
|
||||||
placeholder="选择字典类型"
|
placeholder="选择字典类型"
|
||||||
style="width: 120px"
|
style="width: 120px"
|
||||||
:loading="dictLoading"
|
:loading="dictLoading"
|
||||||
@@ -66,8 +66,8 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
<!-- 选择字典类型后显示字典值选择 -->
|
<!-- 选择字典类型后显示字典值选择 -->
|
||||||
<el-select
|
<el-select
|
||||||
v-if="attr.dictKey && (attr.type === 'select' || attr.type === 'multi_select')"
|
v-if="attr.description && (attr.type === 'select' || attr.type === 'multi_select')"
|
||||||
v-model="attr.dictValues"
|
v-model="attr.options"
|
||||||
multiple
|
multiple
|
||||||
placeholder="选择字典值"
|
placeholder="选择字典值"
|
||||||
style="width: 150px"
|
style="width: 150px"
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
:max-collapse-tags="2"
|
:max-collapse-tags="2"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="(item, idx) in getDictValuesByType(attr.dictKey)"
|
v-for="(item, idx) in getDictValuesByType(attr.description)"
|
||||||
:key="idx"
|
:key="idx"
|
||||||
:label="item.key"
|
:label="item.key"
|
||||||
:value="item.key"
|
:value="item.key"
|
||||||
@@ -126,7 +126,7 @@ interface CustomAttr {
|
|||||||
type: string;
|
type: string;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
multiple?: boolean;
|
multiple?: boolean;
|
||||||
options?: string;
|
options?: string[];
|
||||||
description?: string;
|
description?: string;
|
||||||
sort?: number;
|
sort?: number;
|
||||||
dictKey?: string;
|
dictKey?: string;
|
||||||
@@ -163,11 +163,11 @@ const isAddChild = ref(false);
|
|||||||
const submitLoading = ref(false);
|
const submitLoading = ref(false);
|
||||||
const categoryData = ref<CategoryRow[]>([]);
|
const categoryData = ref<CategoryRow[]>([]);
|
||||||
const dictTypeOptions = ref<DictInfo[]>([]);
|
const dictTypeOptions = ref<DictInfo[]>([]);
|
||||||
const dictValueOptions = ref<DictValue[]>([]);
|
const dictValueOptions = ref<any[]>([]);
|
||||||
const dictLoading = ref(false);
|
const dictLoading = ref(false);
|
||||||
|
|
||||||
const ruleForm = reactive<RuleForm>({
|
const ruleForm = reactive<RuleForm>({
|
||||||
id: '',
|
id: '',
|
||||||
parentId: '',
|
parentId: '',
|
||||||
name: '',
|
name: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
@@ -185,18 +185,13 @@ const fetchDictTypeOptions = () => {
|
|||||||
getDicts('assets')
|
getDicts('assets')
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
console.log('字典接口返回数据:', res);
|
console.log('字典接口返回数据:', res);
|
||||||
const info = res.data?.info;
|
const list = res.data?.list ?? [];
|
||||||
let infoList: DictInfo[] = [];
|
// 提取所有字典类型信息
|
||||||
// 处理info可能是对象或数组的情况
|
dictTypeOptions.value = list
|
||||||
if (Array.isArray(info)) {
|
.map((item: any) => item.info)
|
||||||
infoList = info;
|
.filter((info: DictInfo) => info && info.name);
|
||||||
} else if (info && typeof info === 'object') {
|
// 保存完整的字典数据列表(包含info和values)
|
||||||
infoList = [info];
|
dictValueOptions.value = list;
|
||||||
}
|
|
||||||
// 过滤掉name为空的项
|
|
||||||
dictTypeOptions.value = infoList.filter((item: DictInfo) => item && item.name);
|
|
||||||
// 保存字典值列表
|
|
||||||
dictValueOptions.value = res.data?.values ?? [];
|
|
||||||
console.log('字典类型选项:', dictTypeOptions.value);
|
console.log('字典类型选项:', dictTypeOptions.value);
|
||||||
console.log('字典值选项:', dictValueOptions.value);
|
console.log('字典值选项:', dictValueOptions.value);
|
||||||
})
|
})
|
||||||
@@ -213,15 +208,15 @@ const fetchDictTypeOptions = () => {
|
|||||||
// 根据字典类型获取对应的字典值
|
// 根据字典类型获取对应的字典值
|
||||||
const getDictValuesByType = (dictKey: string) => {
|
const getDictValuesByType = (dictKey: string) => {
|
||||||
if (!dictKey) return [];
|
if (!dictKey) return [];
|
||||||
// 暂时返回所有字典值,后续可根据实际数据结构调整过滤逻辑
|
// 根据字典类型名称找到对应的字典数据
|
||||||
// 如果需要按类型过滤,可以根据后端返回的数据结构调整
|
const dictItem = dictValueOptions.value.find((item: any) => item.info?.name === dictKey);
|
||||||
return dictValueOptions.value;
|
return dictItem?.values ?? [];
|
||||||
};
|
};
|
||||||
|
|
||||||
// 字典类型选择变化时
|
// 字典类型选择变化时
|
||||||
const onDictKeyChange = (attr: CustomAttr) => {
|
const onDictKeyChange = (attr: CustomAttr) => {
|
||||||
// 清空已选的字典值
|
// 清空已选的字典值
|
||||||
attr.dictValues = [];
|
attr.options = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
// 添加自定义属性
|
// 添加自定义属性
|
||||||
@@ -281,7 +276,18 @@ const openDialog = (row?: CategoryRow | string, edit?: boolean) => {
|
|||||||
ruleForm.name = data.name || '';
|
ruleForm.name = data.name || '';
|
||||||
ruleForm.sort = data.sort || 0;
|
ruleForm.sort = data.sort || 0;
|
||||||
ruleForm.status = data.status || 'enabled';
|
ruleForm.status = data.status || 'enabled';
|
||||||
ruleForm.attrs = data.attrs || [];
|
// 处理 attrs 中的 options 字段(后端可能返回字符串格式)
|
||||||
|
ruleForm.attrs = (data.attrs || []).map((attr: any) => {
|
||||||
|
let options = attr.options;
|
||||||
|
if (typeof options === 'string') {
|
||||||
|
try {
|
||||||
|
options = JSON.parse(options);
|
||||||
|
} catch {
|
||||||
|
options = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { ...attr, options: options || [] };
|
||||||
|
});
|
||||||
// 如果有单选/多选属性,预加载字典类型数据
|
// 如果有单选/多选属性,预加载字典类型数据
|
||||||
if (ruleForm.attrs.some((attr: CustomAttr) => attr.type === 'select' || attr.type === 'multi_select')) {
|
if (ruleForm.attrs.some((attr: CustomAttr) => attr.type === 'select' || attr.type === 'multi_select')) {
|
||||||
fetchDictTypeOptions();
|
fetchDictTypeOptions();
|
||||||
@@ -311,13 +317,32 @@ const onSubmit = () => {
|
|||||||
formRef.value.validate((valid: boolean) => {
|
formRef.value.validate((valid: boolean) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
submitLoading.value = true;
|
submitLoading.value = true;
|
||||||
const submitData = { ...ruleForm };
|
// 处理 attrs:单选/多选类型不传递 name,并转换 options 格式
|
||||||
|
const processedAttrs = ruleForm.attrs.map((attr) => {
|
||||||
|
if (attr.type === 'select' || attr.type === 'multi_select') {
|
||||||
|
const { name, ...rest } = attr;
|
||||||
|
// 将 options 从 ["red"] 转换为 [{"label":"红色","value":"red"}]
|
||||||
|
const dictValues = getDictValuesByType(attr.description || '');
|
||||||
|
const formattedOptions = (attr.options || []).map((optValue: string) => {
|
||||||
|
const dictItem = dictValues.find((d: any) => d.key === optValue);
|
||||||
|
return {
|
||||||
|
label: dictItem?.value || optValue,
|
||||||
|
value: optValue,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return { ...rest, options: formattedOptions };
|
||||||
|
}
|
||||||
|
return attr;
|
||||||
|
});
|
||||||
|
const submitData = { ...ruleForm, attrs: processedAttrs };
|
||||||
|
|
||||||
if (isEdit.value) {
|
if (isEdit.value) {
|
||||||
// 修改
|
// 修改
|
||||||
updateCategory(submitData)
|
updateCategory(submitData)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success('修改成功');
|
ElMessage.success('修改成功');
|
||||||
|
console.log(submitData,'111');
|
||||||
|
|
||||||
closeDialog();
|
closeDialog();
|
||||||
emit('getCategoryList');
|
emit('getCategoryList');
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<el-input size="default" v-model="tableData.param.name" placeholder="请输入分类名称" clearable style="width: 200px" />
|
<el-input size="default" v-model="tableData.param.name" placeholder="请输入分类名称" clearable style="width: 200px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button size="default" type="primary" @click="AlistCategories">
|
<el-button size="default" type="primary" @click="AlistCategories" >
|
||||||
<el-icon><ele-Search /></el-icon>
|
<el-icon><ele-Search /></el-icon>
|
||||||
查询
|
查询
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|||||||
Reference in New Issue
Block a user