Browse Source

Merge branch 'dev_v1.3.4_20220902'

liujunchi 3 years ago
parent
commit
b90f6b62ec
35 changed files with 2488 additions and 5 deletions
  1. 1 1
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/AdminApplication.java
  2. 152 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/coupon/CouponInfoController.java
  3. 78 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/coupon/CouponIssueController.java
  4. 371 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/coupon/CouponInfoVO.java
  5. 343 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/coupon/CouponIssueVo.java
  6. 37 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/UserParam.java
  7. 109 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CouponInfo.java
  8. 93 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CouponIssue.java
  9. 127 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysUser.java
  10. 35 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/SendTypeEnum.java
  11. 40 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/coupon/CouponCategoryEnum.java
  12. 33 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/coupon/CouponTypeEnum.java
  13. 34 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/coupon/CouponUseStateEnum.java
  14. 41 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/CouponInfoMapper.java
  15. 21 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/CouponIssueMapper.java
  16. 18 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/SysUserMapper.java
  17. 54 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/queryInfo/CouponInfoQuery.java
  18. 126 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/queryInfo/CouponIssueQueryInfo.java
  19. 40 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CouponInfoService.java
  20. 34 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CouponIssueService.java
  21. 136 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CouponInfoServiceImp.java
  22. 50 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CouponIssueServiceImp.java
  23. 49 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/coupon/CouponInfoWrapper.java
  24. 24 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/StatGroupWrapper.java
  25. 69 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CouponInfoMapper.xml
  26. 85 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CouponIssueMapper.xml
  27. 38 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysUserMapper.xml
  28. 1 1
      cooleshow-user/user-classroom/src/main/java/com/yonge/cooleshow/classroom/ClassroomApplication.java
  29. 1 1
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/StudentApplication.java
  30. 34 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/coupon/CouponInfoController.java
  31. 89 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/io/request/CouponInfoVO.java
  32. 1 1
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/TeacherApplication.java
  33. 34 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/coupon/CouponInfoController.java
  34. 89 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/io/request/CouponInfoVO.java
  35. 1 1
      cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/WebsiteApplication.java

+ 1 - 1
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/AdminApplication.java

@@ -16,7 +16,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @SpringBootApplication
 @EnableDiscoveryClient
 @EnableFeignClients("com.yonge.cooleshow")
-@MapperScan(basePackages = {"com.yonge.cooleshow.biz.dal.dao", "com.yonge.toolset.payment.core.dao"})
+@MapperScan(basePackages = {"com.yonge.cooleshow.biz.dal.dao", "com.yonge.cooleshow.biz.dal.mapper", "com.yonge.toolset.payment.core.dao"})
 @ComponentScan(basePackages = {"com.yonge.cooleshow", "com.yonge.toolset"})
 @Configuration
 @EnableSwagger2Doc

+ 152 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/coupon/CouponInfoController.java

@@ -0,0 +1,152 @@
+package com.yonge.cooleshow.admin.controller.coupon;
+
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.admin.io.request.coupon.CouponInfoVO;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.CouponInfo;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
+import com.yonge.cooleshow.biz.dal.service.CouponInfoService;
+import com.yonge.cooleshow.biz.dal.vo.coupon.CouponInfoWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * <p>
+ * 优惠券信息 前端控制器
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@RestController
+@RequestMapping("/couponInfo")
+@Api(value = "优惠券信息", tags = "优惠券信息")
+public class CouponInfoController extends BaseController {
+
+    @Autowired
+    private CouponInfoService couponInfoService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 优惠券信息
+     * @param request CouponInfoVO.RequestInfo
+     * @return HttpResponseResult<PageInfo<CouponInfoVO.ResponseInfo>>
+     */
+    @PostMapping(value = "/page", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "查询优惠券分页", notes = "传入CouponInfoVO.PageRequest")
+    public HttpResponseResult<PageInfo<CouponInfoVO.CouponPageInfo>> queryCouponPageInfo(@RequestBody CouponInfoVO.PageRequest request) {
+
+        // 优惠券信息
+        IPage<CouponInfoWrapper> wrapper = couponInfoService.queryCouponPageInfo(PageUtil.getPage(request),
+                CouponInfoQuery.from(request.jsonString()));
+
+        // 数据转换
+        List<CouponInfoVO.CouponPageInfo> pageInfos = JSON.parseArray(JSON.toJSONString(wrapper.getRecords()),
+                CouponInfoVO.CouponPageInfo.class);
+
+        // 分页数据信息
+        return succeed(PageUtil.getPageInfo(wrapper, pageInfos));
+    }
+
+    /**
+     * 优惠券详情信息
+     * @param id 优惠券ID
+     * @return HttpResponseResult<CouponInfoVO.CouponQueryInfo>
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "优惠券详情", notes = "传入优惠券ID")
+    public HttpResponseResult<CouponInfoVO.CouponQueryInfo> findCouponById(@PathVariable("id") Long id) {
+
+        if (Objects.isNull(id)) {
+            return failed("无效的优惠券ID");
+        }
+
+        // 优惠券信息
+        CouponInfo couponInfo = couponInfoService.queryCouponInfoById(id);
+
+        return succeed(CouponInfoVO.CouponQueryInfo.from(JSON.toJSONString(couponInfo)));
+    }
+
+    /**
+     * 新增或者更新优惠券信息
+     * - ID为空新增;否则进行更新
+     * @param info CouponInfoVO.CouponInfo
+     * @return HttpResponseResult<CouponInfoVO.CouponInfo>
+     */
+    @PostMapping(value = "/save", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "新增或修改", notes = "CouponInfoVO.CouponInfo")
+    public HttpResponseResult<CouponInfoVO.CouponQueryInfo> saveOrUpdate(@Valid @RequestBody CouponInfoVO.CouponInfo info) {
+
+        // 获取当前登录用户信息
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(user) || Objects.isNull(user.getId())) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        // 校验参数合法性
+        if (info.invalidRequestParam(user.getId())) {
+            throw new BizException("无效的请求参数");
+        }
+
+        // 新增或更新信息
+        CouponInfo couponInfo = couponInfoService.saveOrUpdateCouponInfo(JSON.parseObject(info.jsonString(), CouponInfo.class));
+
+        return succeed(CouponInfoVO.CouponQueryInfo.from(JSON.toJSONString(couponInfo)));
+    }
+
+    /**
+     * 启用/停用 优惠券
+     */
+    @GetMapping("/updateState")
+    @ApiOperation(value = "优惠券状态启/停用")
+    public HttpResponseResult<Boolean> updateCouponStateInfo(
+            @ApiParam(value = "优惠券ID", required = true) @RequestParam("couponId") Long couponId,
+            @ApiParam(value = "状态 0 停用 1 启用", required = true) @RequestParam("state") Integer state) {
+
+        // 获取当前登录用户信息
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(user) || Objects.isNull(user.getId())) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        // 更新数据信息
+        CouponInfoVO.CouponInfo info = CouponInfoVO.CouponInfo.builder()
+                .id(couponId)
+                .status(state)
+                .updatedBy(user.getId())
+                .updateTime(DateTime.now().getMillis())
+                .build();
+
+        CouponInfo couponInfo = couponInfoService.saveOrUpdateCouponInfo(JSON.parseObject(info.jsonString(), CouponInfo.class));
+
+        // 校验状态更新结果
+        return status(couponInfo.getStatus().intValue() == state);
+    }
+
+
+}

+ 78 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/coupon/CouponIssueController.java

