Browse Source

fix: 修复 SkuList TODO 优化相关算法

puhui999 1 year ago
parent
commit
9c06832d7e
1 changed files with 60 additions and 122 deletions
  1. 60 122
      src/views/mall/product/spu/components/SkuList.vue

+ 60 - 122
src/views/mall/product/spu/components/SkuList.vue

@@ -1,6 +1,6 @@
 <template>
   <el-table
-    :data="isBatch ? SkuData : formData.skus"
+    :data="isBatch ? skuList : formData.skus"
     border
     class="tabNumWidth"
     max-height="500"
@@ -14,7 +14,7 @@
     <template v-if="formData.specType && !isBatch">
       <!--  根据商品属性动态添加  -->
       <el-table-column
-        v-for="(item, index) in tableHeaderList"
+        v-for="(item, index) in tableHeaders"
         :key="index"
         :label="item.label"
         align="center"
@@ -32,65 +32,45 @@
       </template>
     </el-table-column>
     <!-- TODO @puhui999:用户输入的时候,是按照元;分主要是我们自己用; -->
-    <el-table-column align="center" label="销售价()" min-width="168">
+    <el-table-column align="center" label="销售价()" min-width="168">
       <template #default="{ row }">
-        <el-input-number v-model="row.price" :min="0" class="w-100%" controls-position="right" />
+        <el-input-number v-model="row.price" :min="0" class="w-100%" />
       </template>
     </el-table-column>
-    <el-table-column align="center" label="市场价()" min-width="168">
+    <el-table-column align="center" label="市场价()" min-width="168">
       <template #default="{ row }">
-        <el-input-number
-          v-model="row.marketPrice"
-          :min="0"
-          class="w-100%"
-          controls-position="right"
-        />
+        <el-input-number v-model="row.marketPrice" :min="0" class="w-100%" />
       </template>
     </el-table-column>
-    <el-table-column align="center" label="成本价()" min-width="168">
+    <el-table-column align="center" label="成本价(元)" min-width="168">
       <template #default="{ row }">
-        <el-input-number
-          v-model="row.costPrice"
-          :min="0"
-          class="w-100%"
-          controls-position="right"
-        />
+        <el-input-number v-model="row.costPrice" :min="0" class="w-100%" />
       </template>
     </el-table-column>
     <el-table-column align="center" label="库存" min-width="168">
       <template #default="{ row }">
-        <el-input-number v-model="row.stock" :min="0" class="w-100%" controls-position="right" />
+        <el-input-number v-model="row.stock" :min="0" class="w-100%" />
       </template>
     </el-table-column>
     <el-table-column align="center" label="重量(kg)" min-width="168">
       <template #default="{ row }">
-        <el-input-number v-model="row.weight" :min="0" class="w-100%" controls-position="right" />
+        <el-input-number v-model="row.weight" :min="0" class="w-100%" />
       </template>
     </el-table-column>
     <el-table-column align="center" label="体积(m^3)" min-width="168">
       <template #default="{ row }">
-        <el-input-number v-model="row.volume" :min="0" class="w-100%" controls-position="right" />
+        <el-input-number v-model="row.volume" :min="0" class="w-100%" />
       </template>
     </el-table-column>
     <template v-if="formData.subCommissionType">
-      <el-table-column align="center" label="一级返佣()" min-width="168">
+      <el-table-column align="center" label="一级返佣()" min-width="168">
         <template #default="{ row }">
-          <el-input-number
-            v-model="row.subCommissionFirstPrice"
-            :min="0"
-            class="w-100%"
-            controls-position="right"
-          />
+          <el-input-number v-model="row.subCommissionFirstPrice" :min="0" class="w-100%" />
         </template>
       </el-table-column>
-      <el-table-column align="center" label="二级返佣()" min-width="168">
+      <el-table-column align="center" label="二级返佣(元)" min-width="168">
         <template #default="{ row }">
-          <el-input-number
-            v-model="row.subCommissionSecondPrice"
-            :min="0"
-            class="w-100%"
-            controls-position="right"
-          />
+          <el-input-number v-model="row.subCommissionSecondPrice" :min="0" class="w-100%" />
         </template>
       </el-table-column>
     </template>
@@ -107,9 +87,8 @@
 <script lang="ts" name="SkuList" setup>
 import { UploadImg } from '@/components/UploadFile'
 import { PropType } from 'vue'
-import { SpuType } from '@/api/mall/product/management/type/spuType'
+import type { Property, SkuType, SpuType } from '@/api/mall/product/spu'
 import { propTypes } from '@/utils/propTypes'
