This commit is contained in:
Cold
2025-12-17 10:37:57 +08:00
3 changed files with 68 additions and 28 deletions

View File

@@ -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
}) })

View File

@@ -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,9 +76,9 @@
: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.value"
:value="item.key" :value="item.key"
/> />
</el-select> </el-select>
@@ -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,7 +163,7 @@ 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>({
@@ -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,24 @@ 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 = [];
}
}
// 如果是对象数组 [{label, value}],转换为简单数组 [value]
// 这样前端选择器才能正确工作
if (Array.isArray(options) && options.length > 0 && typeof options[0] === 'object') {
options = options.map((opt: any) => opt.value || opt.key || opt);
}
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 +323,41 @@ 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;
const options = attr.options || [];
let formattedOptions: any[] = [];
// 判断 options 是否已经是对象数组格式
if (options.length > 0 && typeof options[0] === 'object') {
// 已经是对象数组格式,直接使用
formattedOptions = options;
} else {
// 是字符串数组,需要转换为 [{label, value}] 格式
const dictValues = getDictValuesByType(attr.description || '');
formattedOptions = 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');
}) })

View File

@@ -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>