From f9780b636c3f7320e71707f2d0bc9311632d68db Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 31 Aug 2023 21:13:20 +0800 Subject: [PATCH] =?UTF-8?q?fix:=201=E3=80=81=E4=BF=AE=E5=A4=8D=E8=90=A5?= =?UTF-8?q?=E9=94=80=E6=B4=BB=E5=8A=A8=E7=9B=B8=E5=85=B3=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=89=93=E4=B8=8D=E5=BC=80=E7=9A=84=E9=97=AE=E9=A2=98=202?= =?UTF-8?q?=E3=80=81=E4=BF=AE=E5=A4=8D=20spu=20=E6=B7=BB=E5=8A=A0=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98=202=E3=80=81=E9=87=8D?= =?UTF-8?q?=E6=9E=84=20spu=20=E7=9A=84=20sku=20=E6=A0=A1=E9=AA=8C=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E4=B8=BA=E9=80=9A=E7=94=A8=E9=85=8D=E7=BD=AE=E7=9A=84?= =?UTF-8?q?=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/product/spu/components/SkuList.vue | 17 ++----- .../mall/product/spu/components/index.ts | 31 ++++++++++++- .../mall/product/spu/form/BasicInfoForm.vue | 44 +++++++++++++++++-- src/views/mall/product/spu/form/index.vue | 22 +++++----- 4 files changed, 86 insertions(+), 28 deletions(-) diff --git a/src/views/mall/product/spu/components/SkuList.vue b/src/views/mall/product/spu/components/SkuList.vue index 1cc70298..81e2347d 100644 --- a/src/views/mall/product/spu/components/SkuList.vue +++ b/src/views/mall/product/spu/components/SkuList.vue @@ -328,24 +328,15 @@ const tableHeaders = ref<{ prop: string; label: string }[]>([]) // 多属性表 * 保存时,每个商品规格的表单要校验下。例如说,销售金额最低是 0.01 这种。 */ const validateSku = () => { - const checks = ['price', 'marketPrice', 'costPrice'] let warningInfo = '请检查商品各行相关属性配置,' let validate = true // 默认通过 for (const sku of formData.value!.skus!) { // 作为活动组件的校验 - if (props.isActivityComponent) { - for (const rule of props?.ruleConfig) { - const arg = getValue(sku, rule.name) - if (!rule.rule(arg)) { - validate = false // 只要有一个不通过则直接不通过 - warningInfo += rule.message - break - } - } - } else { - if (checks.some((check) => sku[check] < 0.01)) { + for (const rule of props?.ruleConfig) { + const arg = getValue(sku, rule.name) + if (!rule.rule(arg)) { validate = false // 只要有一个不通过则直接不通过 - warningInfo = '商品相关价格不能低于 0.01 元!!' + warningInfo += rule.message break } } diff --git a/src/views/mall/product/spu/components/index.ts b/src/views/mall/product/spu/components/index.ts index 8f793c51..e2cbe73d 100644 --- a/src/views/mall/product/spu/components/index.ts +++ b/src/views/mall/product/spu/components/index.ts @@ -1,4 +1,5 @@ import SkuList from './SkuList.vue' +import { Spu } from '@/api/mall/product/spu' interface PropertyAndValues { id: number @@ -22,4 +23,32 @@ interface RuleConfig { message: string } -export { SkuList, PropertyAndValues, RuleConfig } +/** + * 获得商品的规格列表 - 商品相关的公共函数 + * + * @param spu + * @return PropertyAndValues 规格列表 + */ +const getPropertyList = (spu: Spu): PropertyAndValues[] => { + // 直接拿返回的 skus 属性逆向生成出 propertyList + const properties: PropertyAndValues[] = [] + // 只有是多规格才处理 + if (spu.specType) { + spu.skus?.forEach((sku) => { + sku.properties?.forEach(({ propertyId, propertyName, valueId, valueName }) => { + // 添加属性 + if (!properties?.some((item) => item.id === propertyId)) { + properties.push({ id: propertyId!, name: propertyName!, values: [] }) + } + // 添加属性值 + const index = properties?.findIndex((item) => item.id === propertyId) + if (!properties[index].values?.some((value) => value.id === valueId)) { + properties[index].values?.push({ id: valueId!, name: valueName! }) + } + }) + }) + } + return properties +} + +export { SkuList, PropertyAndValues, RuleConfig, getPropertyList } diff --git a/src/views/mall/product/spu/form/BasicInfoForm.vue b/src/views/mall/product/spu/form/BasicInfoForm.vue index 678b564d..50fb8793 100644 --- a/src/views/mall/product/spu/form/BasicInfoForm.vue +++ b/src/views/mall/product/spu/form/BasicInfoForm.vue @@ -109,7 +109,12 @@ - + 添加规格 @@ -120,7 +125,12 @@ - + @@ -175,7 +185,11 @@ import { propTypes } from '@/utils/propTypes' import { checkSelectedNode, defaultProps, handleTree, treeToString } from '@/utils/tree' import { createImageViewer } from '@/components/ImageViewer' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' -import { PropertyAndValues, SkuList } from '@/views/mall/product/spu/components/index.ts' +import { + PropertyAndValues, + RuleConfig, + SkuList +} from '@/views/mall/product/spu/components/index.ts' import ProductAttributes from './ProductAttributes.vue' import ProductPropertyAddForm from './ProductPropertyAddForm.vue' import { basicInfoSchema } from './spu.data' @@ -186,6 +200,30 @@ import * as ExpressTemplateApi from '@/api/mall/trade/delivery/expressTemplate' defineOptions({ name: 'ProductSpuBasicInfoForm' }) +// sku 相关属性校验规则 +const ruleConfig: RuleConfig[] = [ + { + name: 'stock', + rule: (arg) => arg >= 1, + message: '商品库存必须大于等于 1 !!!' + }, + { + name: 'price', + rule: (arg) => arg >= 0.01, + message: '商品销售价格必须大于等于 0.01 !!!' + }, + { + name: 'marketPrice', + rule: (arg) => arg >= 0.01, + message: '商品市场价格必须大于等于 0.01 !!!' + }, + { + name: 'costPrice', + rule: (arg) => arg >= 0.01, + message: '商品成本价格必须大于等于 0.01 !!!' + } +] + // ====== 商品详情相关操作 ====== const { allSchemas } = useCrudSchemas(basicInfoSchema) /** 商品图预览 */ diff --git a/src/views/mall/product/spu/form/index.vue b/src/views/mall/product/spu/form/index.vue index db5b0445..526bb338 100644 --- a/src/views/mall/product/spu/form/index.vue +++ b/src/views/mall/product/spu/form/index.vue @@ -142,17 +142,17 @@ const submitForm = async () => { await unref(otherSettingsRef)?.validate() // 深拷贝一份, 这样最终 server 端不满足,不需要恢复, const deepCopyFormData = cloneDeep(unref(formData.value)) as ProductSpuApi.Spu - // 兜底处理 sku 空数据 - formData.value.skus!.forEach((sku) => { - // 因为是空数据这里判断一下商品条码是否为空就行 - if (sku.barCode === '') { - const index = deepCopyFormData.skus!.findIndex( - (item) => JSON.stringify(item.properties) === JSON.stringify(sku.properties) - ) - // 删除这条 sku - deepCopyFormData.skus!.splice(index, 1) - } - }) + // 兜底处理 sku 空数据 TODO 后续没得问题就移除 + // formData.value.skus!.forEach((sku) => { + // // 因为是空数据这里判断一下商品条码是否为空就行 + // if (sku.barCode === '') { + // const index = deepCopyFormData.skus!.findIndex( + // (item) => JSON.stringify(item.properties) === JSON.stringify(sku.properties) + // ) + // // 删除这条 sku + // deepCopyFormData.skus!.splice(index, 1) + // } + // }) deepCopyFormData.skus!.forEach((item) => { // 给sku name赋值 item.name = deepCopyFormData.name