-import { SkuType } from '@/api/mall/product/management/type/skuType'
 import { copyValueToTarget } from '@/utils'
 
 const props = defineProps({
@@ -121,66 +100,35 @@ const props = defineProps({
     type: Array,
     default: () => []
   },
-  isBatch: propTypes.bool.def(false) // 是否批量操作
+  isBatch: propTypes.bool.def(false) // 是否作为批量操作组件
 })
 const formData = ref<SpuType>() // 表单数据
-// 批量添加时的零时数据 TODO @puhui999:小写开头哈;然后变量都尾注释
-const SkuData = ref<SkuType[]>([
+const skuList = ref<SkuType[]>([
   {
-    /**
-     * 商品价格,单位:分
-     */
-    price: 0,
-    /**
-     * 市场价,单位:分
-     */
-    marketPrice: 0,
-    /**
-     * 成本价,单位:分
-     */
-    costPrice: 0,
-    /**
-     * 商品条码
-     */
-    barCode: '',
-    /**
-     * 图片地址
-     */
-    picUrl: '',
-    /**
-     * 库存
-     */
-    stock: 0,
-    /**
-     * 商品重量,单位:kg 千克
-     */
-    weight: 0,
-    /**
-     * 商品体积,单位:m^3 平米
-     */
-    volume: 0,
-    /**
-     * 一级分销的佣金,单位:分
-     */
-    subCommissionFirstPrice: 0,
-    /**
-     * 二级分销的佣金,单位:分
-     */
-    subCommissionSecondPrice: 0
+    price: 0, // 商品价格
+    marketPrice: 0, // 市场价
+    costPrice: 0, // 成本价
+    barCode: '', // 商品条码
+    picUrl: '', // 图片地址
+    stock: 0, // 库存
+    weight: 0, // 商品重量
+    volume: 0, // 商品体积
+    subCommissionFirstPrice: 0, // 一级分销的佣金
+    subCommissionSecondPrice: 0 // 二级分销的佣金
   }
-])
+]) // 批量添加时的临时数据
 
 /** 批量添加 */
 const batchAdd = () => {
   formData.value.skus.forEach((item) => {
-    copyValueToTarget(item, SkuData.value[0])
+    copyValueToTarget(item, skuList.value[0])
   })
 }
 
-const tableHeaderList = ref<{ prop: string; label: string }[]>([])
+const tableHeaders = ref<{ prop: string; label: string }[]>([]) // 多属性表头
 
 /**
- * 将传进来的值赋值给SkuData
+ * 将传进来的值赋值给skuList
  */
 watch(
   () => props.propFormData,
@@ -197,21 +145,18 @@ watch(
 // TODO @芋艿:看看 chatgpt 可以进一步下面几个方法的实现不
 /** 生成表数据 */
 const generateTableData = (data: any[]) => {
-  // 构建数据结构
-  const propertiesItemList = []
-  for (const item of data) {
-    const objList = []
-    for (const v of item.values) {
-      const obj = { propertyId: 0, valueId: 0, valueName: '' }
-      obj.propertyId = item.id
-      obj.valueId = v.id
-      obj.valueName = v.name
-      objList.push(obj)
-    }
-    propertiesItemList.push(objList)
-  }
+  // 构建数据结构 fix: 使用map替换多重for循环
+  const propertiesItemList = data.map((item) =>
+    item.values.map((v) => ({
+      propertyId: item.id,
+      propertyName: item.name,
+      valueId: v.id,
+      valueName: v.name
+    }))
+  )
   const buildList = build(propertiesItemList)
-  // 如果构建后的组合数跟sku数量一样的话则不用处理,添加新属性没有属性值也不做处理 (解决编辑表单时或查看详情时数据回显问题)
+  // 如果构建后的组合数跟sku数量一样的话则不用处理,添加新属性没有属性值也不做处理
+  // fix: 解决编辑表单时或查看详情时数据回显问题
   if (
     buildList.length === formData.value.skus.length ||
     data.some((item) => item.values.length === 0)
@@ -222,7 +167,7 @@ const generateTableData = (data: any[]) => {
   formData.value!.skus = []
   buildList.forEach((item) => {
     const row = {
-      properties: [],
+      properties: Array.isArray(item) ? item : [item],
       price: 0,
       marketPrice: 0,
       costPrice: 0,
@@ -234,32 +179,25 @@ const generateTableData = (data: any[]) => {
       subCommissionFirstPrice: 0,
       subCommissionSecondPrice: 0
     }
-    // 判断是否是单一属性的情况
-    if (Array.isArray(item)) {
-      row.properties = item
-    } else {
-      row.properties.push(item)
-    }
     formData.value.skus.push(row)
   })
 }
-
 /** 构建所有排列组合 */
-const build = (list: any[]) => {
-  if (list.length === 0) {
+const build = (propertyValuesList: Property[][]) => {
+  if (propertyValuesList.length === 0) {
     return []
-  } else if (list.length === 1) {
-    return list[0]
+  } else if (propertyValuesList.length === 1) {
+    return propertyValuesList[0]
   } else {
-    const result = []
-    const rest = build(list.slice(1))
-    for (let i = 0; i < list[0].length; i++) {
+    const result: Property[][] = []
+    const rest = build(propertyValuesList.slice(1))
+    for (let i = 0; i < propertyValuesList[0].length; i++) {
       for (let j = 0; j < rest.length; j++) {
         // 第一次不是数组结构,后面的都是数组结构
         if (Array.isArray(rest[j])) {
-          result.push([list[0][i], ...rest[j]])
+          result.push([propertyValuesList[0][i], ...rest[j]])
         } else {
-          result.push([list[0][i], rest[j]])
+          result.push([propertyValuesList[0][i], rest[j]])
         }
       }
     }
@@ -270,12 +208,12 @@ const build = (list: any[]) => {
 /** 监听属性列表生成相关参数和表头 */
 watch(
   () => props.attributeList,
-  (data) => {
+  (attributeList) => {
     // 如果不是多规格则结束
     if (!formData.value.specType) return
     // 如果当前组件作为批量添加数据使用则重置表数据
     if (props.isBatch) {
-      SkuData.value = [
+      skuList.value = [
         {
           price: 0,
           marketPrice: 0,
@@ -291,15 +229,15 @@ watch(
       ]
     }
     // 判断代理对象是否为空
-    if (JSON.stringify(data) === '[]') return
+    if (JSON.stringify(attributeList) === '[]') return
     // 重置表头
-    tableHeaderList.value = []
+    tableHeaders.value = []
     // 生成表头
-    data.forEach((item, index) => {
+    attributeList.forEach((item, index) => {
       // name加属性项index区分属性值
-      tableHeaderList.value.push({ prop: `name${index}`, label: item.name })
+      tableHeaders.value.push({ prop: `name${index}`, label: item.name })
     })
-    generateTableData(data)
+    generateTableData(attributeList)
   },
   {
     deep: true,