Commit 6d48bd1ed8651f4214b622052c5afd5269bff076

Authored by YunaiV
1 parent 544597d6

promotion:完善限时折扣的添加逻辑

Showing 16 changed files with 308 additions and 44 deletions
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java
1 1 package cn.iocoder.yudao.module.product.controller.admin.sku;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  6 +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO;
  7 +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
  8 +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
  9 +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
  10 +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
  11 +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
3 12 import io.swagger.annotations.Api;
  13 +import io.swagger.annotations.ApiOperation;
4 14 import org.springframework.validation.annotation.Validated;
  15 +import org.springframework.web.bind.annotation.GetMapping;
5 16 import org.springframework.web.bind.annotation.RequestMapping;
6 17 import org.springframework.web.bind.annotation.RestController;
7 18  
  19 +import javax.annotation.Resource;
  20 +import java.util.Collections;
  21 +import java.util.List;
  22 +import java.util.Map;
  23 +
  24 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  25 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  26 +
8 27 @Api(tags = "管理后台 - 商品 sku")
9 28 @RestController
10 29 @RequestMapping("/product/sku")
11 30 @Validated
12 31 public class ProductSkuController {
13 32  
  33 + @Resource
  34 + private ProductSkuService productSkuService;
  35 + @Resource
  36 + private ProductSpuService productSpuService;
  37 +
  38 + @GetMapping("/get-option-list")
  39 + @ApiOperation("获得商品 SKU 选项的列表")
  40 +// @PreAuthorize("@ss.hasPermission('product:sku:query')")
  41 + public CommonResult<List<ProductSkuOptionRespVO>> getSkuOptionList() {
  42 + // 获得 SKU 列表
  43 + List<ProductSkuDO> skus = productSkuService.getSkuList();
  44 + if (CollUtil.isEmpty(skus)) {
  45 + return success(Collections.emptyList());
  46 + }
  47 +
  48 + // 获得对应的 SPU 映射
  49 + Map<Long, ProductSpuDO> spuMap = productSpuService.getSpuMap(convertSet(skus, ProductSkuDO::getSpuId));
  50 + // 转换为返回结果
  51 + List<ProductSkuOptionRespVO> skuVOs = ProductSkuConvert.INSTANCE.convertList05(skus);
  52 + skuVOs.forEach(sku -> MapUtils.findAndThen(spuMap, sku.getSpuId(),
  53 + spu -> sku.setSpuId(spu.getId()).setSpuName(spu.getName())));
  54 + return success(skuVOs);
  55 + }
  56 +
14 57 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +
  7 +@ApiModel(value = "管理后台 - 商品 SKU 选项 Response VO", description = "用于前端 SELECT 选项")
  8 +@Data
  9 +public class ProductSkuOptionRespVO {
  10 +
  11 + @ApiModelProperty(value = "主键", required = true, example = "1024")
  12 + private Long id;
  13 +
  14 + @ApiModelProperty(value = "商品 SKU 名字", example = "红色")
  15 + private String name;
  16 +
  17 + @ApiModelProperty(value = "销售价格", required = true, example = "100", notes = "单位:分")
  18 + private String price;
  19 +
  20 + @ApiModelProperty(value = "库存", required = true, example = "100")
  21 + private Integer stock;
  22 +
  23 + // ========== 商品 SPU 信息 ==========
  24 +
  25 + @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1")
  26 + private Long spuId;
  27 +
  28 + @ApiModelProperty(value = "商品 SPU 名字", required = true, example = "iPhone 11")
  29 + private String spuName;
  30 +
  31 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java
... ... @@ -9,7 +9,7 @@ import lombok.ToString;
9 9 import java.util.Date;
10 10 import java.util.List;
11 11  
12   -@ApiModel("管理后台 - 商品sku Response VO")
  12 +@ApiModel("管理后台 - 商品 SKU Response VO")
13 13 @Data
14 14 @EqualsAndHashCode(callSuper = true)
15 15 @ToString(callSuper = true)
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.convert.sku;
2 2  
3 3 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
4 4 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
  5 +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO;
5 6 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
6 7 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO;
7 8 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
... ... @@ -11,7 +12,7 @@ import org.mapstruct.factory.Mappers;
11 12 import java.util.List;
12 13  
13 14 /**
14   - * 商品sku Convert
  15 + * 商品 SKU Convert
15 16 *
16 17 * @author 芋道源码
17 18 */
... ... @@ -36,4 +37,6 @@ public interface ProductSkuConvert {
36 37  
37 38 List<ProductSkuRespDTO> convertList04(List<ProductSkuDO> list);
38 39  
  40 + List<ProductSkuOptionRespVO> convertList05(List<ProductSkuDO> skus);
  41 +
39 42 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java
... ... @@ -97,6 +97,7 @@ public class ProductSkuDO extends BaseDO {
97 97 * 商品属性
98 98 */
99 99 @Data
  100 + @NoArgsConstructor
100 101 @AllArgsConstructor
101 102 public static class Property {
102 103  
... ... @@ -130,19 +131,5 @@ public class ProductSkuDO extends BaseDO {
130 131  
131 132 }
132 133  
133   - // TODO ========== 待定字段:yv =========
134   - // TODO brokerage:一级返佣
135   - // TODO brokerage_two:二级返佣
136   - // TODO pink_price:拼团价
137   - // TODO pink_stock:拼团库存
138   - // TODO seckill_price:秒杀价
139   - // TODO seckill_stock:秒杀库存
140   - // TODO integral:需要积分
141   -
142   - // TODO ========== 待定字段:cf =========
143   - // TODO type 活动显示排序 0=默认 1=秒 2=砍价 3=拼团
144   - // TODO quota 活动限购数量
145   - // TODO quota_show 活动限购数量显示
146   -
147 134 }
148 135  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
... ... @@ -14,22 +14,29 @@ import java.util.List;
14 14 public interface ProductSkuService {
15 15  
16 16 /**
17   - * 删除商品sku
  17 + * 删除商品 SKU
18 18 *
19 19 * @param id 编号
20 20 */
21 21 void deleteSku(Long id);
22 22  
23 23 /**
24   - * 获得商品sku
  24 + * 获得商品 SKU 信息
25 25 *
26 26 * @param id 编号
27   - * @return 商品sku
  27 + * @return 商品 SKU 信息
28 28 */
29 29 ProductSkuDO getSku(Long id);
30 30  
31 31 /**
32   - * 获得商品sku列表
  32 + * 获得商品 SKU 列表
  33 + *
  34 + * @return 商品sku列表
  35 + */
  36 + List<ProductSkuDO> getSkuList();
  37 +
  38 + /**
  39 + * 获得商品 SKU 列表
33 40 *
34 41 * @param ids 编号
35 42 * @return 商品sku列表
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
... ... @@ -62,6 +62,11 @@ public class ProductSkuServiceImpl implements ProductSkuService {
62 62 }
63 63  
64 64 @Override
  65 + public List<ProductSkuDO> getSkuList() {
  66 + return productSkuMapper.selectList();
  67 + }
  68 +
  69 + @Override
65 70 public List<ProductSkuDO> getSkuList(Collection<Long> ids) {
66 71 return productSkuMapper.selectBatchIds(ids);
67 72 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
... ... @@ -9,6 +9,9 @@ import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
9 9 import javax.validation.Valid;
10 10 import java.util.Collection;
11 11 import java.util.List;
  12 +import java.util.Map;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
12 15  
13 16 /**
14 17 * 商品 SPU Service 接口
... ... @@ -64,6 +67,16 @@ public interface ProductSpuService {
64 67 List<ProductSpuDO> getSpuList(Collection<Long> ids);
65 68  
66 69 /**
  70 + * 获得商品 SPU 映射
  71 + *
  72 + * @param ids 编号数组
  73 + * @return 商品 SPU 映射
  74 + */
  75 + default Map<Long, ProductSpuDO> getSpuMap(Collection<Long> ids) {
  76 + return convertMap(getSpuList(ids), ProductSpuDO::getId);
  77 + }
  78 +
  79 + /**
67 80 * 获得所有商品 SPU 列表
68 81 *
69 82 * @return 商品 SPU 列表
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java
... ... @@ -130,11 +130,11 @@ public class CouponTemplateBaseVO {
130 130 || fixedEndTerm != null;
131 131 }
132 132  
133   - @AssertTrue(message = "折扣百分比需要大于等于 1")
  133 + @AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99")
134 134 @JsonIgnore
135 135 public boolean isDiscountPercentValid() {
136 136 return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType())
137   - || (discountPercent != null && discountPercent >= 1);
  137 + || (discountPercent != null && discountPercent >= 1 && discountPercent<= 99);
138 138 }
139 139  
140 140 @AssertTrue(message = "优惠金额不能为空")
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java
1 1 package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
2 2  
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
  6 +import com.fasterxml.jackson.annotation.JsonIgnore;
3 7 import io.swagger.annotations.ApiModel;
4 8 import io.swagger.annotations.ApiModelProperty;
5 9 import lombok.Data;
6 10 import org.springframework.format.annotation.DateTimeFormat;
7 11  
  12 +import javax.validation.constraints.AssertTrue;
8 13 import javax.validation.constraints.Min;
9 14 import javax.validation.constraints.NotNull;
10 15 import java.util.Date;
... ... @@ -47,10 +52,31 @@ public class DiscountActivityBaseVO {
47 52 @NotNull(message = "商品 SKU 编号不能为空")
48 53 private Long skuId;
49 54  
50   - @ApiModelProperty(value = "折扣价格,单位:分", required = true, example = "1000")
51   - @NotNull(message = "折扣价格不能为空")
52   - @Min(value = 1, message = "折扣价格必须大于 0")
  55 + @ApiModelProperty(value = "优惠类型", required = true, example = "1", notes = "参见 PromotionDiscountTypeEnum 枚举")
  56 + @NotNull(message = "优惠类型不能为空")
  57 + @InEnum(PromotionDiscountTypeEnum.class)
  58 + private Integer discountType;
  59 +
  60 + @ApiModelProperty(value = "折扣百分比", example = "80", notes = "例如说,80% 为 80")
  61 + private Integer discountPercent;
  62 +
  63 + @ApiModelProperty(value = "优惠金额", example = "10", notes = "单位:分")
  64 + @Min(value = 0, message = "优惠金额需要大于等于 0")
53 65 private Integer discountPrice;
54 66  
  67 + @AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99")
  68 + @JsonIgnore
  69 + public boolean isDiscountPercentValid() {
  70 + return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType())
  71 + || (discountPercent != null && discountPercent >= 1 && discountPercent<= 99);
  72 + }
  73 +
  74 + @AssertTrue(message = "优惠金额不能为空")
  75 + @JsonIgnore
  76 + public boolean isDiscountPriceValid() {
  77 + return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PRICE.getType())
  78 + || discountPrice != null;
  79 + }
  80 +
55 81 }
56 82 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java
... ... @@ -5,7 +5,8 @@ import lombok.Data;
5 5 import lombok.EqualsAndHashCode;
6 6 import lombok.ToString;
7 7  
8   -import javax.validation.constraints.NotNull;
  8 +import javax.validation.Valid;
  9 +import javax.validation.constraints.NotEmpty;
9 10 import java.util.List;
10 11  
11 12 @ApiModel("管理后台 - 限时折扣活动创建 Request VO")
... ... @@ -17,7 +18,8 @@ public class DiscountActivityCreateReqVO extends DiscountActivityBaseVO {
17 18 /**
18 19 * 商品列表
19 20 */
20   - @NotNull(message = "商品列表不能为空")
  21 + @NotEmpty(message = "商品列表不能为空")
  22 + @Valid
21 23 private List<Product> products;
22 24  
23 25 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java
... ... @@ -6,6 +6,8 @@ import lombok.Data;
6 6 import lombok.EqualsAndHashCode;
7 7 import lombok.ToString;
8 8  
  9 +import javax.validation.Valid;
  10 +import javax.validation.constraints.NotEmpty;
9 11 import javax.validation.constraints.NotNull;
10 12 import java.util.List;
11 13  
... ... @@ -22,7 +24,8 @@ public class DiscountActivityUpdateReqVO extends DiscountActivityBaseVO {
22 24 /**
23 25 * 商品列表
24 26 */
25   - @NotNull(message = "商品列表不能为空")
  27 + @NotEmpty(message = "商品列表不能为空")
  28 + @Valid
26 29 private List<DiscountActivityCreateReqVO.Product> products;
27 30  
28 31 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java
1 1 package cn.iocoder.yudao.module.promotion.dal.dataobject.discount;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
4 5 import com.baomidou.mybatisplus.annotation.KeySequence;
5 6 import com.baomidou.mybatisplus.annotation.TableId;
6 7 import com.baomidou.mybatisplus.annotation.TableName;
... ... @@ -41,8 +42,23 @@ public class DiscountProductDO extends BaseDO {
41 42 * 关联 ProductSkuDO 的 id 编号
42 43 */
43 44 private Long skuId;
  45 +
  46 + /**
  47 + * 折扣类型
  48 + *
  49 + * 枚举 {@link PromotionDiscountTypeEnum}
  50 + */
  51 + private Integer discountType;
44 52 /**
45   - * 优惠价格,单位:分
  53 + * 折扣百分比
  54 + *
  55 + * 例如,80% 为 80
  56 + */
  57 + private Integer discountPercent;
  58 + /**
  59 + * 优惠金额,单位:分
  60 + *
  61 + * 当 {@link #discountType} 为 {@link PromotionDiscountTypeEnum#PRICE} 生效
46 62 */
47 63 private Integer discountPrice;
48 64  
... ...
yudao-ui-admin/src/api/mall/product/sku.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获得商品 SKU 选项的列表
  4 +export function getSkuOptionList() {
  5 + return request({
  6 + url: '/product/sku/get-option-list',
  7 + method: 'get',
  8 + })
  9 +}
... ...
yudao-ui-admin/src/api/mall/product/spu.js
1 1 import request from '@/utils/request'
2 2  
3   -// 创建商品spu
  3 +// 创建商品 SPU
4 4 export function createSpu(data) {
5 5 return request({
6 6 url: '/product/spu/create',
... ... @@ -9,7 +9,7 @@ export function createSpu(data) {
9 9 })
10 10 }
11 11  
12   -// 更新商品spu
  12 +// 更新商品 SPU
13 13 export function updateSpu(data) {
14 14 return request({
15 15 url: '/product/spu/update',
... ... @@ -18,7 +18,7 @@ export function updateSpu(data) {
18 18 })
19 19 }
20 20  
21   -// 删除商品spu
  21 +// 删除商品 SPU
22 22 export function deleteSpu(id) {
23 23 return request({
24 24 url: '/product/spu/delete?id=' + id,
... ... @@ -34,7 +34,7 @@ export function getSpu(id) {
34 34 })
35 35 }
36 36  
37   -// 获得商品spu详情
  37 +// 获得商品 SPU 详情
38 38 export function getSpuDetail(id) {
39 39 return request({
40 40 url: '/product/spu/get/detail?id=' + id,
... ... @@ -42,7 +42,7 @@ export function getSpuDetail(id) {
42 42 })
43 43 }
44 44  
45   -// 获得商品spu分页
  45 +// 获得商品 SPU 分页
46 46 export function getSpuPage(query) {
47 47 return request({
48 48 url: '/product/spu/page',
... ...
yudao-ui-admin/src/views/mall/promotion/discountActivity/index.vue
... ... @@ -70,7 +70,7 @@
70 70 @pagination="getList"/>
71 71  
72 72 <!-- 对话框(添加 / 修改) -->
73   - <el-dialog :title="title" :visible.sync="open" width="600px" v-dialogDrag append-to-body>
  73 + <el-dialog :title="title" :visible.sync="open" width="1000px" v-dialogDrag append-to-body>
74 74 <el-form ref="form" :model="form" :rules="rules" label-width="80px">
75 75 <el-form-item label="活动名称" prop="name">
76 76 <el-input v-model="form.name" placeholder="请输入活动名称" />
... ... @@ -80,7 +80,54 @@
80 80 </el-form-item>
81 81 <el-form-item label="活动时间" prop="startAndEndTime">
82 82 <el-date-picker clearable v-model="form.startAndEndTime" type="datetimerange" :default-time="['00:00:00', '23:59:59']"
83   - value-format="timestamp" placeholder="选择开始时间" style="width: 480px" />
  83 + value-format="timestamp" placeholder="选择开始时间" style="width: 880px" />
  84 + </el-form-item>
  85 + <el-form-item label="商品选择">
  86 + <el-select v-model="form.skuIds" placeholder="请选择活动商品" clearable size="small"
  87 + multiple filterable style="width: 400px" @change="changeFormSku">
  88 + <el-option v-for="item in productSkus" :key="item.id" :label="item.name" :value="item.id">
  89 + <span style="float: left">{{ item.spuName }} &nbsp; {{ item.name}}</span>
  90 + <span style="float: right; color: #8492a6; font-size: 13px">¥{{ (item.price / 100.0).toFixed(2) }}</span>
  91 + </el-option>
  92 + </el-select>
  93 + <el-table v-loading="loading" :data="form.products">
  94 + <el-table-column label="商品名称" align="center" width="200">
  95 + <template slot-scope="scope">
  96 + {{ scope.row.spuName }} &nbsp; {{ scope.row.name}}
  97 + </template>
  98 + </el-table-column>
  99 + <el-table-column label="商品价格" align="center" prop="price">
  100 + <template slot-scope="scope">
  101 + ¥{{ (scope.row.price / 100.0).toFixed(2) }}
  102 + </template>
  103 + </el-table-column>
  104 + <el-table-column label="库存" align="center" prop="stock" />
  105 + <el-table-column label="优惠类型" align="center">
  106 + <template slot-scope="scope">
  107 + <el-select v-model="scope.row.discountType" placeholder="请选择优惠类型">
  108 + <el-option v-for="dict in getDictDatas(DICT_TYPE.PROMOTION_DISCOUNT_TYPE)"
  109 + :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"/>
  110 + </el-select>
  111 + </template>
  112 + </el-table-column>
  113 + <el-table-column label="优惠" align="center" prop="startTime" width="250">
  114 + <template slot-scope="scope">
  115 + <el-form-item v-if="scope.row.discountType === PromotionDiscountTypeEnum.PRICE.type" prop="discountPrice">
  116 + 减 <el-input-number v-model="scope.row.discountPrice" placeholder="请输入优惠金额"
  117 + style="width: 190px" :precision="2" :min="0" /> 元
  118 + </el-form-item>
  119 + <el-form-item v-if="scope.row.discountType === PromotionDiscountTypeEnum.PERCENT.type" prop="discountPercent">
  120 + 打 <el-input-number v-model="scope.row.discountPercent" placeholder="请输入优惠折扣"
  121 + style="width: 190px" :precision="1" :min="1" :max="9.9" /> 折
  122 + </el-form-item>
  123 + </template>
  124 + </el-table-column>
  125 + <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  126 + <template slot-scope="scope">
  127 + <el-button size="mini" type="text" icon="el-icon-delete" @click="removeFormSku(scope.row.skuId)">删除</el-button>
  128 + </template>
  129 + </el-table-column>
  130 + </el-table>
84 131 </el-form-item>
85 132 </el-form>
86 133 <div slot="footer" class="dialog-footer">
... ... @@ -93,8 +140,11 @@
93 140  
94 141 <script>
95 142 import { createDiscountActivity, updateDiscountActivity, deleteDiscountActivity, getDiscountActivity, getDiscountActivityPage } from "@/api/mall/promotion/discountActivity";
96   -import {PromotionActivityStatusEnum, PromotionProductScopeEnum} from "@/utils/constants";
97   -import {closeRewardActivity} from "@/api/mall/promotion/rewardActivity";
  143 +import {
  144 + PromotionActivityStatusEnum, PromotionDiscountTypeEnum,
  145 + PromotionProductScopeEnum
  146 +} from "@/utils/constants";
  147 +import { getSkuOptionList } from "@/api/mall/product/sku";
98 148  
99 149 export default {
100 150 name: "DiscountActivity",
... ... @@ -115,7 +165,7 @@ export default {
115 165 // 弹出层名称
116 166 title: "",
117 167 // 是否显示弹出层
118   - open: false,
  168 + open: true,
119 169 // 查询参数
120 170 queryParams: {
121 171 pageNo: 1,
... ... @@ -125,17 +175,38 @@ export default {
125 175 createTime: [],
126 176 },
127 177 // 表单参数
128   - form: {},
  178 + form: {
  179 + skuIds: [], // 选中的 SKU
  180 + products: [], // 商品信息
  181 + // products: [{
  182 + // id: 2,
  183 + // name: '白色',
  184 + // price: 500,
  185 + // stock: 20,
  186 + // spuId: 1,
  187 + // spuName: 'iPhone 14 Pro',
  188 + // discountType: 1,
  189 + // }, {
  190 + // id: 10,
  191 + // name: '蓝色',
  192 + // price: 1000,
  193 + // stock: 100,
  194 + // spuId: 20,
  195 + // spuName: 'iPhone 14 Pro',
  196 + // discountType: 2,
  197 + // }]
  198 + },
129 199 // 表单校验
130 200 rules: {
131 201 name: [{ required: true, message: "活动名称不能为空", trigger: "blur" }],
132 202 startAndEndTime: [{ required: true, message: "活动时间不能为空", trigger: "blur" }],
133 203 },
134   - // 商品列表
135   - productSpus: [], // TODO 芋艿:需要重新写下
  204 + // 商品 SKU 列表
  205 + productSkus: [],
136 206 // 如下的变量,主要为了 v-if 判断可以使用到
137 207 PromotionProductScopeEnum: PromotionProductScopeEnum,
138 208 PromotionActivityStatusEnum: PromotionActivityStatusEnum,
  209 + PromotionDiscountTypeEnum: PromotionDiscountTypeEnum,
139 210 };
140 211 },
141 212 created() {
... ... @@ -151,6 +222,10 @@ export default {
151 222 this.total = response.data.total;
152 223 this.loading = false;
153 224 });
  225 + // 获得 SKU 商品列表
  226 + getSkuOptionList().then(response => {
  227 + this.productSkus = response.data;
  228 + });
154 229 },
155 230 /** 取消按钮 */
156 231 cancel() {
... ... @@ -166,6 +241,8 @@ export default {
166 241 startTime: undefined,
167 242 endTime: undefined,
168 243 remark: undefined,
  244 + skuIds: [],
  245 + products: [],
169 246 };
170 247 this.resetForm("form");
171 248 },
... ... @@ -240,7 +317,49 @@ export default {
240 317 this.getList();
241 318 this.$modal.msgSuccess("关闭成功");
242 319 }).catch(() => {});
243   - }
  320 + },
  321 + /** 当 Form 的 SKU 发生变化时 */
  322 + changeFormSku(skuIds) {
  323 + // 处理【新增】
  324 + skuIds.forEach(skuId => {
  325 + // 获得对应的 SKU 信息
  326 + const sku = this.productSkus.find(item => item.id === skuId);
  327 + if (!sku) {
  328 + // debugger
  329 + return;
  330 + }
  331 + // 判断已存在,直接跳过
  332 + const product = this.form.products.find(item => item.skuId === skuId);
  333 + if (product) {
  334 + // debugger
  335 + return;
  336 + }
  337 + this.form.products.push({
  338 + skuId: sku.id,
  339 + name: sku.name,
  340 + price: sku.price,
  341 + stock: sku.stock,
  342 + spuId: sku.spuId,
  343 + spuName: sku.spuName,
  344 + discountType: PromotionDiscountTypeEnum.PRICE.type,
  345 + });
  346 + });
  347 + // 处理【移除】
  348 + this.form.products.map((product, index) => {
  349 + if (!skuIds.includes(product.skuId)) {
  350 + this.form.products.splice(index, 1);
  351 + }
  352 + });
  353 + },
  354 + /** 移除 Form 的 SKU */
  355 + removeFormSku(skuId) {
  356 + this.form.skuIds.map((id, index) => {
  357 + if (skuId === id) {
  358 + this.form.skuIds.splice(index, 1);
  359 + }
  360 + });
  361 + this.changeFormSku(this.form.skuIds);
  362 + },
244 363 }
245   -};
  364 +}
246 365 </script>
... ...