@@ -0,0 +1,78 @@
+package com.yonge.cooleshow.admin.controller.coupon;
+
+
+import com.yonge.cooleshow.admin.io.request.coupon.CouponIssueVo;
+import com.yonge.cooleshow.biz.dal.entity.CouponIssue;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import com.yonge.cooleshow.biz.dal.service.CouponIssueService;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.time.Instant;
+
+/**
+ * <p>
+ * 优惠券发放 前端控制器
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@RestController
+@RequestMapping("/couponIssue")
+@Api(value = "优惠券发放信息", tags = "优惠券发放信息")
+public class CouponIssueController {
+
+    @Autowired
+    private CouponIssueService couponIssueService;
+
+    /**
+     * 优惠券发放分页信息
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询优惠券发放分页")
+    public HttpResponseResult<PageInfo<CouponIssueVo.CouponIssuePageInfo>> queryCouponIssuePageInfo(@RequestBody @Valid CouponIssueVo.PageRequest request) {
+
+        return null;
+    }
+
+
+    /**
+     * 优惠券课发放用户分页信息
+     */
+    @PostMapping("/userPage")
+    @ApiOperation(value = "优惠券发放用户分页信息")
+    public HttpResponseResult<PageInfo<CouponIssueVo.CouponIssueUserPageInfo>> queryCouponIssueUserPageInfo(@RequestBody @Valid CouponIssueVo.CouponIssueUserRequest request) {
+
+        return null;
+    }
+
+
+    @PostMapping("/issueUser")
+    @ApiOperation(value = "发送优惠券")
+    public HttpResponseResult<Boolean> issueCoupon(@RequestBody @Valid CouponIssueVo.CouponIssueUserParam param) {
+        couponIssueService.issueCoupon(param.getCouponId(),param.getUserParam());
+
+        return null;
+    }
+
+    @PostMapping("/withdraw/{couponIssueId}")
+    @ApiOperation(value = "撤回优惠券")
+    public HttpResponseResult<Boolean> withdrawCoupon(@PathVariable Long couponIssueId) {
+        CouponIssue couponIssue = couponIssueService.getById(couponIssueId);
+        if (couponIssue == null) {
+            return HttpResponseResult.failed("未找到数据");
+        }
+        if (couponIssue.getUseState().equals(CouponUseStateEnum.USED)) {
+            return HttpResponseResult.failed("优惠券已被使用");
+        }  else if(couponIssue.getEndTime().compareTo(Instant.now().getEpochSecond()) <0) {
+            return HttpResponseResult.failed("优惠券已过期");
+        }
+        return HttpResponseResult.status(couponIssueService.withdrawCoupon(couponIssueId));
+    }
+}

+ 371 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/coupon/CouponInfoVO.java

