diff --git a/src/views/goods/commodity/detail-dialog/edit-method.ts b/src/views/goods/commodity/detail-dialog/edit-method.ts new file mode 100644 index 0000000..8c39d7b --- /dev/null +++ b/src/views/goods/commodity/detail-dialog/edit-method.ts @@ -0,0 +1,95 @@ +import { Atrans$DialogRes } from '@/utils/page/config' + +interface PreviewItem { + fileName: string + name: string + resourceUrl: string + type: 'image' | 'video' + fileType: 'mainImageUrl' | 'videoUrl' | 'subImageUrl' +} + +// 编辑的时候从接口响应数据提取$dialog数据 +export const handleGetDialogData = ( + data: any, + $dialog: Ref, + fileList: Ref, + defaultCheckedNodes: Ref<{ admin: number[]; app: number[] }> +) => { + const result = { ...$dialog.value.data } + result.appCategoryId = data.appCategoryId2 + defaultCheckedNodes.value.admin = extractAdminCategoryIds(data) + result.adminCategoryId = defaultCheckedNodes.value.admin.slice(-1)[0] + defaultCheckedNodes.value.app = [data.appCategoryId1, data.appCategoryId2] + result.isTest = data.isTest + result.title = data.title + const files = [ + { + fileName: '主图', + name: '主图', + fileType: 'mainImageUrl', + resourceUrl: data.mainImageUrl, + type: 'image' + }, + { + fileName: '视频', + name: '视频', + fileType: 'videoUrl', + resourceUrl: data.videoUrl, + type: 'video' + } + ] + files.push( + ...data.vvProductDetailList + .filter((item: any) => item.type === 1) + .map((item: any) => ({ + fileName: '副图', + name: '副图', + resourceUrl: item.detail, + fileType: 'subImageUrl', + type: 'image' + })) + ) + fileList.value = files as PreviewItem[] + $dialog.value.data = result +} + +// 将adminCategoryId1, adminCategoryId2, ... 提取出来并排序 +function extractAdminCategoryIds(obj: Record): number[] { + return Object.entries(obj) + .filter(([key]) => key.startsWith('adminCategoryId')) + .sort(([keyA], [keyB]) => { + // 按数字部分排序 (adminCategoryId1 < adminCategoryId2) + const numA = parseInt(keyA.replace('adminCategoryId', '')) + const numB = parseInt(keyB.replace('adminCategoryId', '')) + return numA - numB + }) + .map(([, value]) => value) + .filter((val) => ![undefined, null].includes(val)) as number[] +} + +// 编辑的时候对后台类目的数据进行重组 +export const handleGetNewAdminCategoryData = (data: any) => { + return data.map((item: any) => ({ + ...item, + categoryPropertyName: item.productPropertyName, + vvPropertyValueList: item.vvProductPropertyValueList.map((child: any) => ({ + ...child, + categoryPropertyName: item.productPropertyName, + categoryPropertyValue: child.productPropertyValue + })), + vvProductPropertyValueList: undefined + })) +} + +// 编辑的时候对sku进行重组 +export const handleGetNewSkuList = (data: any) => { + return data.map((item: any) => ({ + ...item, + name: item.vvSkuPropertyValueList.reduce((str: string, cur: any) => { + cur.categoryPropertyName = cur.productPropertyName + cur.categoryPropertyValue = cur.productPropertyValue + str += cur.productPropertyValue + return str + }, '') + })) +} diff --git a/src/views/goods/commodity/detail-dialog/index.vue b/src/views/goods/commodity/detail-dialog/index.vue index 7a4e8bb..1ca8c42 100644 --- a/src/views/goods/commodity/detail-dialog/index.vue +++ b/src/views/goods/commodity/detail-dialog/index.vue @@ -164,14 +164,15 @@ import { handleCheckChange, defaultAdminCategoryTreeProps, defaultCheckedNodes, - handleGetDialogData, fileList, - TSkuList, - handleGetNewAdminCategoryData, - handleGetNewSkuList, - handleValidFormData, - handleGetSubmitParams + TSkuList } from './use-method' +import { + handleGetDialogData, + handleGetNewAdminCategoryData, + handleGetNewSkuList +} from './edit-method' +import { handleValidFormData, handleGetSubmitParams } from './submit-method' import categoryConfig from './category-config.vue' import wanEditor from './editor.vue' import fileUploadBtn from '@/components/FileUploadBtn/index.vue' @@ -193,11 +194,12 @@ const init = async () => { skuList.value = [] if (route.query.id) { const res = await api.commodity.getCommodityDetail.post!({ productId: route.query.id }) - handleGetDialogData(res.data, $dialog, fileList) + handleGetDialogData(res.data, $dialog, fileList, defaultCheckedNodes) adminCategoryData.value = handleGetNewAdminCategoryData(res.data.vvProductPropertyList) initPropertyData(adminCategoryData.value) skuList.value = handleGetNewSkuList(res.data.vvSkuList) } else { + fileList.value = [] initPropertyData(adminCategoryData.value) } } @@ -240,6 +242,7 @@ const htmlContent = ref('自定义') const onDeletePropertyValue = (index: number, id: number) => onClosePropertyValue(index, id, skuList) +const router = useRouter() const onSubmit = () => { const msg = handleValidFormData( $dialog.value.data, @@ -256,10 +259,13 @@ const onSubmit = () => { fileList.value, adminCategoryData.value, htmlContent.value, - skuList.value + skuList.value, + defaultCheckedNodes ) console.warn('----- my data is params111: ', params) + if (route.query.type === 'edit') Object.assign(params, { id: route.query.id }) api.commodity.addOrUpdateCommodity.post!(params).then((res) => { + router.replace({ path: '/goods/commodity/index' }) console.warn('----- my data is res: ', res) }) } diff --git a/src/views/goods/commodity/detail-dialog/submit-method.ts b/src/views/goods/commodity/detail-dialog/submit-method.ts new file mode 100644 index 0000000..75dcebd --- /dev/null +++ b/src/views/goods/commodity/detail-dialog/submit-method.ts @@ -0,0 +1,165 @@ +interface PreviewItem { + fileName: string + name: string + resourceUrl: string + type: 'image' | 'video' + fileType: 'mainImageUrl' | 'videoUrl' | 'subImageUrl' +} + +interface Option { + id: number + categoryPropertyName: string + categoryPropertyValue: string + isAdd?: boolean +} + +interface Category { + typeName: string + typeId: number + vvPropertyValueList: Option[] +} + +// 定义目标数据的结构类型 +export interface TSkuList { + serialNo: string + name: string + salePrice: string + imageUrl: string + stock: number + originPrice: number + promotionPrice: string + vvSkuPropertyValueList: any[] +} + +type CategoryDataMock = Category[] + +export const handleValidFormData = ( + $dialogData: any, + fileList: PreviewItem[], + adminCategoryData: CategoryDataMock, + htmlContent: string, + skuList: TSkuList[] +) => { + console.warn( + '----- my data is fileList, adminCategoryData, skuList: ', + fileList, + adminCategoryData, + skuList + ) + if (!$dialogData.title) { + return '请输入商品标题' + } + if (!$dialogData.appCategoryId) { + return '请选择app类目' + } + if (!$dialogData.adminCategoryId) { + return '请选择后台类目' + } + if (fileList.length === 0) { + return '请上传主图' + } + if (fileList.some((item) => item.fileType === 'mainImageUrl' && !item.resourceUrl)) { + return '请上传主图' + } + if (fileList.some((item) => item.fileType === 'videoUrl' && !item.resourceUrl)) { + return '请上传视频' + } + if (fileList.some((item) => item.fileType === 'subImageUrl' && !item.resourceUrl)) { + return '请上传副图' + } + if (adminCategoryData.length === 0) { + return '请添加商品属性' + } + let msg = '' + skuList.some((item) => { + const nameMap = { + stock: '库存', + originPrice: '成本价', + salePrice: '原价', + promotionPrice: '售价' + } + if (!item.stock) { + msg = `${item.name}的${nameMap.stock}不能为空` + } + if (item.originPrice) { + msg = `${item.name}的${nameMap.originPrice}不能为空` + } + if (!item.salePrice) { + msg = `${item.name}的${nameMap.salePrice}不能为空` + } + if (!item.promotionPrice) { + msg = `${item.name}的${nameMap.promotionPrice}不能为空` + } + return msg + }) + if (msg) return msg + if (!htmlContent) { + return '请填写商品详情' + } + return '' +} + +export const handleGetSubmitParams = ( + isAdd: boolean, + $dialogData: any, + fileList: PreviewItem[], + adminCategoryData: CategoryDataMock, + htmlContent: string, + skuList: TSkuList[], + defaultCheckedNodes: Ref<{ admin: number[]; app: number[] }> +) => { + let vvProductPropertyList = [] + if (isAdd) { + vvProductPropertyList = adminCategoryData.map((item) => ({ + // ...item, + productPropertyName: item.categoryPropertyName, + vvProductPropertyValueList: item.vvPropertyValueList.map((item) => ({ + // ...item, + productPropertyValue: item.categoryPropertyValue + })) + })) + } else { + vvProductPropertyList = adminCategoryData.map((item) => ({ + ...item, + productPropertyName: item.categoryPropertyName, + vvProductPropertyValueList: item.vvPropertyValueList.map((item) => { + if (item.isAdd) delete item.id + return { + ...item, + productPropertyValue: item.categoryPropertyValue + } + }) + })) + } + return { + ...$dialogData, + mainImageUrl: fileList.find((item) => item.fileType === 'mainImageUrl')?.resourceUrl, + videoUrl: fileList.find((item) => item.fileType === 'videoUrl')?.resourceUrl, + appCategoryId1: $dialogData.appCategoryIds?.[0] || defaultCheckedNodes.value.app[0], + appCategoryId2: $dialogData.appCategoryIds?.[1] || defaultCheckedNodes.value.app[1], + ...($dialogData.adminCategoryIds || defaultCheckedNodes.value.admin).reduce((acc, cur, i) => { + acc[`adminCategoryId${i + 1}`] = cur + return acc + }, {}), + vvProductDetailList: fileList + .filter((item) => item.fileType === 'subImageUrl') + .map((item) => ({ + detail: item.resourceUrl, + type: 1 + })), + vvProductPropertyList, + vvSkuList: skuList.map((item) => { + const result = {} + const canDeleteId = !item.id + return { + ...item, + vvSkuPropertyValueList: item.vvSkuPropertyValueList.map((child) => ({ + ...child, + id: canDeleteId ? undefined : child.id, + productPropertyValue: child.categoryPropertyValue, // testzc 编辑提交有问题,没有效果 + productPropertyName: child.categoryPropertyName // testzc 编辑提交有问题,没有效果 + })) + } + }) + } +} diff --git a/src/views/goods/commodity/detail-dialog/use-method.ts b/src/views/goods/commodity/detail-dialog/use-method.ts index 17f5618..f2fe8f6 100644 --- a/src/views/goods/commodity/detail-dialog/use-method.ts +++ b/src/views/goods/commodity/detail-dialog/use-method.ts @@ -1,8 +1,8 @@ -import { Atrans$DialogRes } from '@/utils/page/config' import { useDraggable } from 'vue-draggable-plus' // 定义源数据的结构类型 interface Option { id: number + categoryPropertyName: string categoryPropertyValue: string isAdd?: boolean } @@ -84,13 +84,13 @@ export const usePropertyValue = () => { debugger const i = adminCategoryData[index].vvPropertyValueList.findIndex((item: any) => item.id === id) const temp = adminCategoryData[index].vvPropertyValueList[i] - const filterName = temp.productPropertyName + ':' + temp.productPropertyValue + const filterName = temp.categoryPropertyName + ':' + temp.categoryPropertyValue adminCategoryData[index].vvPropertyValueList.splice(i, 1) const deleteIndexs: number[] = [] skuList.value.forEach((item: TSkuList, skuIndex: number) => { if ( item.vvSkuPropertyValueList.find( - (it) => it.productPropertyName + ':' + it.productPropertyValue === filterName + (it) => it.categoryPropertyName + ':' + it.categoryPropertyValue === filterName ) ) { deleteIndexs.push(skuIndex) @@ -222,7 +222,13 @@ export const handleLoadNode = (node: any, resolve: any) => { value: item.id, hasChild: item.hasChild, disabled: !!item.hasChild, - categoryPropertyList: item.vvCategoryPropertyDTOList + categoryPropertyList: (item.vvCategoryPropertyDTOList || []).map((child: any) => ({ + ...child, + vvPropertyValueList: child.vvPropertyValueList.map((it: any) => ({ + ...it, + categoryPropertyName: child.categoryPropertyName + })) + })) })) ) }) @@ -257,220 +263,3 @@ export const handleCheckChange = ( data[type + 'CategoryIds'] = [...checkedStatus.halfCheckedKeys, ...checkedStatus.checkedKeys] return checkedData } - -interface PreviewItem { - fileName: string - name: string - resourceUrl: string - type: 'image' | 'video' - fileType: 'mainImageUrl' | 'videoUrl' | 'subImageUrl' -} - -// 编辑的时候从接口响应数据提取$dialog数据 -export const handleGetDialogData = ( - data: any, - $dialog: Ref, - fileList: Ref -) => { - const result = { ...$dialog.value.data } - result.appCategoryId = data.appCategoryId2 - result.adminCategoryId = data.adminCategoryId - defaultCheckedNodes.value.admin = extractAdminCategoryIds(data) - defaultCheckedNodes.value.app = [data.appCategoryId1, data.appCategoryId2] - result.isTest = data.isTest - result.title = data.title - const files = [ - { - fileName: '主图', - name: '主图', - fileType: 'mainImageUrl', - resourceUrl: data.mainImageUrl, - type: 'image' - }, - { - fileName: '视频', - name: '视频', - fileType: 'videoUrl', - resourceUrl: data.videoUrl, - type: 'video' - } - ] - files.push( - ...data.vvProductDetailList - .filter((item: any) => item.type === 1) - .map((item: any) => ({ - fileName: '副图', - name: '副图', - resourceUrl: item.resourceUrl, - fileType: 'subImageUrl', - type: 'image' - })) - ) - fileList.value = files as PreviewItem[] - $dialog.value.data = result -} - -// 将adminCategoryId1, adminCategoryId2, ... 提取出来并排序 -function extractAdminCategoryIds(obj: Record): number[] { - return Object.entries(obj) - .filter(([key]) => key.startsWith('adminCategoryId')) - .sort(([keyA], [keyB]) => { - // 按数字部分排序 (adminCategoryId1 < adminCategoryId2) - const numA = parseInt(keyA.replace('adminCategoryId', '')) - const numB = parseInt(keyB.replace('adminCategoryId', '')) - return numA - numB - }) - .map(([, value]) => value) - .filter((val) => ![undefined, null].includes(val)) as number[] -} - -// 编辑的时候对后台类目的数据进行重组 -export const handleGetNewAdminCategoryData = (data: any) => { - return data.map((item: any) => ({ - ...item, - categoryPropertyName: item.productPropertyName, - vvPropertyValueList: item.vvProductPropertyValueList.map((item: any) => ({ - ...item, - categoryPropertyValue: item.productPropertyValue - })), - vvProductPropertyValueList: undefined - })) -} - -// 编辑的时候对sku进行重组 -export const handleGetNewSkuList = (data: any) => { - return data.map((item: any) => ({ - ...item, - name: item.vvSkuPropertyValueList.reduce((str: string, cur: any) => { - str += cur.productPropertyValue - return str - }, '') - })) -} - -export const handleValidFormData = ( - $dialogData: any, - fileList: PreviewItem[], - adminCategoryData: CategoryDataMock, - htmlContent: string, - skuList: TSkuList[] -) => { - console.warn( - '----- my data is fileList, adminCategoryData, skuList: ', - fileList, - adminCategoryData, - skuList - ) - if (!$dialogData.title) { - return '请输入商品标题' - } - if (!$dialogData.appCategoryId) { - return '请选择app类目' - } - if (!$dialogData.adminCategoryId) { - return '请选择后台类目' - } - if (fileList.length === 0) { - return '请上传主图' - } - if (fileList.some((item) => item.fileType === 'mainImageUrl' && !item.resourceUrl)) { - return '请上传主图' - } - if (fileList.some((item) => item.fileType === 'videoUrl' && !item.resourceUrl)) { - return '请上传视频' - } - if (fileList.some((item) => item.fileType === 'subImageUrl' && !item.resourceUrl)) { - return '请上传副图' - } - if (adminCategoryData.length === 0) { - return '请添加商品属性' - } - let msg = '' - skuList.some((item) => { - const nameMap = { - stock: '库存', - originPrice: '成本价', - salePrice: '原价', - promotionPrice: '售价' - } - if (!item.stock) { - msg = `${item.name}的${nameMap.stock}不能为空` - } - if (item.originPrice) { - msg = `${item.name}的${nameMap.originPrice}不能为空` - } - if (!item.salePrice) { - msg = `${item.name}的${nameMap.salePrice}不能为空` - } - if (!item.promotionPrice) { - msg = `${item.name}的${nameMap.promotionPrice}不能为空` - } - return msg - }) - if (msg) return msg - if (!htmlContent) { - return '请填写商品详情' - } - return '' -} - -export const handleGetSubmitParams = ( - isAdd: boolean, - $dialogData: any, - fileList: PreviewItem[], - adminCategoryData: CategoryDataMock, - htmlContent: string, - skuList: TSkuList[] -) => { - let vvProductPropertyList = [] - if (isAdd) { - vvProductPropertyList = adminCategoryData.map((item) => ({ - // ...item, - productPropertyName: item.categoryPropertyName, - vvProductPropertyValueList: item.vvPropertyValueList.map((item) => ({ - // ...item, - productPropertyValue: item.categoryPropertyValue - })) - })) - } else { - vvProductPropertyList = adminCategoryData.map((item) => ({ - ...item, - productPropertyName: item.categoryPropertyName, - vvProductPropertyValueList: item.vvPropertyValueList.map((item) => ({ - ...item, - productPropertyValue: item.categoryPropertyValue - })) - })) - } - return { - ...$dialogData, - mainImageUrl: fileList.find((item) => item.fileType === 'mainImageUrl')?.resourceUrl, - videoUrl: fileList.find((item) => item.fileType === 'videoUrl')?.resourceUrl, - appCategoryId1: $dialogData.appCategoryIds?.[0] || defaultCheckedNodes.value.app[0], - appCategoryId2: $dialogData.appCategoryIds?.[1] || defaultCheckedNodes.value.app[1], - ...($dialogData.adminCategoryIds || defaultCheckedNodes.value.admin).reduce((acc, cur, i) => { - acc[`adminCategoryId${i + 1}`] = cur - return acc - }, {}), - vvProductDetailList: fileList - .filter((item) => item.fileType === 'subImageUrl') - .map((item) => ({ - detail: item.resourceUrl, - type: 1 - })), - vvProductPropertyList, - vvSkuList: skuList.map((item) => { - const result = {} - const canDeleteId = !item.id - return { - ...item, - vvSkuPropertyValueList: item.vvSkuPropertyValueList.map((child) => ({ - ...child, - id: canDeleteId ? undefined : child.id, - productPropertyValue: item.categoryPropertyValue, // testzc 编辑提交有问题,没有效果 - productPropertyName: item.categoryPropertyName // testzc 编辑提交有问题,没有效果 - })) - } - }) - } -}