diff --git a/src/apis/modules/categorys.js b/src/apis/modules/categorys.js new file mode 100644 index 0000000..ca85edf --- /dev/null +++ b/src/apis/modules/categorys.js @@ -0,0 +1,14 @@ +/** + * 海邻动态接口 + */ +import request from '@/utils/request' +// 获取公司动态列表 +export const getDataList = (params) => request.basic.get('/api/v1/products/categorys', params) +// 获取单条数据 +export const getItem = (id) => request.basic.get(`/api/v1/products/categorys/${id}`) +// 添加动态 +export const createProductsItem = (params) => request.basic.post('/api/v1/products/categorys', params) +// 更新动态 +export const updateItem = (id, params) => request.basic.put(`/api/v1/products/categorys/${id}`, params) +// 删除动态 +export const delProductsItem = (id) => request.basic.delete(`/api/v1/products/categorys/${id}`) diff --git a/src/locales/lang/zh-CN/menu.js b/src/locales/lang/zh-CN/menu.js index 2c1a183..4271195 100644 --- a/src/locales/lang/zh-CN/menu.js +++ b/src/locales/lang/zh-CN/menu.js @@ -51,4 +51,5 @@ export default { friendlyLinks:'友情链接', websiteStatement:'网站声明', contactUs:'联系我们', + productType:'产品分类' } diff --git a/src/router/routes/product.js b/src/router/routes/product.js index 1762640..1c8b7a0 100644 --- a/src/router/routes/product.js +++ b/src/router/routes/product.js @@ -13,4 +13,16 @@ export default [ permission: '*', }, }, + { + path: 'productType', + name: 'productType', + component: 'productType/index.vue', + meta: { + icon: ShoppingOutlined, + title: '产品分类', + isMenu: true, + keepAlive: true, + permission: '*', + }, + }, ] diff --git a/src/views/product/components/Department.vue b/src/views/product/components/Department.vue deleted file mode 100644 index efaefad..0000000 --- a/src/views/product/components/Department.vue +++ /dev/null @@ -1,169 +0,0 @@ - - - - - diff --git a/src/views/product/components/EditDepartmentDialog.vue b/src/views/product/components/EditDepartmentDialog.vue deleted file mode 100644 index e5a271f..0000000 --- a/src/views/product/components/EditDepartmentDialog.vue +++ /dev/null @@ -1,131 +0,0 @@ - - - - - diff --git a/src/views/product/components/EditDialog.vue b/src/views/product/components/EditDialog.vue index afb0e6e..991c8da 100644 --- a/src/views/product/components/EditDialog.vue +++ b/src/views/product/components/EditDialog.vue @@ -1,120 +1,88 @@ @@ -227,7 +110,7 @@ import { cloneDeep } from 'lodash-es' import { ref, onBeforeMount } from 'vue' import { config } from '@/config' import apis from '@/apis' -import { useForm, useModal,useSpining } from '@/hooks' +import { useForm, useModal, useSpining } from '@/hooks' import { message } from 'ant-design-vue' import { useI18n } from 'vue-i18n' @@ -245,7 +128,7 @@ const emit = defineEmits(['ok']) const { t } = useI18n() // 解构出t方法 const { modal, showModal, hideModal, showLoading, hideLoading } = useModal() const { formRecord, formData, formRef, formRules, resetForm } = useForm() -const { spining,showSpining,hideSpining} = useSpining() +const { spining, showSpining, hideSpining } = useSpining() const cancelText = ref(t('button.cancel')) const okText = ref(t('button.confirm')) const rolesValue = ref([]) @@ -254,16 +137,14 @@ const imgUrl = ref('') const categoryList = ref([]) const targetList = ref([]) const images = ref([]) -const mainImage = ref([]) const contentImage = ref([]) const childOpen = ref(false) -const formArea = ref({ name: '', status: 'enabled' }) -const categoryForm = ref({ name: '', status: 'enabled' }) -const targetForm = ref({ name: '', status: 'enabled' }) + +const activeKey = ref('1') formRules.value = { title: { required: true, message: '请输入产品类别名称' }, code: { required: true, message: '请输入产品名称' }, - categoryID: { required: true, message: '请选择产品类别', trigger: 'change' }, + categoryIDs: { required: true, message: '请选择产品类别', trigger: 'change' }, compose: { required: true, message: '请选择产品适用对象', trigger: 'change' }, feature: [{ required: true, message: '请输入产品功能特点', trigger: 'change' }], // feature: [{ required: true, message: '请输入产品功能特点' }], @@ -273,28 +154,15 @@ formRules.value = { contentImage: { required: false, message: '请上传产品内容图片' }, sequence: [{ required: true, message: '请输入产品排序' }], status: [{ required: true, message: '请选择状态', trigger: 'change' }], + } -const areaFormRules = { - categoryIDName: [{ required: true, message: '请输入产品类别' }], - targetName: [{ required: true, message: '请输入产品适用对象' }], - status: [{ required: true, message: '请选择状态', trigger: 'change' }], -} + const initData = async () => { try { showSpining(); - - const { success: catSuccess, data: catData } = await apis.products.getProductCategory({ pageSize: 999, page: 1 }); - if (config('http.code.success') === catSuccess) { - categoryList.value = catData - .filter(item => item.status === 'enabled') - .map(item => ({ code: item.id, name: item.name })); - } - - const { success: prodSuccess, data: prodData } = await apis.products.getProductObj({ pageSize: 999, page: 1 }); + const { success: prodSuccess, data: prodData } = await apis.categorys.getDataList({ pageSize: 999, page: 1 }); if (config('http.code.success') === prodSuccess) { - targetList.value = prodData - .filter(item => item.status === 'enabled') - .map(item => ({ code: item.id, name: item.name })); + categoryList.value = prodData } } catch (error) { @@ -303,6 +171,7 @@ const initData = async () => { hideSpining(); } } + /** * 新建 */ @@ -314,54 +183,26 @@ function handleCreate() { // 初始化所有字段 formData.value = { title: '', - categoryID: '', + categoryIDs:'', compose: '', target: '', feature: [{ - label:'功能特点', - data:[ - // { msg:[''], } - ] - }], + label: '功能特点', + data: [] + }], standard: [{ label: '', - val: '' , - fu_hoao: '' , - prx: '' , + val: '', + fu_hoao: '', + prx: '', }], - images: [ - ...(Array.isArray(formData.value.mainImage) - ? formData.value.mainImage - : [formData.value.mainImage] - ).filter(Boolean).map(item => String(item)), - - ...(Array.isArray(formData.value.contentImage) - ? formData.value.contentImage - : [formData.value.contentImage] - ).filter(Boolean).map(item => String(item)) - ], - + images: [''], sequence: null, status: 'enabled', } initData() } -//新建产品类别 -const childHandleOk = async () => { - areaFormRef.value.validateFields().then(async (values) => { - try { - const params = { ...categoryForm.value } - const { success } = await apis.products.createProductCategory(params) - if (success) message.success('新增成功') - childOpen.value = false - categoryForm.value = { categoryIDName: '', status: 'enabled' } - initData() - } catch (error) { - message.error(error.message) - } - }) -} //新建产品适用对象 const childHandleObjOk = async () => { areaFormRef.value.validateFields().then(async (values) => { @@ -385,6 +226,7 @@ const handleCombinedOk = () => { * 编辑 */ async function handleEdit(record = {}) { + initData() showModal({ type: 'edit', title: t('pages.system.user.edit'), @@ -396,26 +238,20 @@ async function handleEdit(record = {}) { } formData.value = { ...data, - standard:data.standard|| [{ + categoryIDs:data.categoryID, + standard: data.standard || [{ label: '', - val: '' , - fu_hoao: '' , - prx: '' , + val: '', + fu_hoao: '', + prx: '', }], - feature:data.feature|| [{ - label:'功能特点', - data:[ - // {msg:[''],} - ] + feature: data.feature || [{ + label: '功能特点', + data: [] }], - // images:data.images || [''], - mainImage: data.images?[config('http.apiBasic')+data.images[0]]:[''], - contentImage:data.images?[config('http.apiBasic')+data.images[1]]:[''], + // images:data.images || [''], + mainImage: data.images ? data.images.map(item=>config('http.apiBasic')+item):[''], } - // imgUrl.value = config('http.apiBasic') + data.img - mainImage.value = config('http.apiBasic') + data.images?.[0] , - contentImage.value = config('http.apiBasic') + data.images?.[1] , - console.log('编辑产品数据:',formData.value); } /** @@ -428,30 +264,17 @@ function handleOk() { showLoading() const params = { ...values, - standard:formData.value.standard || + categoryID:formData.value.categoryID, + categoryRootID:formData.value.categoryRootID, + standard: formData.value.standard || [{ - label: '', - val: '' , - fu_hoao: '' , - prx: '' , + label: '', + val: '', + fu_hoao: '', + prx: '', }], - feature:formData.value.feature|| [{ - label:'功能特点', - data:[ - // { msg:[''], } - ] - }], - images: [ - ...(Array.isArray(formData.value.mainImage) - ? formData.value.mainImage - : [formData.value.mainImage] - ).filter(Boolean).map(item => spliceUrl(item)), - - ...(Array.isArray(formData.value.contentImage) - ? formData.value.contentImage - : [formData.value.contentImage] - ).filter(Boolean).map(item => spliceUrl(item)) - ], + feature: formData.value.feature, + images: formData.value.mainImage?formData.value.mainImage.map(item=>spliceUrl(item)):[''], } let result = null switch (modal.value.type) { @@ -526,8 +349,52 @@ function removeFeature(index) { formData.value.feature.splice(index, 1) } } +// 递归查找节点路径 +const findNodePath = (tree, value, path = []) => { + for (const node of tree) { + const currentPath = [...path, node.value]; + if (node.value === value) return currentPath; + if (node.children) { + const found = findNodePath(node.children, value, currentPath); + if (found) return found; + } + } + return null; +}; +// 获取节点是否是叶子节点 +const isLeafNode = (id) => { + const node = findNodeById(categoryList.value, id); + if(node.children.length>0) return false; + else return true +}; +// 根据ID查找节点 +const findNodeById = (tree, value) => { + for (const node of tree) { + if (node.value === value) return node; + if(node.children){ + const found=findNodeById(node.children,value) + if(found) return found; + } + } + return null; +}; +// 处理选择事件 +const handleTreeSelectChange = (value) => { + // 验证是否叶子节点 + if (!isLeafNode(value)) { + message.warning('只能选择最后一级节点'); + formData.value.categoryID = null; // 清除非叶子选择 + return; + } + if (!value) return; + const pathIds = findNodePath(categoryList.value, value); + if (pathIds) { + console.log('选中的路径ID数组:', pathIds); + // 实际使用中,此处可提交 pathIds 到后端或进行其他操作 + formData.value.categoryID=pathIds[1] + formData.value.categoryRootID=pathIds[0] + } +}; - + diff --git a/src/views/product/index.vue b/src/views/product/index.vue index 618f23c..a00102d 100644 --- a/src/views/product/index.vue +++ b/src/views/product/index.vue @@ -49,7 +49,6 @@