@@ -0,0 +1,371 @@
+package com.yonge.cooleshow.admin.io.request.coupon;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponTypeEnum;
+import com.yonge.cooleshow.common.enums.EStatus;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * 优惠券信息
+ * Created by Eric.Shang on 2022/9/2.
+ */
+public class CouponInfoVO {
+
+    /**
+     * 优惠券分页请求信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "优惠券信息分页请求", description = "优惠券信息分页")
+    public static class PageRequest extends QueryInfo {
+
+        @ApiModelProperty("优惠券名称")
+        private String name;
+
+        @ApiModelProperty("客户类型")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("优惠券类型")
+        private CouponTypeEnum couponType;
+
+        @ApiModelProperty("可用品类")
+        private CouponCategoryEnum category;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public String getName() {
+
+            if (StringUtils.isEmpty(this.name)) {
+                return null;
+            }
+            return name;
+        }
+    }
+
+    /**
+     * 优惠券分页响应数据
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "优惠券信息分页信息", description = "优惠券信息分页信息")
+    public static class CouponPageInfo implements Serializable {
+
+        @ApiModelProperty("优惠券ID")
+        private Long id;
+
+        @ApiModelProperty("优惠券名称")
+        private String name;
+
+        @ApiModelProperty("描述")
+        private String describe;
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private String clientType;
+
+        @ApiModelProperty("可用品类: UNIVERSAL(全场通用) VIP(小酷Ai) PIANO(云酷琴房) MALL(商场购物券) MUSIC(单曲点播券) SPARRING(陪练课购买券) LIVE(直播课购买券) VIDEO(视频课购买券) ")
+        private String category;
+
+        @ApiModelProperty("优惠券类型: FULL_DISCOUNT(满减券) VOUCHER(代金券) ")
+        private String couponType;
+
+        @ApiModelProperty("可以库存")
+        private Integer inventory;
+
+        @ApiModelProperty("领取次数限制")
+        private Integer quantityLimit;
+
+        @ApiModelProperty("状态")
+        private Integer status;
+
+        @ApiModelProperty("发放领取数")
+        private Integer issueNum;
+
+        @ApiModelProperty("关联奖品数")
+        private Integer rewardNum;
+
+        @ApiModelProperty("最后更新人")
+        private String updatedUser;
+
+        @ApiModelProperty("最后更新时间")
+        private Long updateTime;
+
+        @ApiModelProperty("创建时间")
+        private Date createdTime;
+    }
+
+    /**
+     * 优惠券详情信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class CouponQueryInfo implements Serializable {
+
+        @ApiModelProperty("优惠券ID")
+        private Long id;
+
+        @ApiModelProperty("优惠券名称")
+        private String name;
+
+        @ApiModelProperty("描述")
+        private String describe;
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("可用品类: UNIVERSAL(全场通用) VIP(小酷Ai) PIANO(云酷琴房) MALL(商场购物券) MUSIC(单曲点播券) SPARRING(陪练课购买券) LIVE(直播课购买券) VIDEO(视频课购买券) ")
+        private CouponCategoryEnum category;
+
+        @ApiModelProperty("使用门槛")
+        private BigDecimal useLimit;
+
+        @ApiModelProperty("优惠金额")
+        private BigDecimal discountPrice;
+
+        @ApiModelProperty("优惠券类型")
+        private CouponTypeEnum couponType;
+
+        @ApiModelProperty("有效天数")
+        private Integer validDay;
+
+        @ApiModelProperty("生效时间")
+        private Long startTime;
+
+        @ApiModelProperty("失效时间")
+        private Long endTime;
+
+        @ApiModelProperty("库存量")
+        private Integer inventory;
+
+        @ApiModelProperty("领取次数限制")
+        private Integer quantityLimit;
+
+        @ApiModelProperty("启禁状态")
+        private Integer status;
+
+        @ApiModelProperty("更新用户")
+        private Long updatedBy;
+
+        @ApiModelProperty("更新时间")
+        private Long updateTime;
+
+        @ApiModelProperty("创建用户")
+        private Long createdBy;
+
+        @ApiModelProperty("创建时间")
+        private Date createdTime;
+
+        public static CouponQueryInfo from(String recv) {
+            return JSON.parseObject(recv, CouponQueryInfo.class);
+        }
+    }
+
+    /**
+     * 新增或更新优惠券信息
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class CouponInfo implements Serializable {
+
+        @ApiModelProperty("优惠券ID")
+        private Long id;
+
+        @ApiModelProperty("优惠券名称")
+        private String name;
+
+        @ApiModelProperty("描述")
+        private String describe;
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("可用品类: UNIVERSAL(全场通用) VIP(小酷Ai) PIANO(云酷琴房) MALL(商场购物券) MUSIC(单曲点播券) SPARRING(陪练课购买券) LIVE(直播课购买券) VIDEO(视频课购买券) ")
+        private CouponCategoryEnum category;
+
+        @ApiModelProperty("使用门槛")
+        private BigDecimal useLimit;
+
+        @ApiModelProperty("优惠金额")
+        private BigDecimal discountPrice;
+
+        @ApiModelProperty("优惠券类型: FULL_DISCOUNT(满减券) VOUCHER(代金券) ")
+        private CouponTypeEnum couponType;
+
+        @ApiModelProperty("有效天数")
+        private Integer validDay;
+
+        @ApiModelProperty("生效时间")
+        private Long startTime;
+
+        @ApiModelProperty("失效时间")
+        private Long endTime;
+
+        @ApiModelProperty("库存量")
+        private Integer inventory;
+
+        @ApiModelProperty("领取次数限制")
+        private Integer quantityLimit;
+
+        @ApiModelProperty(value = "启禁状态", hidden = true)
+        private Integer status;
+
+        @ApiModelProperty(value = "更新用户", hidden = true)
+        private Long updatedBy;
+
+        @ApiModelProperty(value = "更新时间", hidden = true)
+        private Long updateTime;
+
+        @ApiModelProperty(value = "创建用户", hidden = true)
+        private Long createdBy;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public boolean invalidRequestParam(Long userId) {
+
+            if (Objects.isNull(getId())) {
+
+                // 新增参数
+                if (StringUtils.isEmpty(getName())) {
+                    throw new BizException("优惠券名称不能为空");
+                }
+
+                if (Objects.isNull(getClientType())) {
+                    throw new BizException("客户端不能为空");
+                }
+
+                if (Objects.isNull(getCategory())) {
+                    throw new BizException("可用品类不能为空");
+                }
+
+                if (Objects.isNull(getCouponType())) {
+                    throw new BizException("优惠券类型不能为空");
+                }
+
+                if (CouponTypeEnum.FULL_DISCOUNT == getCouponType()
+                        && Optional.ofNullable(getUseLimit()).map(BigDecimal::intValue).orElse(0) <= 0) {
+                    throw new BizException("满减金额未设置");
+                }
+
+                if (Optional.ofNullable(getValidDay()).orElse(0) <= 0
+                        && (Optional.ofNullable(getStartTime()).orElse(0L) == 0
+                            || Optional.ofNullable(getEndTime()).orElse(0L) == 0)) {
+                    throw new BizException("优惠券时间有效期不合法");
+                }
+
+                this.createdBy(userId).initSaveParam();
+            } else {
+
+                // 更新参数
+                this.updatedBy(userId).setUpdateTime(DateTime.now().getMillis());
+            }
+
+            return false;
+        }
+
+        public CouponInfo initSaveParam() {
+
+            return this.describe("")
+                    .useLimit(BigDecimal.ZERO)
+                    .discountPrice(BigDecimal.ZERO)
+                    .validDay(0)
+                    .startTime(0L)
+                    .endTime(0L)
+                    .inventory(0)
+                    .quantityLimit(0)
+                    .status(EStatus.DISABLE.getValue());
+        }
+
+        public CouponInfo describe(String describe) {
+            if (StringUtils.isEmpty(this.describe)) {
+                this.describe = describe;
+            }
+            return this;
+        }
+
+        public CouponInfo useLimit(BigDecimal useLimit) {
+            if (Objects.isNull(this.useLimit)) {
+                this.useLimit = useLimit;
+            }
+            return this;
+        }
+
+        public CouponInfo discountPrice(BigDecimal discountPrice) {
+            if (Objects.isNull(this.discountPrice)) {
+                this.discountPrice = discountPrice;
+            }
+            return this;
+        }
+
+        public CouponInfo validDay(Integer validDay) {
+            if (Objects.isNull(this.validDay)) {
+                this.validDay = validDay;
+            }
+            return this;
+        }
+
+        public CouponInfo startTime(Long startTime) {
+            if (Objects.isNull(this.startTime)) {
+                this.startTime = startTime;
+            }
+            return this;
+        }
+
+        public CouponInfo endTime(Long endTime) {
+            if (Objects.isNull(this.endTime)) {
+                this.endTime = endTime;
+            }
+            return this;
+        }
+
+        public CouponInfo inventory(Integer inventory) {
+            this.inventory = inventory;
+            return this;
+        }
+
+        public CouponInfo quantityLimit(Integer quantityLimit) {
+            this.quantityLimit = quantityLimit;
+            return this;
+        }
+
+        public CouponInfo status(Integer status) {
+            this.status = status;
+            return this;
+        }
+
+        public CouponInfo createdBy(Long createdBy) {
+            this.createdBy = createdBy;
+            return this;
+        }
+
+        public CouponInfo updatedBy(Long updatedBy) {
+            this.updatedBy = updatedBy;
+            return this;
+        }
+
+    }
+}

+ 343 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/coupon/CouponIssueVo.java

@@ -0,0 +1,343 @@
+package com.yonge.cooleshow.admin.io.request.coupon;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.biz.dal.dto.UserParam;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.SendTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-09-02
+ */
+public class CouponIssueVo {
+
+    @ApiModel(value = "优惠券发放信息分页请求", description = "优惠券发放信息分页请求")
+    public static class PageRequest extends QueryInfo {
+
+        @ApiModelProperty(value = "优惠券id",required = true)
+        @NotNull(message = "优惠券id不能为空")
+        private Long couponId;
+
+        // 真实姓名/昵称/手机号/编号
+        @ApiModelProperty("真实姓名/昵称/手机号/编号")
+        private String keyword;
+
+        // 客户端 TEACHER  STUDENT
+        @ApiModelProperty("客户端 TEACHER  STUDENT")
+        private ClientEnum client;
+
+        // 发放方式 PLATFORM AVTIVITY
+        @ApiModelProperty("发放方式 PLATFORM:后台发放 AVTIVITY:活动领取")
+        private SendTypeEnum issueWay;
+
+        //使用状态 USED:已使用 USABLE:未使用 EXPIRED:过期
+        @ApiModelProperty("使用状态 USED:已使用 USABLE:未使用 EXPIRED:过期")
+        private CouponUseStateEnum useState;
+
+        //  发放开始时间
+        @ApiModelProperty("发放开始时间")
+        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        private Date issueStartTime;
+
+        // 发放结束时间
+        @ApiModelProperty("发放结束时间")
+        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        private Date issueEndTime;
+
+        //  使用开始时间
+        @ApiModelProperty("使用开始时间")
+        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        private Date usedStartTime;
+
+        // 使用结束时间
+        @ApiModelProperty("使用结束时间")
+        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        private Date usedEndTime;
+
+        public Long getCouponId() {
+            return couponId;
+        }
+
+        public void setCouponId(Long couponId) {
+            this.couponId = couponId;
+        }
+
+        public String getKeyword() {
+            return keyword;
+        }
+
+        public void setKeyword(String keyword) {
+            this.keyword = keyword;
+        }
+
+        public ClientEnum getClient() {
+            return client;
+        }
+
+        public void setClient(ClientEnum client) {
+            this.client = client;
+        }
+
+        public SendTypeEnum getIssueWay() {
+            return issueWay;
+        }
+
+        public void setIssueWay(SendTypeEnum issueWay) {
+            this.issueWay = issueWay;
+        }
+
+        public CouponUseStateEnum getUseState() {
+            return useState;
+        }
+
+        public void setUseState(CouponUseStateEnum useState) {
+            this.useState = useState;
+        }
+
+        public Date getIssueStartTime() {
+            return issueStartTime;
+        }
+
+        public void setIssueStartTime(Date issueStartTime) {
+            this.issueStartTime = issueStartTime;
+        }
+
+        public Date getIssueEndTime() {
+            return issueEndTime;
+        }
+
+        public void setIssueEndTime(Date issueEndTime) {
+            this.issueEndTime = issueEndTime;
+        }
+
+        public Date getUsedStartTime() {
+            return usedStartTime;
+        }
+
+        public void setUsedStartTime(Date usedStartTime) {
+            this.usedStartTime = usedStartTime;
+        }
+
+        public Date getUsedEndTime() {
+            return usedEndTime;
+        }
+
+        public void setUsedEndTime(Date usedEndTime) {
+            this.usedEndTime = usedEndTime;
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+    }
+
+
+
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "优惠券信息分页信息", description = "优惠券信息分页信息")
+    public static class CouponIssuePageInfo implements Serializable {
+
+        @ApiModelProperty("用户id")
+        private Long userId;
+
+        @ApiModelProperty("优惠券发放id")
+        private Long couponIssueId;
+
+        @ApiModelProperty("用户实名")
+        private String realName;
+
+        @ApiModelProperty("用户昵称")
+        private String username;
+
+        @ApiModelProperty("客户端类型 TEACHER :老师端 STUDENT:学生端")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("使用状态 USED:已使用 USABLE:未使用 EXPIRED:过期")
+        private CouponUseStateEnum useState;
+
+        @ApiModelProperty("订单号")
+        private String orderNo;
+
+        @ApiModelProperty("有效期开始时间")
+        private Date startTime;
+
+        @ApiModelProperty("有效期结束时间")
+        private Date endTime;
+
+        @ApiModelProperty("发放时间")
+        private Date issueTime;
+
+        @ApiModelProperty("使用时间")
+        private Date useTime;
+
+        @ApiModelProperty("发放途径PLATFORM:后台发放 ACTIVITY:活动领取")
+        private SendTypeEnum issueWay;
+
+        @ApiModelProperty("发放人昵称")
+        private String issueUsername;
+
+        @ApiModelProperty("发放人实名")
+        private String issueRealName;
+
+        @ApiModelProperty("备注")
+        private String remark;
+
+    }
+
+    @ApiModel("优惠券发放用户分页查询")
+    public static class CouponIssueUserRequest extends QueryInfo {
+
+        @ApiModelProperty(value = "优惠券id",required = true)
+        @NotNull(message = "优惠券id不能为空")
+        private Long couponId;
+
+        // 真实姓名/昵称/手机号/编号
+        @ApiModelProperty("真实姓名/昵称/手机号/编号")
+        private String keyword;
+
+        // 客户端 TEACHER  STUDENT
+        @ApiModelProperty("客户端 TEACHER  STUDENT")
+        private ClientEnum client;
+
+        public Long getCouponId() {
+            return couponId;
+        }
+
+        public void setCouponId(Long couponId) {
+            this.couponId = couponId;
+        }
+
+        public String getKeyword() {
+            return keyword;
+        }
+
+        public void setKeyword(String keyword) {
+            this.keyword = keyword;
+        }
+
+        public ClientEnum getClient() {
+            return client;
+        }
+
+        public void setClient(ClientEnum client) {
+            this.client = client;
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+    }
+
+    @ApiModel("发放优惠券用户分页数据")
+    public static class CouponIssueUserPageInfo {
+
+        @ApiModelProperty("用户id")
+        private Long userId;
+
+        @ApiModelProperty("实名")
+        private String realName;
+
+        @ApiModelProperty("昵称")
+        private String username;
+
+        @ApiModelProperty("客户端")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("手机号")
+        private String phone;
+
+        public Long getUserId() {
+            return userId;
+        }
+
+        public void setUserId(Long userId) {
+            this.userId = userId;
+        }
+
+        public String getRealName() {
+            return realName;
+        }
+
+        public void setRealName(String realName) {
+            this.realName = realName;
+        }
+
+        public String getUsername() {
+            return username;
+        }
+
+        public void setUsername(String username) {
+            this.username = username;
+        }
+
+        public ClientEnum getClientType() {
+            return clientType;
+        }
+
+        public void setClientType(ClientEnum clientType) {
+            this.clientType = clientType;
+        }
+
+        public String getPhone() {
+            return phone;
+        }
+
+        public void setPhone(String phone) {
+            this.phone = phone;
+        }
+    }
+
+    @ApiModel("发送优惠券")
+    public static class CouponIssueUserParam {
+
+        @ApiModelProperty(value = "优惠券id",required = true)
+        @NotNull(message = "优惠券id不能为空")
+        private Long couponId;
+
+        @ApiModelProperty("用户信息")
+        @Size(min = 1,message = "请选择发送优惠券用户")
+        private List<UserParam> userParam;
+
+        public Long getCouponId() {
+            return couponId;
+        }
+
+        public void setCouponId(Long couponId) {
+            this.couponId = couponId;
+        }
+
+        public List<UserParam> getUserParam() {
+            return userParam;
+        }
+
+        public void setUserParam(List<UserParam> userParam) {
+            this.userParam = userParam;
+        }
+
+
+    }
+}

+ 37 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/UserParam.java

@@ -0,0 +1,37 @@
+package com.yonge.cooleshow.biz.dal.dto;
+
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-09-02
+ */
+@ApiModel("用户信息")
+public class UserParam{
+
+    @ApiModelProperty("用户id")
+    private Long userId;
+
+    @ApiModelProperty("客户端类型 TEACHER :老师 STUDENT:学生")
+    private ClientEnum clientType;
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public ClientEnum getClientType() {
+        return clientType;
+    }
+
+    public void setClientType(ClientEnum clientType) {
+        this.clientType = clientType;
+    }
+}

+ 109 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CouponInfo.java

@@ -0,0 +1,109 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 优惠券信息
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@Getter
+@Setter
+@TableName("coupon_info")
+@ApiModel(value = "CouponInfo对象", description = "优惠券信息")
+public class CouponInfo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("优惠券ID")
+    @TableId(value = "id_", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("优惠券名称")
+    @TableField("name_")
+    private String name;
+
+    @ApiModelProperty("优惠券编号")
+    @TableField("serial_num_")
+    private String serialNum;
+
+    @ApiModelProperty("描述")
+    @TableField("describe_")
+    private String describe;
+
+    @ApiModelProperty("客户端类型")
+    @TableField("client_type_")
+    private String clientType;
+
+    @ApiModelProperty("可用品类")
+    @TableField("category_")
+    private String category;
+
+    @ApiModelProperty("使用门槛")
+    @TableField("use_limit_")
+    private BigDecimal useLimit;
+
+    @ApiModelProperty("优惠金额")
+    @TableField("discount_price_")
+    private BigDecimal discountPrice;
+
+    @ApiModelProperty("优惠券类型")
+    @TableField("coupon_type_")
+    private String couponType;
+
+    @ApiModelProperty("有效天数")
+    @TableField("valid_day_")
+    private Integer validDay;
+
+    @ApiModelProperty("生效时间")
+    @TableField("start_time_")
+    private Long startTime;
+
+    @ApiModelProperty("失效时间")
+    @TableField("end_time_")
+    private Long endTime;
+
+    @ApiModelProperty("库存量")
+    @TableField("inventory_")
+    private Integer inventory;
+
+    @ApiModelProperty("领取次数限制")
+    @TableField("quantity_limit_")
+    private Integer quantityLimit;
+
+    @ApiModelProperty("启禁状态")
+    @TableField("status_")
+    private Integer status;
+
+    @ApiModelProperty("更新用户")
+    @TableField("updated_by_")
+    private Long updatedBy;
+
+    @ApiModelProperty("更新时间")
+    @TableField("update_time_")
+    private Long updateTime;
+
+    @ApiModelProperty("创建用户")
+    @TableField("created_by_")
+    private Long createdBy;
+
+    @ApiModelProperty("创建时间")
+    @TableField("created_time_")
+    private Date createdTime;
+
+
+}

+ 93 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CouponIssue.java

@@ -0,0 +1,93 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 优惠券发放
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@Getter
+@Setter
+@TableName("coupon_issue")
+@ApiModel(value = "CouponIssue对象", description = "优惠券发放")
+public class CouponIssue implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("发放ID")
+    @TableId(value = "id_", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("用户ID")
+    @TableField("user_id_")
+    private Long userId;
+
+    @ApiModelProperty("优惠券ID")
+    @TableField("coupon_id_")
+    private Long couponId;
+
+    @ApiModelProperty("客户端类型")
+    @TableField("client_type_")
+    private String clientType;
+
+    @ApiModelProperty("使用状态")
+    @TableField("use_state_")
+    private CouponUseStateEnum useState;
+
+    @ApiModelProperty("使用时间")
+    @TableField("use_time_")
+    private Long useTime;
+
+    @ApiModelProperty("订单编号")
+    @TableField("order_no_")
+    private Long orderNo;
+
+    @ApiModelProperty("生效时间")
+    @TableField("start_time_")
+    private Long startTime;
+
+    @ApiModelProperty("失效时间")
+    @TableField("end_time_")
+    private Long endTime;
+
+    @ApiModelProperty("发放方式")
+    @TableField("issue_way_")
+    private String issueWay;
+
+    @ApiModelProperty("发放人")
+    @TableField("issuer_")
+    private Long issuer;
+
+    @ApiModelProperty("发放时间")
+    @TableField("issue_time_")
+    private Long issueTime;
+
+    @ApiModelProperty("备注")
+    @TableField("remark_")
+    private String remark;
+
+    @ApiModelProperty("启禁状态")
+    @TableField("status_")
+    private Integer status;
+
+    @ApiModelProperty("创建时间")
+    @TableField("created_time_")
+    private Date createdTime;
+
+
+}

+ 127 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysUser.java

@@ -0,0 +1,127 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 用户表
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@Getter
+@Setter
+@TableName("sys_user")
+@ApiModel(value = "SysUser对象", description = "用户表")
+public class SysUser implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("主键ID")
+    @TableId(value = "id_", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("用户名")
+    @TableField("username_")
+    private String username;
+
+    @TableField("password_")
+    private String password;
+
+    @ApiModelProperty("随机盐")
+    @TableField("salt_")
+    private String salt;
+
+    @ApiModelProperty("手机号")
+    @TableField("phone_")
+    private String phone;
+
+    @ApiModelProperty("头像")
+    @TableField("avatar_")
+    private String avatar;
+
+    @ApiModelProperty("创建时间")
+    @TableField("create_time_")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("修改时间")
+    @TableField("update_time_")
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("0-正常,1-锁定")
+    @TableField("lock_flag_")
+    private Integer lockFlag;
+
+    @ApiModelProperty("微信openid")
+    @TableField("wx_openid_")
+    private String wxOpenid;
+
+    @ApiModelProperty("QQ openid")
+    @TableField("qq_openid_")
+    private String qqOpenid;
+
+    @ApiModelProperty("用户类型(STUDENT/TEACHER/SYSTEM)")
+    @TableField("user_type_")
+    private String userType;
+
+    @ApiModelProperty("性别(0,女  1,男)")
+    @TableField("gender_")
+    private Integer gender;
+
+    @ApiModelProperty("民族")
+    @TableField("nation_")
+    private String nation;
+
+    @ApiModelProperty("出生日期")
+    @TableField("birthdate_")
+    private LocalDate birthdate;
+
+    @ApiModelProperty("邮箱")
+    @TableField("email_")
+    private String email;
+
+    @ApiModelProperty("融云token")
+    @TableField("im_token_")
+    private String imToken;
+
+    @ApiModelProperty("真实姓名")
+    @TableField("real_name_")
+    private String realName;
+
+    @ApiModelProperty("身份证号码")
+    @TableField("id_card_no_")
+    private String idCardNo;
+
+    @ApiModelProperty("证件类型")
+    @TableField("certificate_type_")
+    private String certificateType;
+
+    @ApiModelProperty("是否是超管")
+    @TableField("is_super_admin_")
+    private Boolean superAdmin;
+
+    @ApiModelProperty("微信号")
+    @TableField("wechat_id_")
+    private String wechatId;
+
+    @ApiModelProperty("0-正常,1-删除")
+    @TableField("del_flag_")
+    private Integer delFlag;
+
+    @ApiModelProperty("最近一次修改用户名称时间")
+    @TableField("last_username_time_")
+    private LocalDateTime lastUsernameTime;
+
+
+}

+ 35 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/SendTypeEnum.java

@@ -0,0 +1,35 @@
+package com.yonge.cooleshow.biz.dal.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * 状态,-1,发送失败;0,待发送;1,发送中;2,发送完成
+ */
+public enum SendTypeEnum implements BaseEnum<String, SendTypeEnum> {
+
+    PLATFORM("PLATFORM"),
+    ACTIVITY("ACTIVITY"),
+
+
+    ;
+
+    @EnumValue
+    private String code;
+    private String msg;
+
+    SendTypeEnum(String msg) {
+        this.code = this.name();
+        this.msg = msg;
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+
+    public String getMsg() {
+        return this.msg;
+    }
+
+}

+ 40 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/coupon/CouponCategoryEnum.java

@@ -0,0 +1,40 @@
+package com.yonge.cooleshow.biz.dal.enums.coupon;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * 优惠券可用品类
+ * @author: Eric
+ * @date: 2022-03-30
+ */
+public enum CouponCategoryEnum implements BaseEnum<String, CouponCategoryEnum> {
+
+    UNIVERSAL("全场通用"),
+    VIP("小酷Ai"),
+    PIANO("云酷琴房"),
+    MALL("商场购物券"),
+    MUSIC("单曲点播券"),
+    SPARRING("陪练课购买券"),
+    LIVE("直播课购买券"),
+    VIDEO("视频课购买券"),
+    ;
+
+    @EnumValue
+    private String code;
+    private String msg;
+
+    CouponCategoryEnum(String msg) {
+        this.code = this.name();
+        this.msg = msg;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return this.msg;
+    }
+
+}

+ 33 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/coupon/CouponTypeEnum.java

@@ -0,0 +1,33 @@
+package com.yonge.cooleshow.biz.dal.enums.coupon;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * 优惠券类型
+ * @author: Eric
+ * @date: 2022-03-30
+ */
+public enum CouponTypeEnum implements BaseEnum<String, CouponTypeEnum> {
+
+    FULL_DISCOUNT("满减券"),
+    VOUCHER("代金券"),
+    ;
+
+    @EnumValue
+    private String code;
+    private String msg;
+
+    CouponTypeEnum(String msg) {
+        this.code = this.name();
+        this.msg = msg;
+    }
+
+    public String getMsg() {
+        return this.msg;
+    }
+
+    public String getCode() {
+        return code;
+    }
+}

+ 34 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/coupon/CouponUseStateEnum.java

@@ -0,0 +1,34 @@
+package com.yonge.cooleshow.biz.dal.enums.coupon;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * 优惠券使用状态
+ * @author: Eric
+ * @date: 2022-03-30
+ */
+public enum CouponUseStateEnum implements BaseEnum<String, CouponUseStateEnum> {
+
+
+    EXPIRED("已失效"),
+    USABLE("可使用"),
+    USED("已使用"),
+    ;
+    @EnumValue
+    private String code;
+    private String msg;
+
+    CouponUseStateEnum(String msg) {
+        this.code = this.name();
+        this.msg = msg;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return this.msg;
+    }
+}

+ 41 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/CouponInfoMapper.java

@@ -0,0 +1,41 @@
+package com.yonge.cooleshow.biz.dal.mapper;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.entity.CouponInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
+import com.yonge.cooleshow.biz.dal.vo.coupon.CouponInfoWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * 优惠券信息 Mapper 接口
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@Repository
+public interface CouponInfoMapper extends BaseMapper<CouponInfo> {
+
+    /**
+     * 分页查询优惠券信息
+     * @param page IPage<CouponInfoWrapper>
+     * @param query CouponInfoQuery
+     * @return List<CouponInfoWrapper>
+     */
+    List<CouponInfoWrapper> selectCouponPageInfo(@Param("page") IPage<CouponInfoWrapper> page, @Param("record") CouponInfoQuery query);
+
+    /**
+     * 优惠券发放未使用统计
+     * @param couponIds 优惠券ID
+     * @param query 统计查询条件
+     * @return List<StatGroupWrapper>
+     */
+    List<StatGroupWrapper> selectCouponIssueStatInfo(@Param("couponIds") List<Long> couponIds, @Param("record") CouponInfoQuery.IssueStatQuery query);
+}

+ 21 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/CouponIssueMapper.java

@@ -0,0 +1,21 @@
+package com.yonge.cooleshow.biz.dal.mapper;
+
+import com.yonge.cooleshow.biz.dal.entity.CouponIssue;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponIssueQueryInfo;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 优惠券发放 Mapper 接口
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@Repository
+public interface CouponIssueMapper extends BaseMapper<CouponIssue> {
+
+    void queryCouponIssueInfo(@Param("query") CouponIssueQueryInfo query);
+}

+ 18 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/SysUserMapper.java

@@ -0,0 +1,18 @@
+package com.yonge.cooleshow.biz.dal.mapper;
+
+import com.yonge.cooleshow.biz.dal.entity.SysUser;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 用户表 Mapper 接口
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@Repository
+public interface SysUserMapper extends BaseMapper<SysUser> {
+
+}

+ 54 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/queryInfo/CouponInfoQuery.java

@@ -0,0 +1,54 @@
+package com.yonge.cooleshow.biz.dal.queryInfo;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 优惠券查询条件
+ * Created by Eric.Shang on 2022/9/2.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class CouponInfoQuery implements Serializable {
+
+    // 优惠券名称
+    private String name;
+    // 客户端类型
+    private ClientEnum clientType;
+    // 优惠券类型
+    private CouponTypeEnum couponType;
+    // 可用品类
+    private CouponCategoryEnum category;
+
+    public static CouponInfoQuery from(String recv) {
+
+        return JSON.parseObject(recv, CouponInfoQuery.class);
+    }
+
+    /**
+     * 优惠券发放数统计
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class IssueStatQuery implements Serializable {
+
+        // 当前时间
+        private Long timestamp;
+        // 使用状态
+        private CouponUseStateEnum useState;
+    }
+}

+ 126 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/queryInfo/CouponIssueQueryInfo.java

@@ -0,0 +1,126 @@
+package com.yonge.cooleshow.biz.dal.queryInfo;
+
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.SendTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-09-02
+ */
+public class CouponIssueQueryInfo implements Serializable {
+
+    // 优惠券id
+    private Long couponId;
+    // 用户id
+    private Long userId;
+
+    // 真实姓名/昵称/手机号/编号
+    private String keyword;
+
+    // 客户端 TEACHER  STUDENT
+    private ClientEnum clientType;
+
+    // 发放方式 PLATFORM ACTIVITY
+    private SendTypeEnum issueWay;
+
+    // 使用状态 USED USABLE EXPIRED
+    private CouponUseStateEnum useStatus;
+
+    //  发放开始时间
+    private Date issueStartTime;
+
+    // 发放结束时间
+    private Date issueEndTime;
+
+    //  使用开始时间
+    private Date usedStartTime;
+
+    // 使用结束时间
+    private Date usedEndTime;
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getKeyword() {
+        return keyword;
+    }
+
+    public void setKeyword(String keyword) {
+        this.keyword = keyword;
+    }
+
+    public ClientEnum getClientType() {
+        return clientType;
+    }
+
+    public void setClientType(ClientEnum clientType) {
+        this.clientType = clientType;
+    }
+
+    public SendTypeEnum getIssueWay() {
+        return issueWay;
+    }
+
+    public void setIssueWay(SendTypeEnum issueWay) {
+        this.issueWay = issueWay;
+    }
+
+    public Long getCouponId() {
+        return couponId;
+    }
+
+    public void setCouponId(Long couponId) {
+        this.couponId = couponId;
+    }
+
+    public CouponUseStateEnum getUseStatus() {
+        return useStatus;
+    }
+
+    public void setUseStatus(CouponUseStateEnum useStatus) {
+        this.useStatus = useStatus;
+    }
+
+    public Date getIssueStartTime() {
+        return issueStartTime;
+    }
+
+    public void setIssueStartTime(Date issueStartTime) {
+        this.issueStartTime = issueStartTime;
+    }
+
+    public Date getIssueEndTime() {
+        return issueEndTime;
+    }
+
+    public void setIssueEndTime(Date issueEndTime) {
+        this.issueEndTime = issueEndTime;
+    }
+
+    public Date getUsedStartTime() {
+        return usedStartTime;
+    }
+
+    public void setUsedStartTime(Date usedStartTime) {
+        this.usedStartTime = usedStartTime;
+    }
+
+    public Date getUsedEndTime() {
+        return usedEndTime;
+    }
+
+    public void setUsedEndTime(Date usedEndTime) {
+        this.usedEndTime = usedEndTime;
+    }
+}

+ 40 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CouponInfoService.java

@@ -0,0 +1,40 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.entity.CouponInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
+import com.yonge.cooleshow.biz.dal.vo.coupon.CouponInfoWrapper;
+
+/**
+ * <p>
+ * 优惠券信息 服务类
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+public interface CouponInfoService extends IService<CouponInfo> {
+
+    /**
+     * 分页查询优惠券信息
+     * @param page IPage<Object>
+     * @param query CouponInfoQuery
+     * @return IPage<CouponInfoWrapper>
+     */
+    IPage<CouponInfoWrapper> queryCouponPageInfo(IPage<CouponInfoWrapper> page, CouponInfoQuery query);
+
+    /**
+     * 优惠券信息
+     * @param id 优惠券ID
+     * @return CouponInfo
+     */
+    CouponInfo queryCouponInfoById(Long id);
+
+    /**
+     * 新增或更新优惠券信息
+     * @param couponInfo CouponInfo
+     * @return CouponInfo
+     */
+    CouponInfo saveOrUpdateCouponInfo(CouponInfo couponInfo);
+}

+ 34 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CouponIssueService.java

@@ -0,0 +1,34 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import com.yonge.cooleshow.biz.dal.dto.UserParam;
+import com.yonge.cooleshow.biz.dal.entity.CouponIssue;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 优惠券发放 服务类
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+public interface CouponIssueService extends IService<CouponIssue> {
+
+    /**
+     * 撤销优惠券
+     *
+     * @param couponIssueId 优惠券发放记录id
+     * @return
+     */
+    Boolean withdrawCoupon(Long couponIssueId);
+
+    /**
+     * 发放优惠券
+     *
+     * @param couponId 优惠券id
+     * @param userParam 用户信息
+     */
+    void issueCoupon(Long couponId, List<UserParam> userParam);
+}

+ 136 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CouponInfoServiceImp.java

@@ -0,0 +1,136 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.google.common.collect.Lists;
+import com.yonge.cooleshow.biz.dal.entity.CouponInfo;
+import com.yonge.cooleshow.biz.dal.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import com.yonge.cooleshow.biz.dal.mapper.CouponInfoMapper;
+import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
+import com.yonge.cooleshow.biz.dal.service.CouponInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.biz.dal.vo.coupon.CouponInfoWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import com.yonge.toolset.base.exception.BizException;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 优惠券信息 服务实现类
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@Service
+public class CouponInfoServiceImp extends ServiceImpl<CouponInfoMapper, CouponInfo> implements CouponInfoService {
+
+    @Autowired
+    private SysUserMapper sysUserMapper;
+
+    /**
+     * 分页查询优惠券信息
+     *
+     * @param page  IPage<CouponInfoWrapper>
+     * @param query CouponInfoQuery
+     * @return IPage<CouponInfoWrapper>
+     */
+    @Override
+    public IPage<CouponInfoWrapper> queryCouponPageInfo(IPage<CouponInfoWrapper> page, CouponInfoQuery query) {
+
+        // 优惠券信息
+        List<CouponInfoWrapper> wrappers = getBaseMapper().selectCouponPageInfo(page, query);
+
+        if (CollectionUtils.isEmpty(wrappers)) {
+            // 没有数据,直接返回
+            return page.setRecords(Lists.newArrayList());
+        }
+
+        List<Long> couponIds = wrappers.stream()
+                .map(CouponInfoWrapper::getId).distinct().collect(Collectors.toList());
+
+        // 查询优惠券发放人数
+        Map<Long, Integer> issueNumMap = getBaseMapper().selectCouponIssueStatInfo(couponIds,
+                        CouponInfoQuery.IssueStatQuery.builder()
+                                .timestamp(DateTime.now().getMillis())
+                                .useState(CouponUseStateEnum.USABLE).build()).stream()
+                .collect(Collectors.toMap(StatGroupWrapper::getId, StatGroupWrapper::getTotal, (o, n) -> n));
+
+        // TODO:关联奖品数
+
+        // 更新用户信息
+        List<Long> userIds = wrappers.stream().map(CouponInfoWrapper::getUpdatedBy).distinct().collect(Collectors.toList());
+
+        Map<Long, String> userNameMap = sysUserMapper.selectBatchIds(userIds).stream()
+                .collect(Collectors.toMap(SysUser::getId, x -> {
+
+                    if (StringUtils.isNotEmpty(x.getUsername())) {
+                        return x.getUsername();
+                    }
+                    return x.getRealName();
+                }, (o, n) -> n));
+
+        for (CouponInfoWrapper item : wrappers) {
+
+            item.rewardNum(0)
+                    .updateUser(userNameMap.getOrDefault(item.getUpdatedBy(), ""))
+                    .setIssueNum(issueNumMap.getOrDefault(item.getId(), 0));
+        }
+
+        return page.setRecords(wrappers);
+    }
+
+    /**
+     * 优惠券信息
+     *
+     * @param id 优惠券ID
+     * @return CouponInfo
+     */
+    @Override
+    public CouponInfo queryCouponInfoById(Long id) {
+
+        CouponInfo couponInfo = getBaseMapper().selectById(id);
+        if (Objects.isNull(couponInfo)) {
+            throw new BizException("无效的优惠券ID");
+        }
+
+        return couponInfo;
+    }
+
+    /**
+     * 新增或更新优惠券信息
+     *
+     * @param couponInfo CouponInfo
+     * @return CouponInfo
+     */
+    @Override
+    public CouponInfo saveOrUpdateCouponInfo(CouponInfo couponInfo) {
+
+        if (Objects.isNull(couponInfo.getId())) {
+
+            // 新增优惠券
+            save(couponInfo);
+        } else {
+
+            CouponInfo info = getById(couponInfo.getId());
+            if (Objects.isNull(info)) {
+                throw new BizException("无效的优惠券ID");
+            }
+
+            // 更新优惠券
+            updateById(couponInfo);
+        }
+
+        return getById(couponInfo.getId());
+    }
+}

+ 50 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CouponIssueServiceImp.java

@@ -0,0 +1,50 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.yonge.cooleshow.biz.dal.dto.UserParam;
+import com.yonge.cooleshow.biz.dal.entity.CouponInfo;
+import com.yonge.cooleshow.biz.dal.entity.CouponIssue;
+import com.yonge.cooleshow.biz.dal.mapper.CouponIssueMapper;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponIssueQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.CouponInfoService;
+import com.yonge.cooleshow.biz.dal.service.CouponIssueService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.common.enums.EStatus;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 优惠券发放 服务实现类
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@Service
+public class CouponIssueServiceImp extends ServiceImpl<CouponIssueMapper, CouponIssue> implements CouponIssueService {
+
+    @Autowired
+    private CouponInfoService couponInfoService;
+
+
+    public void queryCouponIssueInfo(CouponIssueQueryInfo query) {
+        baseMapper.queryCouponIssueInfo(query);
+    }
+
+    @Override
+    public Boolean withdrawCoupon(Long couponIssueId) {
+        return this.lambdaUpdate()
+                .eq(CouponIssue::getId,couponIssueId)
+                .set(CouponIssue::getStatus, EStatus.DISABLE.getValue())
+                .update();
+    }
+
+    @Override
+    public void issueCoupon(Long couponId, List<UserParam> userParam) {
+        CouponInfo couponInfo = couponInfoService.queryCouponInfoById(couponId);
+        // 判断优惠券类型 设置优惠券时间
+
+    }
+}

+ 49 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/coupon/CouponInfoWrapper.java

@@ -0,0 +1,49 @@
+package com.yonge.cooleshow.biz.dal.vo.coupon;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *  优惠券信息
+ * Created by Eric.Shang on 2022/9/2.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class CouponInfoWrapper implements Serializable {
+
+    private Long id;
+    private String name;
+    private String clientType;
+    private String category;
+    private String couponType;
+    private Integer status;
+    private Long updatedBy;
+    private Long updateTime;
+    private Long createdBy;
+    private Date createdTime;
+
+    // 发放领取数
+    private Integer issueNum;
+    // 关联奖品数
+    private Integer rewardNum;
+    // 更新用户
+    private String updateUser;
+
+
+    public CouponInfoWrapper rewardNum(Integer rewardNum) {
+        this.rewardNum = rewardNum;
+        return this;
+    }
+
+    public CouponInfoWrapper updateUser(String updateUser) {
+        this.updateUser = updateUser;
+        return this;
+    }
+}

+ 24 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/StatGroupWrapper.java

@@ -0,0 +1,24 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 分组统计指标
+ * Created by Eric.Shang on 28/7/17.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class StatGroupWrapper implements Serializable {
+
+    private Long id;
+    private Integer total;
+    private String gid; // 字符串分组ID
+
+}

+ 69 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/CouponInfoMapper.xml

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.yonge.cooleshow.biz.dal.mapper.CouponInfoMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.yonge.cooleshow.biz.dal.entity.CouponInfo">
+        <id column="id_" property="id" />
+        <result column="name_" property="name" />
+        <result column="serial_num_" property="serialNum" />
+        <result column="describe_" property="describe" />
+        <result column="client_type_" property="clientType" />
+        <result column="category_" property="category" />
+        <result column="use_limit_" property="useLimit" />
+        <result column="discount_price_" property="discountPrice" />
+        <result column="coupon_type_" property="couponType" />
+        <result column="valid_day_" property="validDay" />
+        <result column="start_time_" property="startTime" />
+        <result column="end_time_" property="endTime" />
+        <result column="inventory_" property="inventory" />
+        <result column="quantity_limit_" property="quantityLimit" />
+        <result column="status_" property="status" />
+        <result column="updated_by_" property="updatedBy" />
+        <result column="update_time_" property="updateTime" />
+        <result column="created_by_" property="createdBy" />
+        <result column="created_time_" property="createdTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id_, name_, serial_num_, describe_, client_type_, category_, use_limit_, discount_price_, coupon_type_, valid_day_, start_time_, end_time_, inventory_, quantity_limit_, status_, updated_by_, update_time_, created_by_, created_time_
+    </sql>
+
+    <!--优惠券分页查询-->
+    <select id="selectCouponPageInfo" resultType="com.yonge.cooleshow.biz.dal.vo.coupon.CouponInfoWrapper">
+        SELECT t1.id_, t1.name_, t1.client_type_, t1.category_, t1.coupon_type_, t1.status_, t1.updated_by_, t1.update_time_, t1.created_time_ FROM coupon_info t1
+        <where>
+            <if test="record.name != null">
+                AND t1.name_ LIKE '%${record.name}%'
+            </if>
+            <if test="record.clientType != null">
+                AND t1.client_type_ = #{record.clientType}
+            </if>
+            <if test="record.couponType != null">
+                AND t1.coupon_type_ = #{record.couponType}
+            </if>
+            <if test="record.category != null">
+                AND t1.category_ = #{record.category}
+            </if>
+        </where>
+    </select>
+
+    <!--优惠券发放统计-->
+    <select id="selectCouponIssueStatInfo" resultType="com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper">
+        SELECT t1.coupon_id_ AS id, COUNT(DISTINCT t1.id_) AS total FROM coupon_issue t1
+        <where>
+            <if test="couponIds != null">
+                AND t1.coupon_id_ IN (<foreach collection="couponIds" separator="," item="item">#{item}</foreach>)
+            </if>
+            <if test="record.useState != null">
+                AND t1.use_state_ = #{record.useState}
+            </if>
+            <if test="record.timestamp != null">
+                AND t1.start_time_ &lt;= #{record.timestamp} AND #{record.timestamp} &lt;= t1.end_time_ GROUP BY t1.coupon_id_
+            </if>
+        </where>
+    </select>
+    <!--优惠券分页查询-->
+
+</mapper>

+ 85 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/CouponIssueMapper.xml

@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.yonge.cooleshow.biz.dal.mapper.CouponIssueMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.yonge.cooleshow.biz.dal.entity.CouponIssue">
+        <id column="id_" property="id" />
+        <result column="user_id_" property="userId" />
+        <result column="coupon_id_" property="couponId" />
+        <result column="client_type_" property="clientType" />
+        <result column="use_state_" property="useState" />
+        <result column="use_time_" property="useTime" />
+        <result column="order_no_" property="orderNo" />
+        <result column="start_time_" property="startTime" />
+        <result column="end_time_" property="endTime" />
+        <result column="issue_way_" property="issueWay" />
+        <result column="issuer_" property="issuer" />
+        <result column="issue_time_" property="issueTime" />
+        <result column="remark_" property="remark" />
+        <result column="status_" property="status" />
+        <result column="created_time_" property="createdTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id_, user_id_, coupon_id_, client_type_, use_state_, use_time_, order_no_, start_time_, end_time_, issue_way_, issuer_, issue_time_, remark_, status_, created_time_
+    </sql>
+
+    <select id="queryCouponIssueInfo" >
+        select
+            su.id_ as userId,
+            ci.id_ as couponIssueId,
+            su.real_name_ as realName,
+            su.username_ as username,
+            ci.client_type_ as clientType,
+            ci.use_state_ as useState,
+            ci.order_no_ as orderNo,
+            ci.start_time_ as startTime,
+            ci.end_time_ as endTime,
+            ci.issue_time_ as issueTime,
+            ci.use_time_ as useTime,
+            ci.issue_way_ as issueWay
+        from coupon_issue ci
+        left join sys_user su on ci.user_id_ = su.id_
+        <where>
+            <if test="query.userId != null">
+                and #{query.userId} = ci.user_id_
+            </if>
+            <if test="query.couponId != null">
+                and #{query.couponId} = ci.coupon_id_
+            </if>
+            <if test="query.clientType != null">
+                and #{query.clientType} = ci.client_type_
+            </if>
+            <if test="query.issueWay != null">
+                and #{query.issueWay}  = ci.issue_way_
+            </if>
+            <if test="query.useStatus != null">
+                and #{query.useStatus} = ci.use_state_
+            </if>
+            <if test="query.issueStartTime != null">
+                and unix_timestamp( #{query.issueStartTime}) &lt;= ci.issue_time_
+            </if>
+            <if test="query.issueEndTime != null">
+                and unix_timestamp(#{query.issueEndTime}) &gt;= ci.issue_time_
+            </if>
+            <if test="query.usedStartTime != null">
+                and unix_timestamp(#{query.usedStartTime}) &lt;= ci.use_time_
+            </if>
+            <if test="query.usedEndTime != null">
+                and unix_timestamp(#{query.usedEndTime}) &gt;= ci.use_time_
+            </if>
+            <if test="query.keyword !=null and query.keyword != ''">
+                and (
+                    su.real_name_ like concat('%',#{query.keyword},'%')
+                    or su.username_ like concat('%',#{query.keyword},'%')
+                    or su.phone_ like concat('%',#{query.keyword},'%')
+                    or su.id_ like concat('%',#{query.keyword},'%')
+                )
+            </if>
+        </where>
+
+
+    </select>
+</mapper>

+ 38 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysUserMapper.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.yonge.cooleshow.biz.dal.mapper.SysUserMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.yonge.cooleshow.biz.dal.entity.SysUser">
+        <id column="id_" property="id" />
+        <result column="username_" property="username" />
+        <result column="password_" property="password" />
+        <result column="salt_" property="salt" />
+        <result column="phone_" property="phone" />
+        <result column="avatar_" property="avatar" />
+        <result column="create_time_" property="createTime" />
+        <result column="update_time_" property="updateTime" />
+        <result column="lock_flag_" property="lockFlag" />
+        <result column="wx_openid_" property="wxOpenid" />
+        <result column="qq_openid_" property="qqOpenid" />
+        <result column="user_type_" property="userType" />
+        <result column="gender_" property="gender" />
+        <result column="nation_" property="nation" />
+        <result column="birthdate_" property="birthdate" />
+        <result column="email_" property="email" />
+        <result column="im_token_" property="imToken" />
+        <result column="real_name_" property="realName" />
+        <result column="id_card_no_" property="idCardNo" />
+        <result column="certificate_type_" property="certificateType" />
+        <result column="is_super_admin_" property="superAdmin" />
+        <result column="wechat_id_" property="wechatId" />
+        <result column="del_flag_" property="delFlag" />
+        <result column="last_username_time_" property="lastUsernameTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id_, username_, password_, salt_, phone_, avatar_, create_time_, update_time_, lock_flag_, wx_openid_, qq_openid_, user_type_, gender_, nation_, birthdate_, email_, im_token_, real_name_, id_card_no_, certificate_type_, is_super_admin_, wechat_id_, del_flag_, last_username_time_
+    </sql>
+
+</mapper>

+ 1 - 1
cooleshow-user/user-classroom/src/main/java/com/yonge/cooleshow/classroom/ClassroomApplication.java

@@ -14,7 +14,7 @@ import org.springframework.context.annotation.Configuration;
 @SpringBootApplication
 @EnableDiscoveryClient
 @EnableFeignClients("com.yonge.cooleshow")
-@MapperScan(basePackages = {"com.yonge.cooleshow.biz.dal.dao", "com.yonge.toolset.payment.core.dao"})
+@MapperScan(basePackages = {"com.yonge.cooleshow.biz.dal.dao", "com.yonge.cooleshow.biz.dal.mapper", "com.yonge.toolset.payment.core.dao"})
 @ComponentScan(basePackages = {
         "com.yonge.cooleshow", "com.yonge.toolset"
 })

+ 1 - 1
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/StudentApplication.java

@@ -18,7 +18,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @SpringBootApplication
 @EnableDiscoveryClient
 @EnableFeignClients("com.yonge.cooleshow")
-@MapperScan(basePackages = {"com.yonge.cooleshow.biz.dal.dao", "com.yonge.toolset.payment.core.dao"})
+@MapperScan(basePackages = {"com.yonge.cooleshow.biz.dal.dao", "com.yonge.cooleshow.biz.dal.mapper", "com.yonge.toolset.payment.core.dao"})
 @ComponentScan(basePackages = {"com.yonge.cooleshow", "com.yonge.toolset"})
 @Configuration
 @EnableSwagger2Doc

+ 34 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/coupon/CouponInfoController.java

@@ -0,0 +1,34 @@
+package com.yonge.cooleshow.student.controller.coupon;
+
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.student.io.request.CouponInfoVO;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * 优惠券信息
+ * Created by Eric.Shang on 2022/9/2.
+ */
+@Controller
+@RequestMapping("/couponInfo")
+@Api(value = "优惠券信息", tags = "优惠券信息")
+public class CouponInfoController extends BaseController {
+
+    /**
+     * 优惠券信息
+     * @param request CouponInfoVO.RequestInfo
+     * @return HttpResponseResult<PageInfo<CouponInfoVO.ResponseInfo>>
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询优惠券分页", notes = "传入CouponInfoVO.PageRequest")
+    public HttpResponseResult<PageInfo<CouponInfoVO.CouponPageInfo>> queryCouponPageInfo(@RequestBody CouponInfoVO.PageRequest request) {
+
+        return null;
+    }
+}

+ 89 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/io/request/CouponInfoVO.java

@@ -0,0 +1,89 @@
+package com.yonge.cooleshow.student.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 优惠券信息
+ * Created by Eric.Shang on 2022/9/2.
+ */
+public class CouponInfoVO {
+
+    /**
+     * 优惠券分页请求信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "优惠券信息分页请求", description = "优惠券信息分页")
+    public static class PageRequest extends QueryInfo {
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private String clientType;
+
+        @ApiModelProperty("优惠券类型: FULL_DISCOUNT(满减券) VOUCHER(代金券) ")
+        private String couponType;
+
+        @ApiModelProperty("使用状态")
+        private String useState;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+    }
+
+    /**
+     * 优惠券分页响应数据
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "优惠券信息分页信息", description = "优惠券信息分页信息")
+    public static class CouponPageInfo implements Serializable {
+
+        @ApiModelProperty("优惠券ID")
+        private Long id;
+
+        @ApiModelProperty("优惠券名称")
+        private String name;
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private String clientType;
+
+        @ApiModelProperty("优惠券类型: FULL_DISCOUNT(满减券) VOUCHER(代金券) ")
+        private String couponType;
+
+        @ApiModelProperty("使用门槛")
+        private BigDecimal useLimit;
+
+        @ApiModelProperty("优惠金额")
+        private BigDecimal discountPrice;
+
+        @ApiModelProperty("用户ID")
+        private Long userId;
+
+        @ApiModelProperty("优惠券ID")
+        private Long couponId;
+
+        @ApiModelProperty("使用状态: EXPIRED(已失效) USABLE(可使用) USED(已使用) ")
+        private String useState;
+
+        @ApiModelProperty("使用时间")
+        private Long useTime;
+
+        @ApiModelProperty("生效时间")
+        private Long startTime;
+
+        @ApiModelProperty("失效时间")
+        private Long endTime;
+    }
+
+}

+ 1 - 1
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/TeacherApplication.java

@@ -19,7 +19,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @SpringBootApplication
 @EnableDiscoveryClient
 @EnableFeignClients("com.yonge.cooleshow")
-@MapperScan(basePackages = {"com.yonge.cooleshow.biz.dal.dao", "com.yonge.toolset.payment.core.dao"})
+@MapperScan(basePackages = {"com.yonge.cooleshow.biz.dal.dao", "com.yonge.cooleshow.biz.dal.mapper", "com.yonge.toolset.payment.core.dao"})
 @ComponentScan(basePackages = {"com.yonge.cooleshow","com.yonge.toolset"})
 @Configuration
 @EnableSwagger2Doc

+ 34 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/coupon/CouponInfoController.java

@@ -0,0 +1,34 @@
+package com.yonge.cooleshow.teacher.controller.coupon;
+
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.teacher.io.request.CouponInfoVO;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * 优惠券信息
+ * Created by Eric.Shang on 2022/9/2.
+ */
+@Controller
+@RequestMapping("/couponInfo")
+@Api(value = "优惠券信息", tags = "优惠券信息")
+public class CouponInfoController extends BaseController {
+
+    /**
+     * 优惠券信息
+     * @param request CouponInfoVO.RequestInfo
+     * @return HttpResponseResult<PageInfo<CouponInfoVO.ResponseInfo>>
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询优惠券分页", notes = "传入CouponInfoVO.PageRequest")
+    public HttpResponseResult<PageInfo<CouponInfoVO.CouponPageInfo>> queryCouponPageInfo(@RequestBody CouponInfoVO.PageRequest request) {
+
+        return null;
+    }
+}

+ 89 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/io/request/CouponInfoVO.java

@@ -0,0 +1,89 @@
+package com.yonge.cooleshow.teacher.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 优惠券信息
+ * Created by Eric.Shang on 2022/9/2.
+ */
+public class CouponInfoVO {
+
+    /**
+     * 优惠券分页请求信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "优惠券信息分页请求", description = "优惠券信息分页")
+    public static class PageRequest extends QueryInfo {
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private String clientType;
+
+        @ApiModelProperty("优惠券类型: FULL_DISCOUNT(满减券) VOUCHER(代金券) ")
+        private String couponType;
+
+        @ApiModelProperty("使用状态")
+        private String useState;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+    }
+
+    /**
+     * 优惠券分页响应数据
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "优惠券信息分页信息", description = "优惠券信息分页信息")
+    public static class CouponPageInfo implements Serializable {
+
+        @ApiModelProperty("优惠券ID")
+        private Long id;
+
+        @ApiModelProperty("优惠券名称")
+        private String name;
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private String clientType;
+
+        @ApiModelProperty("优惠券类型: FULL_DISCOUNT(满减券) VOUCHER(代金券) ")
+        private String couponType;
+
+        @ApiModelProperty("使用门槛")
+        private BigDecimal useLimit;
+
+        @ApiModelProperty("优惠金额")
+        private BigDecimal discountPrice;
+
+        @ApiModelProperty("用户ID")
+        private Long userId;
+
+        @ApiModelProperty("优惠券ID")
+        private Long couponId;
+
+        @ApiModelProperty("使用状态: EXPIRED(已失效) USABLE(可使用) USED(已使用) ")
+        private String useState;
+
+        @ApiModelProperty("使用时间")
+        private Long useTime;
+
+        @ApiModelProperty("生效时间")
+        private Long startTime;
+
+        @ApiModelProperty("失效时间")
+        private Long endTime;
+    }
+
+}

+ 1 - 1
cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/WebsiteApplication.java

@@ -17,7 +17,7 @@ import org.springframework.context.annotation.Configuration;
 @SpringBootApplication
 @EnableDiscoveryClient
 @EnableFeignClients("com.yonge.cooleshow")
-@MapperScan(basePackages = {"com.yonge.cooleshow.biz.dal.dao", "com.yonge.toolset.payment.core.dao"})
+@MapperScan(basePackages = {"com.yonge.cooleshow.biz.dal.dao", "com.yonge.cooleshow.biz.dal.mapper", "com.yonge.toolset.payment.core.dao"})
 @ComponentScan(basePackages = {"com.yonge.cooleshow","com.yonge.toolset"})
 @Configuration
 @EnableSwagger2Doc