Przeglądaj źródła

Merge remote-tracking branch 'origin/saas' into saas

zouxuan 3 lat temu
rodzic
commit
a41c88322c
18 zmienionych plików z 888 dodań i 241 usunięć
  1. 27 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysCouponIssueRecordDao.java
  2. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SysCouponCodeDto.java
  3. 29 3
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysCouponCode.java
  4. 144 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysCouponIssueRecord.java
  5. 3 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/CouponDetailTypeEnum.java
  6. 13 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/SysCouponCodeQueryInfo.java
  7. 64 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/vo/CouponIssueRecordVo.java
  8. 15 10
      mec-biz/src/main/java/com/ym/mec/biz/service/SysCouponCodeService.java
  9. 26 0
      mec-biz/src/main/java/com/ym/mec/biz/service/SysCouponIssueRecordService.java
  10. 2 2
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MemberRankSettingServiceImpl.java
  11. 220 181
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysCouponCodeServiceImpl.java
  12. 131 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysCouponIssueRecordServiceImpl.java
  13. 18 4
      mec-biz/src/main/resources/config/mybatis/SysCouponCodeMapper.xml
  14. 76 0
      mec-biz/src/main/resources/config/mybatis/SysCouponIssueRecordMapper.xml
  15. 6 2
      mec-common/common-core/src/main/java/com/ym/mec/common/page/PageUtil.java
  16. 31 0
      mec-common/common-core/src/main/java/com/ym/mec/common/page/WrapperUtil.java
  17. 70 36
      mec-student/src/main/java/com/ym/mec/student/controller/SysCouponCodeController.java
  18. 2 2
      mec-web/src/main/java/com/ym/mec/web/controller/SysCouponController.java

+ 27 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysCouponIssueRecordDao.java

@@ -0,0 +1,27 @@
+package com.ym.mec.biz.dal.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ym.mec.biz.dal.entity.SysCouponIssueRecord;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 优惠券发放记录(SysCouponIssueRecord)表数据库访问层
+ *
+ * @author hgw
+ * @since 2021-12-29 20:25:21
+ */
+public interface SysCouponIssueRecordDao extends BaseMapper<SysCouponIssueRecord> {
+
+    int insertBatch(@Param("entities") List<SysCouponIssueRecord> entities);
+
+    <T> IPage<T> queryIssueDetail(Page<T> page, @Param("param") Map<String, Object> param);
+
+    <T> IPage<T> queryIssueRecord(Page<T> page, @Param("param") Map<String, Object> param);
+
+}
+

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SysCouponCodeDto.java

