feat(mall):优化商品分类表单上级分类选择器

- 将原有的下拉选择器替换为树形选择器,提升用户体验
- 新增 getCategoryTree 方法构建分类树结构
- 引入 handleTree 工具函数处理分类数据层级关系
- 修复分类图标列空值时显示异常的问题
pull/833/head
dafang 2025-11-07 18:29:20 +08:00
parent ad433c4093
commit 473aef6de9
2 changed files with 21 additions and 13 deletions

View File

@ -8,15 +8,14 @@
v-loading="formLoading" v-loading="formLoading"
> >
<el-form-item label="上级分类" prop="parentId"> <el-form-item label="上级分类" prop="parentId">
<el-select v-model="formData.parentId" placeholder="请选择上级分类"> <el-tree-select
<el-option :key="0" label="顶级分类" :value="0" /> v-model="formData.parentId"
<el-option :data="categoryTree"
v-for="item in categoryList" :default-expanded-keys="[0]"
:key="item.id" :props="defaultProps"
:label="item.name" check-strictly
:value="item.id" node-key="id"
/> />
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="分类名称" prop="name"> <el-form-item label="分类名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入分类名称" /> <el-input v-model="formData.name" placeholder="请输入分类名称" />
@ -50,6 +49,7 @@
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { CommonStatusEnum } from '@/utils/constants' import { CommonStatusEnum } from '@/utils/constants'
import * as ProductCategoryApi from '@/api/mall/product/category' import * as ProductCategoryApi from '@/api/mall/product/category'
import { defaultProps, handleTree } from "@/utils/tree";
defineOptions({ name: 'ProductCategory' }) defineOptions({ name: 'ProductCategory' })
@ -69,12 +69,20 @@ const formData = ref({
const formRules = reactive({ const formRules = reactive({
parentId: [{ required: true, message: '请选择上级分类', trigger: 'blur' }], parentId: [{ required: true, message: '请选择上级分类', trigger: 'blur' }],
name: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }], name: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }],
picUrl: [{ required: true, message: '分类图片不能为空', trigger: 'blur' }],
sort: [{ required: true, message: '分类排序不能为空', trigger: 'blur' }], sort: [{ required: true, message: '分类排序不能为空', trigger: 'blur' }],
status: [{ required: true, message: '开启状态不能为空', trigger: 'blur' }] status: [{ required: true, message: '开启状态不能为空', trigger: 'blur' }]
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
const categoryList = ref<any[]>([]) // /** 获取下拉框[上级分类]的数据 */
const categoryTree = ref<Tree[]>([]) //
const getCategoryTree = async () => {
categoryTree.value = []
const res = await ProductCategoryApi.getCategoryList(null)
let category: Tree = {id: 0, name: '顶级分类', children: []}
category.children = handleTree(res)
categoryTree.value.push(category)
}
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (type: string, id?: number) => { const open = async (type: string, id?: number) => {
@ -92,7 +100,7 @@ const open = async (type: string, id?: number) => {
} }
} }
// //
categoryList.value = await ProductCategoryApi.getCategoryList({ parentId: 0 }) await getCategoryTree()
} }
defineExpose({ open }) // open defineExpose({ open }) // open

View File

@ -40,7 +40,7 @@
<el-table-column label="名称" min-width="240" prop="name" sortable /> <el-table-column label="名称" min-width="240" prop="name" sortable />
<el-table-column label="分类图标" align="center" min-width="80" prop="picUrl"> <el-table-column label="分类图标" align="center" min-width="80" prop="picUrl">
<template #default="scope"> <template #default="scope">
<img :src="scope.row.picUrl" alt="移动端分类图" class="h-36px" /> <img v-if="scope.row.picUrl" :src="scope.row.picUrl" alt="移动端分类图" class="h-36px" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="排序" align="center" min-width="150" prop="sort" /> <el-table-column label="排序" align="center" min-width="150" prop="sort" />