Commit dc51a9353394e411006548468ff36aac0ae1cba8

Authored by YunaiV
1 parent 3c10058d

promotion:实现部分优惠劵模板的前端列表

yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionDiscountTypeEnum.java
... ... @@ -15,8 +15,8 @@ import java.util.Arrays;
15 15 @AllArgsConstructor
16 16 public enum PromotionDiscountTypeEnum implements IntArrayValuable {
17 17  
18   - PRICE(1, "减价"), // 具体金额
19   - PERCENT(2, "打折"), // 百分比
  18 + PRICE(1, "满减"), // 具体金额
  19 + PERCENT(2, "折扣"), // 百分比
20 20 ;
21 21  
22 22 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionDiscountTypeEnum::getType).toArray();
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/CouponTemplateRespVO.java
... ... @@ -24,7 +24,7 @@ public class CouponTemplateRespVO extends CouponTemplateBaseVO {
24 24 private Integer status;
25 25  
26 26 @ApiModelProperty(value = "领取优惠券的数量", required = true, example = "1024")
27   - private Integer takeNum;
  27 + private Integer takeCount;
28 28  
29 29 @ApiModelProperty(value = "使用优惠券的次数", required = true, example = "2048")
30 30 private Integer useCount;
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java
... ... @@ -106,6 +106,12 @@ public class CouponTemplateDO extends BaseDO {
106 106 */
107 107 private Date validEndTime;
108 108 /**
  109 + * 领取日期 - 开始天数
  110 + *
  111 + * 当 {@link #validityType} 为 {@link CouponTemplateValidityTypeEnum#TERM}
  112 + */
  113 + private Integer fixedStartTerm;
  114 + /**
109 115 * 领取日期 - 结束天数
110 116 *
111 117 * 当 {@link #validityType} 为 {@link CouponTemplateValidityTypeEnum#TERM}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImplTest.java
1 1 package cn.iocoder.yudao.module.promotion.service.coupon;
2 2  
3   -import org.junit.jupiter.api.Disabled;
4   -import org.junit.jupiter.api.Test;
5   -import org.springframework.boot.test.mock.mockito.MockBean;
6   -
7   -import javax.annotation.Resource;
8   -
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
9 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
10   -
11   -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.*;
  5 +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateCreateReqVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplatePageReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateUpdateReqVO;
12 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
13 9 import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper;
14   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
  10 +import org.junit.jupiter.api.Disabled;
  11 +import org.junit.jupiter.api.Test;
  12 +import org.springframework.context.annotation.Import;
15 13  
16 14 import javax.annotation.Resource;
17   -import org.springframework.context.annotation.Import;
18   -import java.util.*;
19   -
20   -import static cn.hutool.core.util.RandomUtil.*;
21   -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
22   -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
23   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
24   -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
25   -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
  15 +import java.util.Date;
  16 +
  17 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  18 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  19 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  20 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  21 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  22 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS;
26 23 import static org.junit.jupiter.api.Assertions.*;
27   -import static org.mockito.Mockito.*;
28 24  
29 25 /**
30 26 * {@link CouponTemplateServiceImpl} 的单元测试类
... ... @@ -110,7 +106,7 @@ public class CouponTemplateServiceImplTest extends BaseDbUnitTest {
110 106 CouponTemplateDO dbCouponTemplate = randomPojo(CouponTemplateDO.class, o -> { // 等会查询到
111 107 o.setName(null);
112 108 o.setStatus(null);
113   - o.setType(null);
  109 + o.setDiscountType(null);
114 110 o.setCreateTime(null);
115 111 });
116 112 couponTemplateMapper.insert(dbCouponTemplate);
... ... @@ -119,14 +115,14 @@ public class CouponTemplateServiceImplTest extends BaseDbUnitTest {
119 115 // 测试 status 不匹配
120 116 couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setStatus(null)));
121 117 // 测试 type 不匹配
122   - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setType(null)));
  118 + couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setDiscountType(null)));
123 119 // 测试 createTime 不匹配
124 120 couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setCreateTime(null)));
125 121 // 准备参数
126 122 CouponTemplatePageReqVO reqVO = new CouponTemplatePageReqVO();
127 123 reqVO.setName(null);
128 124 reqVO.setStatus(null);
129   - reqVO.setType(null);
  125 + reqVO.setDiscountType(null);
130 126 reqVO.setCreateTime((new Date[]{}));
131 127  
132 128 // 调用
... ... @@ -137,37 +133,4 @@ public class CouponTemplateServiceImplTest extends BaseDbUnitTest {
137 133 assertPojoEquals(dbCouponTemplate, pageResult.getList().get(0));
138 134 }
139 135  
140   - @Test
141   - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
142   - public void testGetCouponTemplateList() {
143   - // mock 数据
144   - CouponTemplateDO dbCouponTemplate = randomPojo(CouponTemplateDO.class, o -> { // 等会查询到
145   - o.setName(null);
146   - o.setStatus(null);
147   - o.setType(null);
148   - o.setCreateTime(null);
149   - });
150   - couponTemplateMapper.insert(dbCouponTemplate);
151   - // 测试 name 不匹配
152   - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setName(null)));
153   - // 测试 status 不匹配
154   - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setStatus(null)));
155   - // 测试 type 不匹配
156   - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setType(null)));
157   - // 测试 createTime 不匹配
158   - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setCreateTime(null)));
159   - // 准备参数
160   - CouponTemplateExportReqVO reqVO = new CouponTemplateExportReqVO();
161   - reqVO.setName(null);
162   - reqVO.setStatus(null);
163   - reqVO.setType(null);
164   - reqVO.setCreateTime((new Date[]{}));
165   -
166   - // 调用
167   - List<CouponTemplateDO> list = couponTemplateService.getCouponTemplateList(reqVO);
168   - // 断言
169   - assertEquals(1, list.size());
170   - assertPojoEquals(dbCouponTemplate, list.get(0));
171   - }
172   -
173 136 }
... ...
yudao-ui-admin/src/utils/constants.js
... ... @@ -236,3 +236,31 @@ export const ProductSpuStatusEnum = {
236 236 name: '上架'
237 237 },
238 238 }
  239 +
  240 +/**
  241 + * 优惠类型枚举
  242 + */
  243 +export const PromotionDiscountTypeEnum = {
  244 + PRICE: {
  245 + type: 1,
  246 + name: '满减'
  247 + },
  248 + PERCENT: {
  249 + type: 2,
  250 + name: '折扣'
  251 + }
  252 +}
  253 +
  254 +/**
  255 + * 优惠劵模板的有限期类型的枚举
  256 + */
  257 +export const CouponTemplateValidityTypeEnum = {
  258 + DATE: {
  259 + type: 1,
  260 + name: '固定日期可用'
  261 + },
  262 + TERM: {
  263 + type: 2,
  264 + name: '领取之后可用'
  265 + }
  266 +}
... ...
yudao-ui-admin/src/utils/dict.js
... ... @@ -59,6 +59,9 @@ export const DICT_TYPE = {
59 59  
60 60 // ========== MALL - PRODUCT 模块 ==========
61 61 PRODUCT_SPU_STATUS: 'product_spu_status', // 商品 SPU 状态
  62 +
  63 + // ========== MALL - PROMOTION 模块 ==========
  64 + PROMOTION_DISCOUNT_TYPE: 'promotion_discount_type', // 优惠类型
62 65 }
63 66  
64 67 /**
... ...
yudao-ui-admin/src/views/promotion/couponTemplate/index.vue
... ... @@ -2,25 +2,19 @@
2 2 <div class="app-container">
3 3  
4 4 <!-- 搜索工作栏 -->
5   - <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
6   - <el-form-item label="优惠劵名" prop="name">
  5 + <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="82px">
  6 + <el-form-item label="优惠券名称" prop="name">
7 7 <el-input v-model="queryParams.name" placeholder="请输入优惠劵名" clearable @keyup.enter.native="handleQuery"/>
8 8 </el-form-item>
9   - <el-form-item label="状态" prop="status">
10   - <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
11   - <el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
12   - :key="dict.value" :label="dict.label" :value="dict.value"/>
  9 + <el-form-item label="优惠券类型" prop="discountType">
  10 + <el-select v-model="queryParams.discountType" placeholder="请选择优惠券类型" clearable size="small">
  11 + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.PROMOTION_DISCOUNT_TYPE)"
  12 + :key="dict.value" :label="dict.label" :value="dict.value"/>
13 13 </el-select>
14 14 </el-form-item>
15   - <el-form-item label="类型
16   - *
17   - * 1-优惠劵
18   - * 2-优惠码" prop="type">
19   - <el-select v-model="queryParams.type" placeholder="请选择类型
20   - *
21   - * 1-优惠劵
22   - * 2-优惠码" clearable size="small">
23   - <el-option v-for="dict in this.getDictDatas(DICT_TYPE.PRODUCT_SPU_STATUS)"
  15 + <el-form-item label="优惠券状态" prop="status">
  16 + <el-select v-model="queryParams.status" placeholder="请选择优惠券状态" clearable size="small">
  17 + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
24 18 :key="dict.value" :label="dict.label" :value="dict.value"/>
25 19 </el-select>
26 20 </el-form-item>
... ... @@ -48,45 +42,24 @@
48 42 <el-table-column label="优惠券名称" align="center" prop="name" />
49 43 <el-table-column label="优惠券类型" align="center" prop="discountType">
50 44 <template slot-scope="scope">
51   - <dict-tag :type="DICT_TYPE.PRODUCT_SPU_STATUS" :value="scope.row.type" />
  45 + <dict-tag :type="DICT_TYPE.PROMOTION_DISCOUNT_TYPE" :value="scope.row.discountType" />
52 46 </template>
53 47 </el-table-column>
54   - <el-table-column label="发行总量" align="center" prop="totalCount" />
55   - <el-table-column label="每人限领个数
56   - *
57   - * null - 则表示不限制" align="center" prop="takeLimitCount" />
58   - <el-table-column label="领取方式" align="center" prop="takeType" />
59   - <el-table-column label="是否设置满多少金额可用,单位:分" align="center" prop="usePrice" />
60   - <el-table-column label="商品范围" align="center" prop="productScope" />
61   - <el-table-column label="商品 SPU 编号的数组" align="center" prop="productSpuIds" />
62   - <el-table-column label="生效日期类型" align="center" prop="validityType" />
63   - <el-table-column label="固定日期-生效开始时间" align="center" prop="validStartTime" width="180">
  48 + <el-table-column label="优惠金额 / 折扣" align="center" prop="discount" :formatter="discountFormat" />
  49 + <el-table-column label="发放数量" align="center" prop="totalCount" />
  50 + <el-table-column label="剩余数量" align="center" prop="totalCount" :formatter="row => (row.totalCount - row.takeCount)" />
  51 + <el-table-column label="领取上限" align="center" prop="takeLimitCount" :formatter="takeLimitCountFormat" />
  52 + <el-table-column label="有效期限" align="center" prop="validityType" width="180" :formatter="validityTypeFormat" />
  53 + <el-table-column label="状态" align="center" prop="status">
64 54 <template slot-scope="scope">
65   - <span>{{ parseTime(scope.row.validStartTime) }}</span>
66   - </template>
67   - </el-table-column>
68   - <el-table-column label="固定日期-生效结束时间" align="center" prop="validEndTime" width="180">
69   - <template slot-scope="scope">
70   - <span>{{ parseTime(scope.row.validEndTime) }}</span>
  55 + <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
71 56 </template>
72 57 </el-table-column>
73   - <el-table-column label="领取日期-开始天数" align="center" prop="fixedStartTerm" />
74   - <el-table-column label="领取日期-结束天数" align="center" prop="fixedEndTerm" />
75   - <el-table-column label="折扣百分比" align="center" prop="discountPercent" />
76   - <el-table-column label="优惠金额,单位:分" align="center" prop="discountPrice" />
77   - <el-table-column label="折扣上限" />
78   - <el-table-column label="领取优惠券的数量" align="center" prop="takeNum" />
79   - <el-table-column label="使用优惠券的次数" align="center" prop="useCount" />
80 58 <el-table-column label="创建时间" align="center" prop="createTime" width="180">
81 59 <template slot-scope="scope">
82 60 <span>{{ parseTime(scope.row.createTime) }}</span>
83 61 </template>
84 62 </el-table-column>
85   - <el-table-column label="优惠券类型" align="center" prop="status">
86   - <template slot-scope="scope">
87   - <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
88   - </template>
89   - </el-table-column>
90 63 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
91 64 <template slot-scope="scope">
92 65 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
... ... @@ -185,7 +158,8 @@
185 158 </template>
186 159  
187 160 <script>
188   -import { createCouponTemplate, updateCouponTemplate, deleteCouponTemplate, getCouponTemplate, getCouponTemplatePage, exportCouponTemplateExcel } from "@/api/promotion/couponTemplate";
  161 +import { createCouponTemplate, updateCouponTemplate, deleteCouponTemplate, getCouponTemplate, getCouponTemplatePage } from "@/api/promotion/couponTemplate";
  162 +import {CouponTemplateValidityTypeEnum, PromotionDiscountTypeEnum} from "@/utils/constants";
189 163  
190 164 export default {
191 165 name: "CouponTemplate",
... ... @@ -340,6 +314,33 @@ export default {
340 314 this.$modal.msgSuccess("删除成功");
341 315 }).catch(() => {});
342 316 },
  317 + // 格式化【优惠金额/折扣】
  318 + discountFormat(row, column) {
  319 + if (row.discountType === PromotionDiscountTypeEnum.PRICE.type) {
  320 + return `¥${(row.discountPrice / 100.0).toFixed(2)}`;
  321 + }
  322 + if (row.discountType === PromotionDiscountTypeEnum.PERCENT.type) {
  323 + return `¥${(row.discountPrice / 100.0).toFixed(2)}`;
  324 + }
  325 + return '未知【' + row.discountType + '】';
  326 + },
  327 + // 格式化【领取上限】
  328 + takeLimitCountFormat(row, column) {
  329 + if (row.takeLimitCount === -1) {
  330 + return '无领取限制';
  331 + }
  332 + return `${row.takeLimitCount} 张/人`
  333 + },
  334 + // 格式化【有效期限】
  335 + validityTypeFormat(row, column) {
  336 + if (row.validityType === CouponTemplateValidityTypeEnum.DATE.type) {
  337 + return `${parseTime(row.validStartTime)} 至 ${parseTime(row.validEndTime)}`
  338 + }
  339 + if (row.validityType === CouponTemplateValidityTypeEnum.TERM.type) {
  340 + return `领取后第 ${row.fixedStartTerm} - ${row.fixedEndTerm} 天内可用`
  341 + }
  342 + return '未知【' + row.validityType + '】';
  343 + }
343 344 }
344 345 };
345 346 </script>
... ...