SpuAndSkuList.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <template>
  2. <el-table :data="spuData" :default-expand-all="true">
  3. <el-table-column type="expand" width="30">
  4. <template #default="{ row }">
  5. <SkuList
  6. ref="skuListRef"
  7. :is-activity-component="true"
  8. :prop-form-data="spuPropertyList.find((item) => item.spuId === row.id)?.spuDetail"
  9. :property-list="spuPropertyList.find((item) => item.spuId === row.id)?.propertyList"
  10. :rule-config="ruleConfig"
  11. >
  12. <template #extension>
  13. <el-table-column align="center" label="秒杀库存" min-width="168">
  14. <template #default="{ row: sku }">
  15. <el-input-number v-model="sku.productConfig.stock" :min="0" class="w-100%" />
  16. </template>
  17. </el-table-column>
  18. <el-table-column align="center" label="秒杀价格(元)" min-width="168">
  19. <template #default="{ row: sku }">
  20. <el-input-number
  21. v-model="sku.productConfig.seckillPrice"
  22. :min="0"
  23. :precision="2"
  24. :step="0.1"
  25. class="w-100%"
  26. />
  27. </template>
  28. </el-table-column>
  29. </template>
  30. </SkuList>
  31. </template>
  32. </el-table-column>
  33. <el-table-column key="id" align="center" label="商品编号" prop="id" />
  34. <el-table-column label="商品图" min-width="80">
  35. <template #default="{ row }">
  36. <el-image :src="row.picUrl" class="w-30px h-30px" @click="imagePreview(row.picUrl)" />
  37. </template>
  38. </el-table-column>
  39. <el-table-column :show-overflow-tooltip="true" label="商品名称" min-width="300" prop="name" />
  40. <el-table-column align="center" label="商品售价" min-width="90" prop="price">
  41. <template #default="{ row }">
  42. {{ formatToFraction(row.price) }}
  43. </template>
  44. </el-table-column>
  45. <el-table-column align="center" label="销量" min-width="90" prop="salesCount" />
  46. <el-table-column align="center" label="库存" min-width="90" prop="stock" />
  47. </el-table>
  48. </template>
  49. <script generic="T extends Spu" lang="ts" setup>
  50. // TODO 后续计划重新封装作为活动商品配置通用组件;可以等其他活动做到的时候,在统一处理 SPU 选择组件哈
  51. import { formatToFraction } from '@/utils'
  52. import { createImageViewer } from '@/components/ImageViewer'
  53. import { Spu } from '@/api/mall/product/spu'
  54. import { RuleConfig, SkuList } from '@/views/mall/product/spu/components'
  55. import { SeckillProductVO } from '@/api/mall/promotion/seckill/seckillActivity'
  56. import { SpuProperty } from '@/views/mall/promotion/components/index'
  57. defineOptions({ name: 'PromotionSpuAndSkuList' })
  58. // TODO @puhui999:是不是改成传递一个 spu 就好啦? 因为活动商品可以多选所以展示编辑的时候需要展示多个
  59. const props = defineProps<{
  60. spuList: T[]
  61. ruleConfig: RuleConfig[]
  62. spuPropertyListP: SpuProperty<T>[]
  63. }>()
  64. const spuData = ref<Spu[]>([]) // spu 详情数据列表
  65. const skuListRef = ref() // 商品属性列表Ref
  66. const spuPropertyList = ref<SpuProperty<T>[]>([]) // spuId 对应的 sku 的属性列表
  67. /**
  68. * 获取所有 sku 秒杀配置
  69. * @param extendedAttribute 在 sku 上扩展的属性,例:秒杀活动 sku 扩展属性 productConfig 请参考 seckillActivity.ts
  70. */
  71. const getSkuConfigs: <V>(extendedAttribute: string) => V[] = (extendedAttribute: string) => {
  72. skuListRef.value.validateSku()
  73. const seckillProducts: SeckillProductVO[] = []
  74. spuPropertyList.value.forEach((item) => {
  75. item.spuDetail.skus.forEach((sku) => {
  76. seckillProducts.push(sku[extendedAttribute])
  77. })
  78. })
  79. return seckillProducts
  80. }
  81. // 暴露出给表单提交时使用
  82. defineExpose({ getSkuConfigs })
  83. /** 商品图预览 */
  84. const imagePreview = (imgUrl: string) => {
  85. createImageViewer({
  86. zIndex: 99999999,
  87. urlList: [imgUrl]
  88. })
  89. }
  90. /**
  91. * 将传进来的值赋值给 skuList
  92. */
  93. watch(
  94. () => props.spuList,
  95. (data) => {
  96. if (!data) return
  97. spuData.value = data as Spu[]
  98. },
  99. {
  100. deep: true,
  101. immediate: true
  102. }
  103. )
  104. /**
  105. * 将传进来的值赋值给 skuList
  106. */
  107. watch(
  108. () => props.spuPropertyListP,
  109. (data) => {
  110. if (!data) return
  111. spuPropertyList.value = data as SpuProperty<T>[]
  112. },
  113. {
  114. deep: true,
  115. immediate: true
  116. }
  117. )
  118. </script>