@@ -69,6 +69,9 @@ public class SysCouponCodeDto {
     @ApiModelProperty("使用截止日期")
     private java.util.Date useDeadlineDate;
 
+    @ApiModelProperty("发放类型 0手动领取 1手动发放 2交易获取")
+    private Integer issueType;
+
     public Integer getCouponCodeId() {
         return couponCodeId;
     }
@@ -220,4 +223,12 @@ public class SysCouponCodeDto {
     public void setUseDeadlineDate(Date useDeadlineDate) {
         this.useDeadlineDate = useDeadlineDate;
     }
+
+    public Integer getIssueType() {
+        return issueType;
+    }
+
+    public void setIssueType(Integer issueType) {
+        this.issueType = issueType;
+    }
 }

+ 29 - 3
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysCouponCode.java

@@ -35,7 +35,17 @@ public class SysCouponCode extends BaseEntity {
 	
 	/** 关联的订单号 */
 	private Long paymentOrderId;
-	
+
+    /**
+     * 发放记录id
+     */
+    private Integer issueId;
+
+    /**
+     *0手动领取  1手动发放 2交易获取
+     */
+    private Integer type;
+
 	/**  */
 	private java.util.Date createTime;
 	
@@ -113,8 +123,24 @@ public class SysCouponCode extends BaseEntity {
 	public Long getPaymentOrderId(){
 		return this.paymentOrderId;
 	}
-			
-	public void setCreateTime(java.util.Date createTime){
+
+    public Integer getIssueId() {
+        return issueId;
+    }
+
+    public void setIssueId(Integer issueId) {
+        this.issueId = issueId;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public void setType(Integer type) {
+        this.type = type;
+    }
+
+    public void setCreateTime(java.util.Date createTime){
 		this.createTime = createTime;
 	}
 	

+ 144 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysCouponIssueRecord.java

@@ -0,0 +1,144 @@
+package com.ym.mec.biz.dal.entity;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 优惠券发放记录(SysCouponIssueRecord)表实体类
+ *
+ * @author hgw
+ * @since 2021-12-29 20:25:21
+ */
+@ApiModel(value = "sys_coupon_issue_record-优惠券发放记录")
+public class SysCouponIssueRecord implements Serializable {
+    @TableId(value = "id_", type = IdType.AUTO)
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+
+    @TableField("tenant_id_")
+    @ApiModelProperty(value = "机构id")
+    private Integer tenantId;
+
+    @TableField("coupon_id_")
+    @ApiModelProperty(value = "优惠券id")
+    private Integer couponId;
+
+    @TableField("coupon_name_")
+    @ApiModelProperty(value = "优惠券名称")
+    private String couponName;
+
+    @TableField("num_")
+    @ApiModelProperty(value = "数量")
+    private Integer num;
+
+    @TableField("ops_")
+    @ApiModelProperty(value = "操作 0发放 1撤回")
+    private Integer ops;
+
+    @TableField("created_by_")
+    @ApiModelProperty(value = "创建人")
+    private Integer createdBy;
+
+    @TableField("created_time_")
+    @ApiModelProperty(value = "创建时间")
+    private Date createdTime;
+
+    @TableField("updated_by_")
+    @ApiModelProperty(value = "更新人")
+    private Integer updatedBy;
+
+    @TableField("updated_time_")
+    @ApiModelProperty(value = "更新时间")
+    private Date updatedTime;
+
+    private static final long serialVersionUID = 1L;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Integer tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public Integer getCouponId() {
+        return couponId;
+    }
+
+    public void setCouponId(Integer couponId) {
+        this.couponId = couponId;
+    }
+
+    public String getCouponName() {
+        return couponName;
+    }
+
+    public void setCouponName(String couponName) {
+        this.couponName = couponName;
+    }
+
+    public Integer getNum() {
+        return num;
+    }
+
+    public void setNum(Integer num) {
+        this.num = num;
+    }
+
+    public Integer getOps() {
+        return ops;
+    }
+
+    public void setOps(Integer ops) {
+        this.ops = ops;
+    }
+
+    public Integer getCreatedBy() {
+        return createdBy;
+    }
+
+    public void setCreatedBy(Integer createdBy) {
+        this.createdBy = createdBy;
+    }
+
+    public Date getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Date createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    public Integer getUpdatedBy() {
+        return updatedBy;
+    }
+
+    public void setUpdatedBy(Integer updatedBy) {
+        this.updatedBy = updatedBy;
+    }
+
+    public Date getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public void setUpdatedTime(Date updatedTime) {
+        this.updatedTime = updatedTime;
+    }
+
+}
+

+ 3 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/CouponDetailTypeEnum.java

@@ -25,7 +25,9 @@ public enum CouponDetailTypeEnum {
     //合奏课 = 合奏课 MIX、集训合奏课 TRAINING_MIX ,
     MIX("MIX", "合奏课"),
     //VIP = vip课 VIP +乐理课 THEORY_COURSE
-    VIP("VIP", "VIP");
+    VIP("VIP", "VIP"),
+    //全类都可以使用
+    FULLCOUPON("FULLCOUPON", "全类券");
 
     private String code;
 

+ 13 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/SysCouponCodeQueryInfo.java

@@ -18,6 +18,11 @@ public class SysCouponCodeQueryInfo extends QueryInfo {
 
     private Integer usageStatus;
 
+    /**
+     * 0手动领取 1手动发放 2有paymentOrderId属于订单送券,交易获取
+     */
+    private Integer issueType;
+
     public Integer getOrganId() {
         return organId;
     }
@@ -57,4 +62,12 @@ public class SysCouponCodeQueryInfo extends QueryInfo {
     public void setUsageStatus(Integer usageStatus) {
         this.usageStatus = usageStatus;
     }
+
+    public Integer getIssueType() {
+        return issueType;
+    }
+
+    public void setIssueType(Integer issueType) {
+        this.issueType = issueType;
+    }
 }

+ 64 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/vo/CouponIssueRecordVo.java

@@ -0,0 +1,64 @@
+package com.ym.mec.biz.dal.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author hgw
+ * Created by 2021-12-30
+ */
+public class CouponIssueRecordVo implements Serializable {
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    private String couponName;
+
+    private Integer num;
+
+    private String name;
+
+    private Integer ops;
+
+    public Date getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Date createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    public String getCouponName() {
+        return couponName;
+    }
+
+    public void setCouponName(String couponName) {
+        this.couponName = couponName;
+    }
+
+    public Integer getNum() {
+        return num;
+    }
+
+    public void setNum(Integer num) {
+        this.num = num;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getOps() {
+        return ops;
+    }
+
+    public void setOps(Integer ops) {
+        this.ops = ops;
+    }
+}

+ 15 - 10
mec-biz/src/main/java/com/ym/mec/biz/service/SysCouponCodeService.java

@@ -15,29 +15,31 @@ import java.util.List;
 public interface SysCouponCodeService extends BaseService<Long, SysCouponCode> {
 
     /**
+     * @param userId:         用户编号
+     * @param couponId:       优惠券编号
+     * @param paymentOrderId: 订单编号
+     * @param exchangeNum:    兑换数量
+     * @return boolean
      * @describe 兑换优惠券
      * @author Joburgess
      * @date 2021/9/8 0008
-     * @param userId: 用户编号
-     * @param couponId: 优惠券编号
-     * @param paymentOrderId: 订单编号
-     * @param exchangeNum: 兑换数量
-     * @return boolean
      */
-    boolean exchangeCoupon(Integer userId, Integer couponId, Long paymentOrderId, Integer exchangeNum);
+    boolean exchangeCoupon(Integer userId, Integer couponId, Long paymentOrderId, Integer exchangeNum, int type,Integer issueId);
+
     boolean exchangeCouponTest(Integer userId, Integer couponId, Long paymentOrderId, Integer exchangeNum);
 
     /**
+     * @param queryInfo:
+     * @return com.ym.mec.common.page.PageInfo<com.ym.mec.biz.dal.dto.SysCouponCodeDto>
      * @describe 优惠券领取列表
      * @author Joburgess
      * @date 2021/9/8 0008
-     * @param queryInfo:
-     * @return com.ym.mec.common.page.PageInfo<com.ym.mec.biz.dal.dto.SysCouponCodeDto>
      */
     PageInfo<SysCouponCodeDto> querySysCouponUseList(SysCouponCodeQueryInfo queryInfo);
 
     /**
      * 获取优惠券跑马灯
+     *
      * @param queryInfo
      * @return
      */
@@ -45,6 +47,7 @@ public interface SysCouponCodeService extends BaseService<Long, SysCouponCode> {
 
     /**
      * 获取用户优惠券列表
+     *
      * @param amount
      * @param userId
      * @return
@@ -53,17 +56,19 @@ public interface SysCouponCodeService extends BaseService<Long, SysCouponCode> {
 
     /**
      * 使用优惠券
+     *
      * @param couponIdList
      * @param amount
-     * @param useFlag 是否消耗优惠券
+     * @param useFlag      是否消耗优惠券
      * @return
      */
-    StudentPaymentOrder use(List<Integer> couponIdList, BigDecimal amount,Boolean useFlag);
+    StudentPaymentOrder use(List<Integer> couponIdList, BigDecimal amount, Boolean useFlag);
 
     List<SysCouponCodeDto> findByIdList(List<Integer> couponIdList);
 
     /**
      * 退优惠券
+     *
      * @param couponCodeId
      */
     void quit(String couponCodeId);

+ 26 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/SysCouponIssueRecordService.java

@@ -0,0 +1,26 @@
+package com.ym.mec.biz.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ym.mec.biz.dal.entity.SysCouponIssueRecord;
+import com.ym.mec.biz.dal.vo.CouponIssueRecordVo;
+import com.ym.mec.common.page.PageInfo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 优惠券发放记录(SysCouponIssueRecord)表服务接口
+ *
+ * @author hgw
+ * @since 2021-12-29 20:26:11
+ */
+public interface SysCouponIssueRecordService extends IService<SysCouponIssueRecord> {
+
+    void issueCoupon(Map<String, Object> param);
+
+    int revokeCoupon(Integer couponId);
+
+    PageInfo<?> queryIssueDetail(Map<String, Object> param);
+    PageInfo<CouponIssueRecordVo> queryIssueRecord(Map<String, Object> param);
+}
+

+ 2 - 2
mec-biz/src/main/java/com/ym/mec/biz/service/impl/MemberRankSettingServiceImpl.java

@@ -439,10 +439,10 @@ public class MemberRankSettingServiceImpl extends BaseServiceImpl<Integer, Membe
 		if(activeRemark.equals(202109)){
 			switch (remark){
 				case "2赠1":
-					sysCouponCodeService.exchangeCoupon(cloudTeacherOrder.getStudentId(),couponId,cloudTeacherOrder.getOrderId(),3);
+					sysCouponCodeService.exchangeCoupon(cloudTeacherOrder.getStudentId(),couponId,cloudTeacherOrder.getOrderId(),3,2,null);
 					break;
 				case "3赠2":
-					sysCouponCodeService.exchangeCoupon(cloudTeacherOrder.getStudentId(),couponId,cloudTeacherOrder.getOrderId(),6);
+					sysCouponCodeService.exchangeCoupon(cloudTeacherOrder.getStudentId(),couponId,cloudTeacherOrder.getOrderId(),6,2,null);
 					break;
 			}
 		}

+ 220 - 181
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysCouponCodeServiceImpl.java

@@ -16,8 +16,10 @@ import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.page.QueryInfo;
+import com.ym.mec.common.page.WrapperUtil;
 import com.ym.mec.common.service.IdGeneratorService;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
+import com.ym.mec.common.tenant.TenantContextHolder;
 import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
 import org.apache.commons.lang3.StringUtils;
@@ -25,7 +27,6 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Isolation;
-import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
@@ -33,197 +34,235 @@ import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 
 @Service
-public class SysCouponCodeServiceImpl extends BaseServiceImpl<Long, SysCouponCode>  implements SysCouponCodeService {
-	
-	@Autowired
-	private SysCouponCodeDao sysCouponCodeDao;
-	@Autowired
-	private SysCouponService sysCouponService;
-	@Autowired
-	private SysCouponDao sysCouponDao;
-	@Autowired
-	private IdGeneratorService idGeneratorService;
-	@Autowired
-	private StudentPaymentOrderDao studentPaymentOrderDao;
-
-	@Override
-	public BaseDAO<Long, SysCouponCode> getDAO() {
-		return sysCouponCodeDao;
-	}
-
-	@Override
-	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
-	public boolean exchangeCouponTest(Integer userId, Integer couponId, Long paymentOrderId, Integer exchangeNum) {
-		return exchangeCoupon(userId, couponId, paymentOrderId, exchangeNum);
-	}
-
-	@Override
-	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
-	public boolean exchangeCoupon(Integer userId, Integer couponId, Long paymentOrderId, Integer exchangeNum) {
-		if(Objects.isNull(userId)||Objects.isNull(couponId)||Objects.isNull(paymentOrderId)||Objects.isNull(exchangeNum)){
-			throw new BizException("领取失败");
-		}
-		if(exchangeNum<=0){
-			return true;
-		}
-		SysCoupon sysCoupon = sysCouponDao.lockCoupon(couponId);
-		Date now = new Date();
-		//如果优惠券不存在,或者已停用,或者不在领取有效期内,或者已消耗完,则此优惠券无效
-		boolean invalid = Objects.isNull(sysCoupon)||0==sysCoupon.getStatus()||now.compareTo(sysCoupon.getStartDate())<0||now.compareTo(sysCoupon.getEndDate())>0;
-		invalid = invalid || sysCoupon.getStockCount()!=-1&&sysCoupon.getConsumeNum()>=sysCoupon.getStockCount()&&(sysCoupon.getStockCount()-sysCoupon.getConsumeNum()<exchangeNum);
-		if(invalid){
-			throw new BizException("无效优惠券");
-		}
-		StudentPaymentOrder studentPaymentOrder = studentPaymentOrderDao.get(paymentOrderId);
-		if(Objects.isNull(studentPaymentOrder)){
-			throw new BizException("无效订单");
-		}
-		if(sysCoupon.getLimitExchangeNum()!=-1){
-			int userUserNum = sysCouponCodeDao.countWithUserAndCoupon(userId, couponId);
-			invalid = (userUserNum + exchangeNum)>sysCoupon.getLimitExchangeNum();
-		}
-		//如果用户使用数量超过优惠券限制则领取无效
-		if(invalid){
-			throw new BizException("当前优惠券最多可领取{}次", sysCoupon.getLimitExchangeNum());
-		}
-		SysCouponCode sysCouponCode = new SysCouponCode();
-		sysCouponCode.setUserId(userId);
-		sysCouponCode.setCouponId(couponId);
-		sysCouponCode.setPaymentOrderId(paymentOrderId);
-		sysCouponCode.setUsageStatus(0);
-		switch (sysCoupon.getEffectiveType()){
-			case DAYS:
-				sysCouponCode.setUseStartDate(now);
-				sysCouponCode.setUseDeadlineDate(DateUtil.addDays(now, sysCoupon.getDeadline()));
-				break;
-			case TIME_BUCKET:
-				sysCouponCode.setUseStartDate(sysCoupon.getEffectiveStartTime());
-				sysCouponCode.setUseDeadlineDate(sysCoupon.getEffectiveExpireTime());
-				break;
-			default:
-				throw new BizException("无效优惠券", sysCoupon.getLimitExchangeNum());
-		}
-		List<SysCouponCode> couponCodes = new ArrayList<>();
-		for (int i = 0; i < exchangeNum; i++) {
-			SysCouponCode couponCode = new SysCouponCode();
-			BeanUtils.copyProperties(sysCouponCode, couponCode);
-			couponCode.setCode(String.valueOf(idGeneratorService.generatorId("coupon")));
-			couponCodes.add(couponCode);
-		}
-		sysCouponCodeDao.batchInsert(couponCodes);
-		sysCoupon.setConsumeNum(new AtomicInteger(sysCoupon.getConsumeNum()).addAndGet(exchangeNum));
-		if(sysCoupon.getWarningStatus()==0&&sysCoupon.getStockCount()!=-1&&sysCoupon.getStockCount()-sysCoupon.getConsumeNum()<sysCoupon.getWarningStockNum()){
-			sysCouponService.stockWarning(sysCoupon.getId(), sysCoupon.getName());
-			sysCoupon.setWarningStatus(1);
-		}
-		sysCouponDao.update(sysCoupon);
-		return true;
-	}
-
-	@Override
-	public PageInfo<SysCouponCodeDto> querySysCouponUseList(SysCouponCodeQueryInfo queryInfo) {
-		PageInfo<SysCouponCodeDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
-		Map<String, Object> params = new HashMap<String, Object>();
-		MapUtil.populateMap(params, queryInfo);
-
-		List<SysCouponCodeDto> dataList = new ArrayList<>();
-		int count = sysCouponCodeDao.countSysCouponUseList(params);
-		if (count > 0) {
-			pageInfo.setTotal(count);
-			params.put("offset", pageInfo.getOffset());
-			dataList = sysCouponCodeDao.querySysCouponUseList(params);
-		}
-		pageInfo.setRows(dataList);
-		return pageInfo;
-	}
+public class SysCouponCodeServiceImpl extends BaseServiceImpl<Long, SysCouponCode> implements SysCouponCodeService {
+
+    @Autowired
+    private SysCouponCodeDao sysCouponCodeDao;
+    @Autowired
+    private SysCouponService sysCouponService;
+    @Autowired
+    private SysCouponDao sysCouponDao;
+    @Autowired
+    private IdGeneratorService idGeneratorService;
+    @Autowired
+    private StudentPaymentOrderDao studentPaymentOrderDao;
+
+    @Override
+    public BaseDAO<Long, SysCouponCode> getDAO() {
+        return sysCouponCodeDao;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
+    public boolean exchangeCouponTest(Integer userId, Integer couponId, Long paymentOrderId, Integer exchangeNum) {
+        return exchangeCoupon(userId, couponId, paymentOrderId, exchangeNum, 0, null);
+    }
+
+    /**
+     * 兑换优惠券
+     *
+     * @param userId:         用户编号
+     * @param couponId:       优惠券编号
+     * @param paymentOrderId: 订单编号
+     * @param exchangeNum:    兑换数量
+     * @param type:          2有paymentOrderId属于订单送券,交易获取,0手动领取 1手动发放
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
+    public boolean exchangeCoupon(Integer userId, Integer couponId, Long paymentOrderId, Integer exchangeNum, int type, Integer issueId) {
+        //检查参数
+        SysCouponCode sysCouponCode = checkParam(userId, couponId, paymentOrderId, exchangeNum, type, issueId);
+        //兑换数量0或者比0小直接返回
+        if (exchangeNum <= 0) {
+            return true;
+        }
+        //校验优惠券是否合法
+        SysCoupon sysCoupon = checkCoupon(userId, couponId, exchangeNum);
+        //写入数据
+        opsCoupon(userId, sysCouponCode, couponId, exchangeNum, sysCoupon);
+        return true;
+    }
+
+    private SysCouponCode checkParam(Integer userId, Integer couponId, Long paymentOrderId, Integer exchangeNum, int type, Integer issueId) {
+        SysCouponCode sysCouponCode = new SysCouponCode();
+        if (type == 2 && WrapperUtil.checkObj(userId, couponId, paymentOrderId, exchangeNum)) {
+            StudentPaymentOrder studentPaymentOrder = studentPaymentOrderDao.get(paymentOrderId);
+            if (Objects.isNull(studentPaymentOrder)) {
+                throw new BizException("无效订单");
+            }
+            sysCouponCode.setPaymentOrderId(paymentOrderId);
+        } else if ((type == 0 || type == 1) && WrapperUtil.checkObj(userId, couponId, issueId, exchangeNum)) {
+            sysCouponCode.setIssueId(issueId);
+        } else {
+            throw new BizException("领取失败");
+        }
+        sysCouponCode.setType(type);
+        return sysCouponCode;
+    }
+
+    private SysCoupon checkCoupon(Integer userId, Integer couponId, Integer exchangeNum) {
+        //锁定优惠券
+        SysCoupon sysCoupon = sysCouponDao.lockCoupon(couponId);
+
+        Date now = new Date();
+        //如果优惠券不存在,或者已停用,或者不在领取有效期内,或者已消耗完,则此优惠券无效
+        boolean invalid = Objects.isNull(sysCoupon) || 0 == sysCoupon.getStatus() || now.compareTo(sysCoupon.getStartDate()) < 0 || now.compareTo(sysCoupon.getEndDate()) > 0;
+        invalid = invalid || sysCoupon.getStockCount() != -1 && sysCoupon.getConsumeNum() >= sysCoupon.getStockCount() && (sysCoupon.getStockCount() - sysCoupon.getConsumeNum() < exchangeNum);
+        if (invalid) {
+            throw new BizException("无效优惠券");
+        }
+        //校验兑换的最大次数
+        if (sysCoupon.getLimitExchangeNum() != -1) {
+            int userUserNum = sysCouponCodeDao.countWithUserAndCoupon(userId, couponId);
+            invalid = (userUserNum + exchangeNum) > sysCoupon.getLimitExchangeNum();
+        }
+        //如果用户使用数量超过优惠券限制则领取无效
+        if (invalid) {
+            throw new BizException("当前优惠券最多可领取{}次", sysCoupon.getLimitExchangeNum());
+        }
+        return sysCoupon;
+    }
+
+    private void opsCoupon(Integer userId, SysCouponCode sysCouponCode, Integer couponId, Integer exchangeNum, SysCoupon sysCoupon) {
+        Integer tenantId = TenantContextHolder.getTenantId();
+        Date now = new Date();
+        sysCouponCode.setUserId(userId);
+        sysCouponCode.setCouponId(couponId);
+        sysCouponCode.setUsageStatus(0);
+        sysCouponCode.setTenantId(tenantId);
+        switch (sysCoupon.getEffectiveType()) {
+            case DAYS:
+                sysCouponCode.setUseStartDate(now);
+                sysCouponCode.setUseDeadlineDate(DateUtil.addDays(now, sysCoupon.getDeadline()));
+                break;
+            case TIME_BUCKET:
+                sysCouponCode.setUseStartDate(sysCoupon.getEffectiveStartTime());
+                sysCouponCode.setUseDeadlineDate(sysCoupon.getEffectiveExpireTime());
+                break;
+            default:
+                throw new BizException("无效优惠券", sysCoupon.getLimitExchangeNum());
+        }
+        List<SysCouponCode> couponCodes = new ArrayList<>();
+        for (int i = 0; i < exchangeNum; i++) {
+            SysCouponCode couponCode = new SysCouponCode();
+            BeanUtils.copyProperties(sysCouponCode, couponCode);
+            couponCode.setCode(String.valueOf(idGeneratorService.generatorId("coupon")));
+            couponCode.setTenantId(tenantId);
+            couponCodes.add(couponCode);
+        }
+        sysCouponCodeDao.batchInsert(couponCodes);
+        sysCoupon.setConsumeNum(new AtomicInteger(sysCoupon.getConsumeNum()).addAndGet(exchangeNum));
+        if (sysCoupon.getWarningStatus() == 0 && sysCoupon.getStockCount() != -1 && sysCoupon.getStockCount() - sysCoupon.getConsumeNum() < sysCoupon.getWarningStockNum()) {
+            sysCouponService.stockWarning(sysCoupon.getId(), sysCoupon.getName());
+            sysCoupon.setWarningStatus(1);
+        }
+        sysCouponDao.update(sysCoupon);
+    }
+
+    @Override
+    public PageInfo<SysCouponCodeDto> querySysCouponUseList(SysCouponCodeQueryInfo queryInfo) {
+        PageInfo<SysCouponCodeDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+        Map<String, Object> params = new HashMap<String, Object>();
+        MapUtil.populateMap(params, queryInfo);
+
+        List<SysCouponCodeDto> dataList = new ArrayList<>();
+        int count = sysCouponCodeDao.countSysCouponUseList(params);
+        if (count > 0) {
+            pageInfo.setTotal(count);
+            params.put("offset", pageInfo.getOffset());
+            dataList = sysCouponCodeDao.querySysCouponUseList(params);
+        }
+        pageInfo.setRows(dataList);
+        return pageInfo;
+    }
 
     @Override
     public PageInfo<HorseRaceLampDto> queryHorseRaceLampDtoList(QueryInfo queryInfo) {
-		PageInfo<HorseRaceLampDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
-		Map<String, Object> params = new HashMap<String, Object>();
-		MapUtil.populateMap(params, queryInfo);
-
-		List<HorseRaceLampDto> dataList = new ArrayList<>();
-		int count = sysCouponCodeDao.countHorseRaceLampDtoList(params);
-		if (count > 0) {
-			pageInfo.setTotal(count);
-			params.put("offset", pageInfo.getOffset());
-			dataList = sysCouponCodeDao.queryHorseRaceLampDtoList(params);
-		}
-		pageInfo.setRows(dataList);
-		return pageInfo;
+        PageInfo<HorseRaceLampDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+        Map<String, Object> params = new HashMap<String, Object>();
+        MapUtil.populateMap(params, queryInfo);
+
+        List<HorseRaceLampDto> dataList = new ArrayList<>();
+        int count = sysCouponCodeDao.countHorseRaceLampDtoList(params);
+        if (count > 0) {
+            pageInfo.setTotal(count);
+            params.put("offset", pageInfo.getOffset());
+            dataList = sysCouponCodeDao.queryHorseRaceLampDtoList(params);
+        }
+        pageInfo.setRows(dataList);
+        return pageInfo;
     }
 
     @Override
     public List<SysCouponCode> queryCouponPage(BigDecimal amount, Integer userId) {
 
-		return null;
+        return null;
     }
 
     @Override
-	@Transactional(rollbackFor = Exception.class)
-    public StudentPaymentOrder use(List<Integer> couponIdList, BigDecimal amount,Boolean useFlag) {
-		StudentPaymentOrder studentPaymentOrder = new StudentPaymentOrder();
-		if(couponIdList != null && couponIdList.size() > 0){
-			Date date = new Date();
-			List<SysCouponCodeDto> couponCodeDtoList = sysCouponCodeDao.findByIdList(couponIdList);
-			if(couponIdList.size() != couponCodeDtoList.size()){
-				throw new BizException("操作失败:优惠券数据异常");
-			}
-			BigDecimal fullAmount = BigDecimal.ZERO;
-			BigDecimal faceAmount = BigDecimal.ZERO;
-
-			for (SysCouponCodeDto sysCouponCodeDto : couponCodeDtoList) {
-				if(sysCouponCodeDto.getUsageStatus() == 1){
-					throw new BizException("操作失败:优惠券已使用");
-				}
-				if(sysCouponCodeDto.getUseStartDate().after(date)){
-					throw new BizException("操作失败:不在优惠券使用期限");
-				}
-				if(date.after(sysCouponCodeDto.getUseDeadlineDate())){
-					throw new BizException("操作失败:优惠券已过期");
-				}
-				CouponTypeEnum couponType = sysCouponCodeDto.getCouponType();
-				switch (couponType){
-					case DISCOUNT:
-						throw new BizException("操作失败:暂不支持折扣劵");
-					case FULL_REDUCTION:
-						fullAmount = fullAmount.add(sysCouponCodeDto.getFullAmount());
-						faceAmount = faceAmount.add(sysCouponCodeDto.getFaceValue());
-						break;
-					default:
-						throw new BizException("操作失败:错误的优惠券类型");
-				}
-			}
-			if(amount.compareTo(fullAmount) < 0){
-				throw new BizException("操作失败:当前消费金额不满足优惠券满减条件");
-			}
-			amount = amount.subtract(faceAmount);
-			if (amount.signum() < 0) {
-				amount = BigDecimal.ZERO;
-			}
-			//使用优惠券
-			if(useFlag){
-				sysCouponCodeDao.use(couponIdList);
-			}
-			studentPaymentOrder.setCouponCodeId(StringUtils.join(couponIdList,","));
-			studentPaymentOrder.setCouponRemitFee(faceAmount);
-		}
-		studentPaymentOrder.setExpectAmount(amount);
-		studentPaymentOrder.setActualAmount(amount);
-		return studentPaymentOrder;
+    @Transactional(rollbackFor = Exception.class)
+    public StudentPaymentOrder use(List<Integer> couponIdList, BigDecimal amount, Boolean useFlag) {
+        StudentPaymentOrder studentPaymentOrder = new StudentPaymentOrder();
+        if (couponIdList != null && couponIdList.size() > 0) {
+            Date date = new Date();
+            List<SysCouponCodeDto> couponCodeDtoList = sysCouponCodeDao.findByIdList(couponIdList);
+            if (couponIdList.size() != couponCodeDtoList.size()) {
+                throw new BizException("操作失败:优惠券数据异常");
+            }
+            BigDecimal fullAmount = BigDecimal.ZERO;
+            BigDecimal faceAmount = BigDecimal.ZERO;
+
+            for (SysCouponCodeDto sysCouponCodeDto : couponCodeDtoList) {
+                if (sysCouponCodeDto.getUsageStatus() == 1) {
+                    throw new BizException("操作失败:优惠券已使用");
+                }
+                if (sysCouponCodeDto.getUseStartDate().after(date)) {
+                    throw new BizException("操作失败:不在优惠券使用期限");
+                }
+                if (date.after(sysCouponCodeDto.getUseDeadlineDate())) {
+                    throw new BizException("操作失败:优惠券已过期");
+                }
+                CouponTypeEnum couponType = sysCouponCodeDto.getCouponType();
+                switch (couponType) {
+                    case DISCOUNT:
+                        throw new BizException("操作失败:暂不支持折扣劵");
+                    case FULL_REDUCTION:
+                        fullAmount = fullAmount.add(sysCouponCodeDto.getFullAmount());
+                        faceAmount = faceAmount.add(sysCouponCodeDto.getFaceValue());
+                        break;
+                    default:
+                        throw new BizException("操作失败:错误的优惠券类型");
+                }
+            }
+            if (amount.compareTo(fullAmount) < 0) {
+                throw new BizException("操作失败:当前消费金额不满足优惠券满减条件");
+            }
+            amount = amount.subtract(faceAmount);
+            if (amount.signum() < 0) {
+                amount = BigDecimal.ZERO;
+            }
+            //使用优惠券
+            if (useFlag) {
+                sysCouponCodeDao.use(couponIdList);
+            }
+            studentPaymentOrder.setCouponCodeId(StringUtils.join(couponIdList, ","));
+            studentPaymentOrder.setCouponRemitFee(faceAmount);
+        }
+        studentPaymentOrder.setExpectAmount(amount);
+        studentPaymentOrder.setActualAmount(amount);
+        return studentPaymentOrder;
     }
 
-	@Override
-	public List<SysCouponCodeDto> findByIdList(List<Integer> couponIdList) {
-		return sysCouponCodeDao.findByIdList(couponIdList);
-	}
-
-	@Override
-	public void quit(String couponCodeId) {
-		if(StringUtils.isEmpty(couponCodeId)){
-			return;
-		}
-		sysCouponCodeDao.quit(couponCodeId);
-	}
+    @Override
+    public List<SysCouponCodeDto> findByIdList(List<Integer> couponIdList) {
+        return sysCouponCodeDao.findByIdList(couponIdList);
+    }
+
+    @Override
+    public void quit(String couponCodeId) {
+        if (StringUtils.isEmpty(couponCodeId)) {
+            return;
+        }
+        sysCouponCodeDao.quit(couponCodeId);
+    }
 }

+ 131 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysCouponIssueRecordServiceImpl.java

@@ -0,0 +1,131 @@
+package com.ym.mec.biz.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dao.SysCouponIssueRecordDao;
+import com.ym.mec.biz.dal.entity.SysCoupon;
+import com.ym.mec.biz.dal.entity.SysCouponIssueRecord;
+import com.ym.mec.biz.dal.vo.CouponIssueRecordVo;
+import com.ym.mec.biz.service.SysCouponCodeService;
+import com.ym.mec.biz.service.SysCouponIssueRecordService;
+import com.ym.mec.biz.service.SysCouponService;
+import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.PageUtil;
+import com.ym.mec.common.page.WrapperUtil;
+import com.ym.mec.common.tenant.TenantContextHolder;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * 优惠券发放记录(SysCouponIssueRecord)表服务实现类
+ *
+ * @author hgw
+ * @since 2021-12-29 20:26:12
+ */
+@Service("sysCouponIssueRecordService")
+public class SysCouponIssueRecordServiceImpl extends ServiceImpl<SysCouponIssueRecordDao, SysCouponIssueRecord> implements SysCouponIssueRecordService {
+
+    private final static Logger logger = LoggerFactory.getLogger(SysCouponIssueRecordServiceImpl.class);
+
+    @Autowired
+    private SysCouponCodeService sysCouponCodeService;
+    @Autowired
+    private SysCouponService sysCouponService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private RedissonClient redissonClient;
+
+    /**
+     * 手动发优惠券
+     *
+     * @param param studentIds 学生id
+     * @param param couponId   优惠券id
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void issueCoupon(Map<String, Object> param) {
+        String ids = WrapperUtil.toStr(param, "studentIds", "请选择学生!");
+        List<String> studentIds = WrapperUtil.toList(ids);
+        //校验优惠券信息 是否存在 是否是启用状态
+        SysCoupon sysCoupon = Optional.ofNullable(param.get("couponId"))
+                .map(String::valueOf)
+                .map(Integer::parseInt)
+                .map(sysCouponService::get)
+                .filter(c -> c.getStatus() == 1)
+                .orElseThrow(() -> new BizException("查询不到优惠券!"));
+
+        Integer tenantId = TenantContextHolder.getTenantId();
+
+        SysCouponIssueRecord record = new SysCouponIssueRecord();
+        record.setCouponId(sysCoupon.getId());
+        record.setCouponName(sysCoupon.getName());
+        record.setNum(studentIds.size());
+        record.setOps(0);
+        record.setTenantId(tenantId);
+        record.setCreatedBy(getUserId());
+        record.setCreatedTime(new Date());
+        this.save(record);
+
+        studentIds.forEach(id -> sysCouponCodeService.exchangeCoupon(Integer.parseInt(id), sysCoupon.getId(),
+                null, 1, 1, record.getId())
+        );
+
+    }
+
+    @Override
+    public int revokeCoupon(Integer id) {
+        List<SysCouponIssueRecord> issueRecords = this.list(new WrapperUtil<SysCouponIssueRecord>()
+                .hasEq("id_", id)
+                .hasEq("ops", 0)
+                .queryWrapper());
+        if (CollectionUtils.isEmpty(issueRecords)) {
+            throw new BizException("未查询到该优惠券的发放记录!");
+        }
+
+
+        return 0;
+    }
+
+    /**
+     * 查询发放记录
+     */
+    @Override
+    public PageInfo<CouponIssueRecordVo> queryIssueRecord(Map<String, Object> param) {
+        Page<CouponIssueRecordVo> pageInfo = PageUtil.getPageInfo(param);
+        pageInfo.setAsc("a.create_time_");
+        return PageUtil.pageInfo(baseMapper.queryIssueRecord(pageInfo, param));
+    }
+
+    /**
+     * 查询发放名单
+     */
+    @Override
+    public PageInfo<?> queryIssueDetail(Map<String, Object> param) {
+        Page<?> pageInfo = PageUtil.getPageInfo(param);
+        pageInfo.setAsc("scc.create_time_");
+        return PageUtil.pageInfo(baseMapper.queryIssueDetail(pageInfo, param));
+    }
+
+    private Integer getUserId() {
+        //修改机构基础信息
+        return Optional.ofNullable(sysUserFeignService.queryUserInfo())
+                .map(SysUser::getId)
+                .orElseThrow(() -> new BizException("用户信息获取失败,请刷新页面或者重新登录!"));
+    }
+
+}
+

+ 18 - 4
mec-biz/src/main/resources/config/mybatis/SysCouponCodeMapper.xml

@@ -16,6 +16,8 @@
 		<result column="use_start_date_" property="useStartDate" />
 		<result column="use_deadline_date_" property="useDeadlineDate" />
 		<result column="payment_order_id_" property="paymentOrderId" />
+		<result column="issue_id_" property="issueId" />
+		<result column="type_" property="type" />
 		<result column="create_time_" property="createTime" />
 		<result column="update_time_" property="updateTime" />
         <result column="tenant_id_" property="tenantId"/>
@@ -40,6 +42,7 @@
 		<result column="used_time_" property="usedTime"/>
 		<result column="use_start_date_" property="useStartDate"/>
 		<result column="use_deadline_date_" property="useDeadlineDate"/>
+		<result column="issueType" property="issueType"/>
 	</resultMap>
 
 	<!-- 根据主键查询一条记录 -->
@@ -60,18 +63,18 @@
 		</selectKey>
 		-->
 		INSERT INTO sys_coupon_code (coupon_id_,code_,usage_status_,user_id_,used_time_,use_start_date_,use_deadline_date_,
-		                             payment_order_id_,create_time_,update_time_,tenant_id_)
+		                             payment_order_id_,issue_id_,type_,create_time_,update_time_,tenant_id_)
 							 VALUES(#{couponId},#{code},#{usageStatus},#{userId},#{usedTime},#{useStartDate},#{useDeadlineDate},
-									#{paymentOrderId},NOW(),NOW(),#{tenantId})
+									#{paymentOrderId},#{issueId},#{type},NOW(),NOW(),#{tenantId})
 	</insert>
 
 	<insert id="batchInsert" parameterType="com.ym.mec.biz.dal.entity.SysCouponCode" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
 		INSERT INTO sys_coupon_code (coupon_id_,code_,usage_status_,user_id_,used_time_,use_start_date_,use_deadline_date_,
-		payment_order_id_,create_time_,update_time_,tenant_id_)
+		payment_order_id_,issue_id_,type_,create_time_,update_time_,tenant_id_)
 		VALUE
 		<foreach collection="couponCodes" item="couponCode" separator=",">
 			(#{couponCode.couponId},#{couponCode.code},#{couponCode.usageStatus},#{couponCode.userId},#{couponCode.usedTime},#{couponCode.useStartDate},#{couponCode.useDeadlineDate},
-			#{couponCode.paymentOrderId},NOW(),NOW(),#{tenantId})
+			#{couponCode.paymentOrderId},#{couponCode.issueId},#{couponCode.type},NOW(),NOW(),#{couponCode.tenantId})
 		</foreach>
 	</insert>
 
@@ -100,6 +103,12 @@
 			<if test="paymentOrderId != null">
 				payment_order_id_ = #{paymentOrderId},
 			</if>
+            <if test="issueId != null">
+                issue_id_ = #{issueId},
+            </if>
+            <if test="type != null">
+                type_ = #{type},
+            </if>
 			<if test="useDeadlineDate != null">
 				use_deadline_date_ = #{useDeadlineDate},
 			</if>
@@ -168,6 +177,9 @@
 			<if test="search!=null and search!=''">
 				AND (scc.user_id_=#{search} OR su.phone_=#{search} OR su.username_ LIKE CONCAT('%', #{search}, '%'))
 			</if>
+			<if test="issueType !=null">
+                AND scc.type_ = #{issueType}
+            </if>
 		</where>
 	</sql>
 
@@ -189,6 +201,7 @@
 			scc.use_start_date_,
 			scc.use_deadline_date_,
 			scc.used_time_,
+            scc.type_ as issueType,
 		    IF(scc.usage_status_ = 0 AND scc.use_deadline_date_ &lt; NOW(),2,scc.usage_status_) usage_status_
 		FROM sys_coupon_code scc
 			 LEFT JOIN sys_coupon sc ON scc.coupon_id_=sc.id_
@@ -245,6 +258,7 @@
 		scc.use_start_date_,
 		scc.use_deadline_date_,
 		scc.used_time_,
+		 scc.type_ as issueType,
 		IF(scc.usage_status_ = 0 AND scc.use_deadline_date_ &lt; NOW(),2,scc.usage_status_) usage_status_
 		FROM sys_coupon_code scc
 		LEFT JOIN sys_coupon sc ON scc.coupon_id_=sc.id_

+ 76 - 0
mec-biz/src/main/resources/config/mybatis/SysCouponIssueRecordMapper.xml

@@ -0,0 +1,76 @@
+<?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.ym.mec.biz.dal.dao.SysCouponIssueRecordDao">
+    <resultMap id="BaseResultMap" type="com.ym.mec.biz.dal.entity.SysCouponIssueRecord">
+        <id column="id_" jdbcType="INTEGER" property="id"/>
+        <result column="tenant_id_" jdbcType="INTEGER" property="tenantId"/>
+        <result column="coupon_id_" jdbcType="INTEGER" property="couponId"/>
+        <result column="coupon_name_" jdbcType="VARCHAR" property="couponName"/>
+        <result column="num_" jdbcType="INTEGER" property="num"/>
+        <result column="ops_" jdbcType="INTEGER" property="ops"/>
+        <result column="created_by_" jdbcType="INTEGER" property="createdBy"/>
+        <result column="created_time_" jdbcType="TIMESTAMP" property="createdTime"/>
+        <result column="updated_by_" jdbcType="INTEGER" property="updatedBy"/>
+        <result column="updated_time_" jdbcType="TIMESTAMP" property="updatedTime"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id_
+        , tenant_id_, coupon_id_, coupon_name_, num_, ops_, created_by_, created_time_, updated_by_, updated_time_
+    </sql>
+
+    <insert id="insertBatch" keyColumn="id_" keyProperty="id" useGeneratedKeys="true"
+            parameterType="com.ym.mec.biz.dal.entity.SysCouponIssueRecord">
+        insert into sys_coupon_issue_record(tenant_id_, coupon_id_, coupon_name_, num_, ops_, created_by_,
+        created_time_, updated_by_, updated_time_)
+        values
+        <foreach collection="entities" item="entity" separator=",">
+            (#{entity.tenantId}, #{entity.couponId}, #{entity.couponName}, #{entity.num}, #{entity.ops},
+            #{entity.createdBy}, #{entity.createdTime}, #{entity.updatedBy}, #{entity.updatedTime})
+        </foreach>
+    </insert>
+
+    <select id="queryIssueDetail" parameterType="map" resultType="map">
+        SELECT o.name_ as organName
+        , s.user_id_ as userId
+        , su.username_ as userName
+        , su.phone_ as phone
+        , sb.name_ as subjectName
+        , scc.usage_status_ as usageStatus
+        FROM student s
+        LEFT JOIN sys_user su ON su.id_ = s.user_id_
+        LEFT JOIN organization o ON o.id_ = su.organ_id_
+        LEFT JOIN subject sb ON sb.id_ = s.subject_id_list_
+        join sys_coupon_code scc on s.user_id_ = scc.user_id_
+        where s.tenant_id_ = #{param.tenantId}
+        <if test="param.issueId !=null">
+            and scc.issue_id_ = #{param.issueId}
+        </if>
+        <if test="param.organId !=null">
+            and o.id_ = #{param.organId}
+        </if>
+        <if test="param.subjectId !=null">
+            and sb.id_ = #{param.subjectId}
+        </if>
+        <if test="param.usageStatus !=null">
+            and scc.usage_status_ = #{param.usageStatus}
+        </if>
+    </select>
+
+    <select id="queryIssueRecord" parameterType="map" resultType="com.ym.mec.biz.dal.vo.CouponIssueRecordVo">
+        select a.created_time_ as createdTime,
+        a.coupon_name_ as couponName,
+        a.num_ as num,
+        u.real_name_ as `name`,
+        a.ops
+        from sys_coupon_issue_record as a
+        left join sys_user as u on a.created_by_ = u.id_
+        where a.tenant_id_ = #{param.tenantId}
+        <if test="param.couponId !=null">
+          and a.coupon_id_ =#{param.couponId}
+        </if>
+        <if test="param.search !=null">
+            and a.coupon_name_ like concat('%',#{param.search},'%')
+        </if>
+    </select>
+</mapper>

+ 6 - 2
mec-common/common-core/src/main/java/com/ym/mec/common/page/PageUtil.java

@@ -2,6 +2,7 @@ package com.ym.mec.common.page;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ym.mec.common.tenant.TenantContextHolder;
 
 import java.util.Map;
 import java.util.Objects;
@@ -52,16 +53,19 @@ public class PageUtil {
      * @param str   关键字
      * @return Optional
      */
-    public static <S, O> Optional<Integer> getPage(Map<S, O> param, String str) {
+    public static <O> Optional<Integer> getPage(Map<String, O> param, String str) {
         return Optional.ofNullable(param)
                 .map(p -> p.get(str))
                 .map(String::valueOf)
                 .map(Integer::valueOf);
     }
 
-    public static <S, O, T> Page<T> getPageInfo(Map<S, O> param) {
+    public static <O, T> Page<T> getPageInfo(Map<String, O> param) {
         int pageSize = getPage(param, "rows").orElse(20);
         int pageIndex = getPage(param, "page").orElse(1);
+        if (!param.containsKey("tenantId")) {
+            param.put("tenantId", (O) TenantContextHolder.getTenantId());
+        }
         return new Page<>(pageIndex, pageSize);
     }
 

+ 31 - 0
mec-common/common-core/src/main/java/com/ym/mec/common/page/WrapperUtil.java

@@ -1,6 +1,7 @@
 package com.ym.mec.common.page;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.ym.mec.common.exception.BizException;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 
@@ -73,6 +74,27 @@ public class WrapperUtil<T> {
         return this.hasIn(column, WrapperUtil.toList(val));
     }
 
+    public static <S, O> String toStr(Map<S, O> map, S str) {
+        Optional<O> o = Optional.ofNullable(map)
+                .map(m -> m.get(str));
+        return strOptional(o)
+                .orElse(null);
+    }
+
+    public static <S, O> String toStr(Map<S, O> map, S str, String exMsg) {
+        Optional<O> o = Optional.ofNullable(map)
+                .map(m -> m.get(str));
+        return strOptional(o)
+                .orElseThrow(() -> new BizException(exMsg));
+    }
+
+    private static <O> Optional<String> strOptional(Optional<O> optional) {
+        return optional
+                .filter(s -> s instanceof String)
+                .map(String::valueOf)
+                .filter(StringUtils::isNotBlank);
+    }
+
     public static List<String> toList(String key) {
         return toList(key, ",");
     }
@@ -104,4 +126,13 @@ public class WrapperUtil<T> {
         return Arrays.stream(b).filter(StringUtils::isNotBlank).collect(Collectors.toList());
     }
 
+    /**
+     * 全部有值则为true
+     *
+     * @param obj 多个对象
+     */
+    public static boolean checkObj(Object... obj) {
+        return Arrays.stream(obj).noneMatch(Objects::isNull);
+    }
+
 }

+ 70 - 36
mec-student/src/main/java/com/ym/mec/student/controller/SysCouponCodeController.java

@@ -4,52 +4,86 @@ import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.page.SysCouponCodeQueryInfo;
 import com.ym.mec.biz.service.SysCouponCodeService;
+import com.ym.mec.biz.service.SysCouponIssueRecordService;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.page.QueryInfo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
 
 @RequestMapping("sysCouponCode")
 @Api(tags = "优惠券明细")
 @RestController
 public class SysCouponCodeController extends BaseController {
 
-	@Autowired
-	private SysCouponCodeService sysCouponCodeService;
-	@Autowired
-	private SysUserFeignService sysUserFeignService;
-
-	@ApiOperation("分页查询")
-	@RequestMapping(value = "queryPage")
-	public HttpResponseResult queryPage(SysCouponCodeQueryInfo queryInfo) {
-		SysUser sysUser = sysUserFeignService.queryUserInfo();
-		if (sysUser != null && sysUser.getId() != null) {
-			queryInfo.setUserId(sysUser.getId());
-		}
-		if(queryInfo.getUserId() == null){
-			return failed("请登录");
-		}
-		return succeed(sysCouponCodeService.querySysCouponUseList(queryInfo));
-	}
-
-	@ApiOperation("获取云教练活动跑马灯")
-	@RequestMapping(value = "queryPageAll")
-	public HttpResponseResult queryPageAll(QueryInfo queryInfo) {
-		return succeed(sysCouponCodeService.queryHorseRaceLampDtoList(queryInfo));
-	}
-
-	@ApiOperation("兑换优惠券")
-	@PostMapping(value = "exchangeCoupon")
-	public HttpResponseResult exchangeCoupon(Integer couponId, Long paymentOrderId, Integer exchangeNum){
-		SysUser sysUser = sysUserFeignService.queryUserInfo();
-		if (sysUser == null) {
-			return failed("用户信息获取失败");
-		}
-		return succeed(sysCouponCodeService.exchangeCouponTest(sysUser.getId(), couponId, paymentOrderId, exchangeNum));
-	}
+    @Autowired
+    private SysCouponCodeService sysCouponCodeService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private SysCouponIssueRecordService couponIssueRecordService;
+
+
+    @ApiOperation("分页查询")
+    @RequestMapping(value = "queryPage")
+    public HttpResponseResult queryPage(SysCouponCodeQueryInfo queryInfo) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser != null && sysUser.getId() != null) {
+            queryInfo.setUserId(sysUser.getId());
+        }
+        if (queryInfo.getUserId() == null) {
+            return failed("请登录");
+        }
+        return succeed(sysCouponCodeService.querySysCouponUseList(queryInfo));
+    }
+
+    @ApiOperation("获取云教练活动跑马灯")
+    @RequestMapping(value = "queryPageAll")
+    public HttpResponseResult queryPageAll(QueryInfo queryInfo) {
+        return succeed(sysCouponCodeService.queryHorseRaceLampDtoList(queryInfo));
+    }
+
+    @ApiOperation("兑换优惠券")
+    @PostMapping(value = "exchangeCoupon")
+    public HttpResponseResult exchangeCoupon(Integer couponId, Long paymentOrderId, Integer exchangeNum) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(sysCouponCodeService.exchangeCouponTest(sysUser.getId(), couponId, paymentOrderId, exchangeNum));
+    }
+
+    /**
+     * 手动发放优惠券
+     */
+    @ApiOperation("手动发放优惠券")
+    @PostMapping(value = "/issueCoupon")
+    public HttpResponseResult issueCoupon(@RequestBody Map<String, Object> param) {
+        couponIssueRecordService.issueCoupon(param);
+        return succeed();
+    }
+
+    @ApiOperation("撤销发放优惠券")
+    @PostMapping(value = "/revokeCoupon")
+    public HttpResponseResult revokeCoupon(Integer couponId) {
+        return succeed(couponIssueRecordService.revokeCoupon(couponId));
+    }
+
+    @ApiOperation("查询优惠券发放名单")
+    @PostMapping(value = "/queryIssueDetail")
+    public HttpResponseResult queryIssueDetail(@RequestBody Map<String, Object> param) {
+        return succeed(couponIssueRecordService.queryIssueDetail(param));
+    }
+
+    @ApiOperation("查询优惠券发放名单")
+    @PostMapping(value = "/queryIssueRecord")
+    public HttpResponseResult queryIssueRecord(@RequestBody Map<String, Object> param) {
+        return succeed(couponIssueRecordService.queryIssueRecord(param));
+    }
+
 }

+ 2 - 2
mec-web/src/main/java/com/ym/mec/web/controller/SysCouponController.java

@@ -26,7 +26,7 @@ public class SysCouponController extends BaseController {
 
     @ApiOperation("新增")
     @PostMapping(value = "add")
-//    @PreAuthorize("@pcs.hasPermissions('sysCoupon/add')")
+    @PreAuthorize("@pcs.hasPermissions('sysCoupon/add')")
     public HttpResponseResult add(@Valid SysCoupon sysCoupon) {
         try {
             return succeed(sysCouponService.add(sysCoupon));
@@ -59,7 +59,7 @@ public class SysCouponController extends BaseController {
 
     @ApiOperation("分页查询")
     @RequestMapping(value = "queryPage")
-    @PreAuthorize("@pcs.hasPermissions('sysCoupon/queryPage')")
+//    @PreAuthorize("@pcs.hasPermissions('sysCoupon/queryPage')")
     public HttpResponseResult queryPage(SysCouponQueryInfo queryInfo) {
         return succeed(sysCouponService.queryPage(queryInfo));
     }