Commit f09f738f authored by zhangfeng's avatar zhangfeng

Merge branch 'refs/heads/feature_member_score' into dev

parents 90e0becc 08b5603a
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
left join member_user_score mus on mus.member_id = mu.id left join member_user_score mus on mus.member_id = mu.id
left join ecw_region re on re.id = mu.country left join ecw_region re on re.id = mu.country
left join ecw_region rea on rea.id = mu.city left join ecw_region rea on rea.id = mu.city
where 1 = 1 where 1 = 1 and mu.deleted = 0
<include refid="scoreCondition"/> <include refid="scoreCondition"/>
order by mu.id order by mu.id
limit #{start}, #{size} limit #{start}, #{size}
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
from member_user mu from member_user mu
left join member_user_score mus on mus.member_id = mu.id left join member_user_score mus on mus.member_id = mu.id
left join ecw_region re on re.id = mu.country left join ecw_region re on re.id = mu.country
where 1 = 1 where 1 = 1 and mu.deleted = 0
<include refid="scoreCondition"/> <include refid="scoreCondition"/>
</select> </select>
<select id="getByMemberId" <select id="getByMemberId"
......
...@@ -21,6 +21,7 @@ import cn.iocoder.yudao.module.reward.enums.RewardPickMethedEnum; ...@@ -21,6 +21,7 @@ import cn.iocoder.yudao.module.reward.enums.RewardPickMethedEnum;
import cn.iocoder.yudao.module.reward.enums.RewardRedeemStatusEnum; import cn.iocoder.yudao.module.reward.enums.RewardRedeemStatusEnum;
import cn.iocoder.yudao.module.reward.enums.RewardStatusEnum; import cn.iocoder.yudao.module.reward.enums.RewardStatusEnum;
import cn.iocoder.yudao.module.reward.service.reward.RewardService; import cn.iocoder.yudao.module.reward.service.reward.RewardService;
import cn.iocoder.yudao.module.reward.util.RewardGenCodeUtils;
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
...@@ -69,6 +70,8 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -69,6 +70,8 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
private SnowflakeGenerator snowflakeGenerator; private SnowflakeGenerator snowflakeGenerator;
@Resource @Resource
private SmsCodeApi smsCodeApi; private SmsCodeApi smsCodeApi;
@Resource
private RewardGenCodeUtils rewardGenCodeUtils;
@Override @Override
public Boolean redeemReward(RedeemRewardReqVO redeemRewardReqVO) { public Boolean redeemReward(RedeemRewardReqVO redeemRewardReqVO) {
...@@ -112,9 +115,9 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -112,9 +115,9 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void executeRedeem(RedeemRewardReqVO redeemRewardReqVO, Integer pointsRequire, Long rewardId) { public void executeRedeem(RedeemRewardReqVO redeemRewardReqVO, Integer pointsRequire, Long rewardId) {
// 添加兑换记录 // 添加兑换记录
Long redeemId = addRedeemRecord(redeemRewardReqVO, pointsRequire); RewardRedeemDO redeemRecord = addRedeemRecord(redeemRewardReqVO, pointsRequire);
// 更新会员积分 // 更新会员积分
updateMemberScore(redeemRewardReqVO, pointsRequire, redeemId); updateMemberScore(redeemRewardReqVO, pointsRequire, redeemRecord.getId(), redeemRecord.getRedemptionNumber());
// 更新礼品 // 更新礼品
redeemReward(rewardId, redeemRewardReqVO.getRewardCount()); redeemReward(rewardId, redeemRewardReqVO.getRewardCount());
} }
...@@ -150,7 +153,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -150,7 +153,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
if (StringUtils.isBlank(redeemRewardReqVO.getRecipientPhoneNum())) { if (StringUtils.isBlank(redeemRewardReqVO.getRecipientPhoneNum())) {
redeemRewardReqVO.setRecipientPhoneNum(memberUser.getMobile()); redeemRewardReqVO.setRecipientPhoneNum(memberUser.getMobile());
} }
} else { } else if (redeemRewardReqVO.getEntrance() != PlatformTypeEnum.BACKEND.getValue()) {
if (StringUtils.isAnyBlank(redeemRewardReqVO.getRecipientName(), redeemRewardReqVO.getRecipientPhoneNum(), redeemRewardReqVO.getRecipientAddress())) { if (StringUtils.isAnyBlank(redeemRewardReqVO.getRecipientName(), redeemRewardReqVO.getRecipientPhoneNum(), redeemRewardReqVO.getRecipientAddress())) {
throw exception(REWARD_REDEEM_RECIPIENT_ERROR); throw exception(REWARD_REDEEM_RECIPIENT_ERROR);
} }
...@@ -170,9 +173,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -170,9 +173,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
rewardMapper.updateById(upReward); rewardMapper.updateById(upReward);
} }
private void updateMemberScore(RedeemRewardReqVO redeemRewardReqVO, Integer pointsRequire, Long redeemId) { private void updateMemberScore(RedeemRewardReqVO redeemRewardReqVO, Integer pointsRequire, Long redeemId, String redemptionNumber) {
Map<String, Object> extParam = new HashMap<>(); Map<String, Object> extParam = new HashMap<>();
extParam.put("redeemId", redeemId); extParam.put("redeemId", redeemId);
extParam.put("redemptionNumber", redemptionNumber);
memberUserScoreApi.operateScore(MemberUserScoreOperateReqDTO.builder() memberUserScoreApi.operateScore(MemberUserScoreOperateReqDTO.builder()
.memberId(redeemRewardReqVO.getMemberId()) .memberId(redeemRewardReqVO.getMemberId())
.sourceType(ScoreSourceTypeEnum.EXCHANGE_REWARD) .sourceType(ScoreSourceTypeEnum.EXCHANGE_REWARD)
...@@ -183,13 +187,14 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -183,13 +187,14 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
.build()); .build());
} }
private Long addRedeemRecord(RedeemRewardReqVO redeemRewardReqVO, Integer pointsRequire) { private RewardRedeemDO addRedeemRecord(RedeemRewardReqVO redeemRewardReqVO, Integer pointsRequire) {
RewardRedeemDO rewardRedeemDO = BeanUtil.copyProperties(redeemRewardReqVO, RewardRedeemDO.class); RewardRedeemDO rewardRedeemDO = BeanUtil.copyProperties(redeemRewardReqVO, RewardRedeemDO.class);
rewardRedeemDO.setId(snowflakeGenerator.next()); rewardRedeemDO.setId(snowflakeGenerator.next());
rewardRedeemDO.setRedemptionNumber(rewardGenCodeUtils.generateRedemptionNumber());
rewardRedeemDO.setStatus(RewardRedeemStatusEnum.REDEEMING.getValue()); rewardRedeemDO.setStatus(RewardRedeemStatusEnum.REDEEMING.getValue());
rewardRedeemDO.setScoreCount(redeemRewardReqVO.getRewardCount() * pointsRequire); rewardRedeemDO.setScoreCount(redeemRewardReqVO.getRewardCount() * pointsRequire);
rewardRedeemMapper.insert(rewardRedeemDO); rewardRedeemMapper.insert(rewardRedeemDO);
return rewardRedeemDO.getId(); return rewardRedeemDO;
} }
@Override @Override
......
package cn.iocoder.yudao.module.reward.controller.admin.job;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
import cn.iocoder.yudao.module.reward.util.RewardGenCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 兑换记录编号刷新任务
* @author zhaobiyan
*/
@Component
@Slf4j
public class RedemptionNumberFlushTask implements JobHandler {
@Resource
private RewardGenCodeUtils rewardGenCodeUtils;
@Override
public String execute(String param) throws Exception {
rewardGenCodeUtils.redemptionNumberFlush();
return "success";
}
}
\ No newline at end of file
package cn.iocoder.yudao.module.reward.controller.admin.job;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
import cn.iocoder.yudao.module.reward.util.RewardGenCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 礼品编号刷新任务
* @author zhaobiyan
*/
@Component
@Slf4j
public class RewardCodeFlushTask implements JobHandler {
@Resource
private RewardGenCodeUtils rewardGenCodeUtils;
@Override
public String execute(String param) throws Exception {
rewardGenCodeUtils.historyRewardCodeFlush();
return "success";
}
}
\ No newline at end of file
...@@ -14,6 +14,8 @@ public class AppRewardRedeemDetailRespVO { ...@@ -14,6 +14,8 @@ public class AppRewardRedeemDetailRespVO {
@ApiModelProperty(value = "id") @ApiModelProperty(value = "id")
@JsonSerialize(using = ToStringSerializer.class) @JsonSerialize(using = ToStringSerializer.class)
private Long id; private Long id;
@ApiModelProperty(value = "兑换记录编号")
private String redemptionNumber;
@ApiModelProperty(value = "会员id") @ApiModelProperty(value = "会员id")
private Long memberId; private Long memberId;
@ApiModelProperty(value = "礼品id") @ApiModelProperty(value = "礼品id")
......
...@@ -23,6 +23,8 @@ public class AppRewardRedeemListRespVO { ...@@ -23,6 +23,8 @@ public class AppRewardRedeemListRespVO {
@ApiModelProperty(value = "id") @ApiModelProperty(value = "id")
@JsonSerialize(using = ToStringSerializer.class) @JsonSerialize(using = ToStringSerializer.class)
private Long id; private Long id;
@ApiModelProperty(value = "兑换记录编号")
private String redemptionNumber;
@ApiModelProperty(value = "礼品ID") @ApiModelProperty(value = "礼品ID")
private Long rewardCode; private Long rewardCode;
@ApiModelProperty(value = "礼品名称(中文)") @ApiModelProperty(value = "礼品名称(中文)")
......
...@@ -21,6 +21,10 @@ public class RewardRedeemDO extends BaseDO { ...@@ -21,6 +21,10 @@ public class RewardRedeemDO extends BaseDO {
*/ */
@TableId @TableId
private Long id; private Long id;
/**
* 兑换记录编号
*/
private String redemptionNumber;
/** /**
* 会员id * 会员id
*/ */
......
...@@ -23,4 +23,6 @@ public interface RewardRedeemMapper extends AbstractMapper<RewardRedeemDO> { ...@@ -23,4 +23,6 @@ public interface RewardRedeemMapper extends AbstractMapper<RewardRedeemDO> {
RewardRedeemPageRespVO detail(@Param("id") Long id); RewardRedeemPageRespVO detail(@Param("id") Long id);
List<RewardRedeemPageRespVO> exportList(@Param("req") RewardRedeemPageReqVO request); List<RewardRedeemPageRespVO> exportList(@Param("req") RewardRedeemPageReqVO request);
String getCurrentMaxRedemptionNumber();
} }
...@@ -7,11 +7,14 @@ import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO; ...@@ -7,11 +7,14 @@ import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.module.reward.dal.dataobject.reward.RewardDO; import cn.iocoder.yudao.module.reward.dal.dataobject.reward.RewardDO;
import cn.iocoder.yudao.module.reward.vo.reward.RewardQueryVO; import cn.iocoder.yudao.module.reward.vo.reward.RewardQueryVO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.ResultType;
import org.apache.ibatis.annotations.Select;
import java.util.List; import java.util.List;
/** /**
* 礼品 Mapper * 礼品 Mapper
*
* @author 系统管理员 * @author 系统管理员
*/ */
@Mapper @Mapper
...@@ -19,18 +22,18 @@ public interface RewardMapper extends AbstractMapper<RewardDO> { ...@@ -19,18 +22,18 @@ public interface RewardMapper extends AbstractMapper<RewardDO> {
@Override @Override
default PageResult<RewardDO> selectPage(PageVO page, Object object) { default PageResult<RewardDO> selectPage(PageVO page, Object object) {
if (object instanceof RewardQueryVO) { if (object instanceof RewardQueryVO) {
RewardQueryVO vo = (RewardQueryVO)object; RewardQueryVO vo = (RewardQueryVO) object;
return selectPage(page, new LambdaQuery<RewardDO>() return selectPage(page, new LambdaQuery<RewardDO>()
.eqIfPresent(RewardDO::getCode, vo.getCode()) .eqIfPresent(RewardDO::getCode, vo.getCode())
.eqIfPresent(RewardDO::getTitleZh, vo.getTitle()) .eqIfPresent(RewardDO::getTitleZh, vo.getTitle())
.eqIfPresent(RewardDO::getTitleEn, vo.getTitle()) .eqIfPresent(RewardDO::getTitleEn, vo.getTitle())
.eqIfPresent(RewardDO::getTitleFr, vo.getTitle()) .eqIfPresent(RewardDO::getTitleFr, vo.getTitle())
.eqIfPresent(RewardDO::getPointsRequire, vo.getPointsRequire()) .eqIfPresent(RewardDO::getPointsRequire, vo.getPointsRequire())
.eqIfPresent(RewardDO::getNodeId, vo.getNodeId()) .eqIfPresent(RewardDO::getNodeId, vo.getNodeId())
.eqIfPresent(RewardDO::getQuantityRemain, vo.getQuantityRemain()) .eqIfPresent(RewardDO::getQuantityRemain, vo.getQuantityRemain())
.eqIfPresent(RewardDO::getPickMethod, vo.getPickMethod()) .eqIfPresent(RewardDO::getPickMethod, vo.getPickMethod())
.eqIfPresent(RewardDO::getStatus, vo.getStatus()) .eqIfPresent(RewardDO::getStatus, vo.getStatus())
.betweenIfPresent(RewardDO::getCreateTime, vo.getBeginCreateTime(), vo.getEndCreateTime()) .betweenIfPresent(RewardDO::getCreateTime, vo.getBeginCreateTime(), vo.getEndCreateTime())
.orderByDesc(RewardDO::getId)); .orderByDesc(RewardDO::getId));
} }
...@@ -40,21 +43,25 @@ public interface RewardMapper extends AbstractMapper<RewardDO> { ...@@ -40,21 +43,25 @@ public interface RewardMapper extends AbstractMapper<RewardDO> {
@Override @Override
default List<RewardDO> selectList(Object object) { default List<RewardDO> selectList(Object object) {
if (object instanceof RewardQueryVO) { if (object instanceof RewardQueryVO) {
RewardQueryVO vo = (RewardQueryVO)object; RewardQueryVO vo = (RewardQueryVO) object;
return selectList(new LambdaQuery<RewardDO>() return selectList(new LambdaQuery<RewardDO>()
.eqIfPresent(RewardDO::getCode, vo.getCode()) .eqIfPresent(RewardDO::getCode, vo.getCode())
.eqIfPresent(RewardDO::getTitleZh, vo.getTitle()) .eqIfPresent(RewardDO::getTitleZh, vo.getTitle())
.eqIfPresent(RewardDO::getTitleEn, vo.getTitle()) .eqIfPresent(RewardDO::getTitleEn, vo.getTitle())
.eqIfPresent(RewardDO::getTitleFr, vo.getTitle()) .eqIfPresent(RewardDO::getTitleFr, vo.getTitle())
.eqIfPresent(RewardDO::getPointsRequire, vo.getPointsRequire()) .eqIfPresent(RewardDO::getPointsRequire, vo.getPointsRequire())
.eqIfPresent(RewardDO::getNodeId, vo.getNodeId()) .eqIfPresent(RewardDO::getNodeId, vo.getNodeId())
.eqIfPresent(RewardDO::getQuantityRemain, vo.getQuantityRemain()) .eqIfPresent(RewardDO::getQuantityRemain, vo.getQuantityRemain())
.eqIfPresent(RewardDO::getPickMethod, vo.getPickMethod()) .eqIfPresent(RewardDO::getPickMethod, vo.getPickMethod())
.eqIfPresent(RewardDO::getStatus, vo.getStatus()) .eqIfPresent(RewardDO::getStatus, vo.getStatus())
.betweenIfPresent(RewardDO::getCreateTime, vo.getBeginCreateTime(), vo.getEndCreateTime()) .betweenIfPresent(RewardDO::getCreateTime, vo.getBeginCreateTime(), vo.getEndCreateTime())
.orderByDesc(RewardDO::getId)); .orderByDesc(RewardDO::getId));
} }
return null; return null;
} }
@ResultType(String.class)
@Select({"select code from ecw_reward order by code desc limit 1"})
String getCurrentMaxRewardCode();
} }
...@@ -288,6 +288,7 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper, ...@@ -288,6 +288,7 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
} }
Map<String, Object> extParam = new HashMap<>(); Map<String, Object> extParam = new HashMap<>();
extParam.put("redeemId", req.getId()); extParam.put("redeemId", req.getId());
extParam.put("redemptionNumber", rewardRedeemDO.getRedemptionNumber());
memberUserScoreApi.operateScore(MemberUserScoreOperateReqDTO.builder() memberUserScoreApi.operateScore(MemberUserScoreOperateReqDTO.builder()
.memberId(rewardRedeemDO.getMemberId()) .memberId(rewardRedeemDO.getMemberId())
.sourceType(ScoreSourceTypeEnum.EXCHANGE_REWARD_CANCEL) .sourceType(ScoreSourceTypeEnum.EXCHANGE_REWARD_CANCEL)
...@@ -323,6 +324,7 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper, ...@@ -323,6 +324,7 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
RewardDO rewardDO = rewardService.getById(rewardRedeemDO.getRewardId()); RewardDO rewardDO = rewardService.getById(rewardRedeemDO.getRewardId());
return AppRewardRedeemListRespVO.builder() return AppRewardRedeemListRespVO.builder()
.id(rewardRedeemDO.getId()) .id(rewardRedeemDO.getId())
.redemptionNumber(rewardRedeemDO.getRedemptionNumber())
.createTime(rewardRedeemDO.getCreateTime()) .createTime(rewardRedeemDO.getCreateTime())
.rewardCode(rewardRedeemDO.getRewardId()) .rewardCode(rewardRedeemDO.getRewardId())
.rewardTitleEn(rewardDO.getTitleEn()) .rewardTitleEn(rewardDO.getTitleEn())
......
...@@ -22,11 +22,11 @@ import cn.iocoder.yudao.module.reward.enums.RewardPickMethedEnum; ...@@ -22,11 +22,11 @@ import cn.iocoder.yudao.module.reward.enums.RewardPickMethedEnum;
import cn.iocoder.yudao.module.reward.enums.RewardStatusEnum; import cn.iocoder.yudao.module.reward.enums.RewardStatusEnum;
import cn.iocoder.yudao.module.reward.vo.reward.*; import cn.iocoder.yudao.module.reward.vo.reward.*;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.module.reward.util.RewardGenCodeUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.Instant; import java.time.Instant;
...@@ -51,6 +51,8 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i ...@@ -51,6 +51,8 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i
private NodeApi nodeApi; private NodeApi nodeApi;
@Resource @Resource
private MemberUserApi memberUserApi; private MemberUserApi memberUserApi;
@Resource
private RewardGenCodeUtils rewardGenCodeUtils;
@Override @Override
public List<Long> create(RewardCreateReqVO createReqVO) { public List<Long> create(RewardCreateReqVO createReqVO) {
...@@ -65,14 +67,9 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i ...@@ -65,14 +67,9 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i
for (RewardCreateReqVO.NodeAndPoints nodeId : createReqVO.getNodeIds()) { for (RewardCreateReqVO.NodeAndPoints nodeId : createReqVO.getNodeIds()) {
rewardDO.setNodeId(nodeId.getNodeId()); rewardDO.setNodeId(nodeId.getNodeId());
rewardDO.setPointsRequire(nodeId.getPoints()); rewardDO.setPointsRequire(nodeId.getPoints());
rewardDO.setCode(generateRewardCode()); rewardDO.setCode(rewardGenCodeUtils.generateRewardCode());
//如果插入失败,重新生成code再次插入
try { rewardMapper.insert(rewardDO);
rewardMapper.insert(rewardDO);
} catch (Exception e) {
rewardDO.setCode(generateRewardCode());
rewardMapper.insert(rewardDO);
}
ids.add(rewardDO.getId()); ids.add(rewardDO.getId());
rewardDO.setId(null); rewardDO.setId(null);
} }
...@@ -267,7 +264,7 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i ...@@ -267,7 +264,7 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i
throw exception(REWARD_NOT_EXISTS); throw exception(REWARD_NOT_EXISTS);
} }
//重新生成礼品ID //重新生成礼品ID
reward.setCode(generateRewardCode()); reward.setCode(rewardGenCodeUtils.generateRewardCode());
//设置为未启用 //设置为未启用
reward.setStatus(RewardStatusEnum.DISABLED.getValue()); reward.setStatus(RewardStatusEnum.DISABLED.getValue());
//已兑换次数清零 //已兑换次数清零
...@@ -277,12 +274,7 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i ...@@ -277,12 +274,7 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i
reward.setCreateTime(null); reward.setCreateTime(null);
reward.setUpdateTime(null); reward.setUpdateTime(null);
reward.setDeleted(null); reward.setDeleted(null);
try { rewardMapper.insert(reward);
rewardMapper.insert(reward);
} catch (Exception e) {
reward.setCode(generateRewardCode());
rewardMapper.insert(reward);
}
return reward.getId(); return reward.getId();
} }
...@@ -407,13 +399,6 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i ...@@ -407,13 +399,6 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i
} }
} }
/**
* 生成礼品ID
*/
private String generateRewardCode() {
return RandomStringUtils.randomAlphanumeric(12).toUpperCase();
}
/** /**
* 校验礼品是否过期并修改礼品状态 * 校验礼品是否过期并修改礼品状态
*/ */
......
package cn.iocoder.yudao.module.reward.util;
import cn.iocoder.yudao.framework.redis.helper.RedisHelper;
import cn.iocoder.yudao.module.reward.dal.dataobject.redeem.RewardRedeemDO;
import cn.iocoder.yudao.module.reward.dal.dataobject.reward.RewardDO;
import cn.iocoder.yudao.module.reward.dal.mysql.redeem.RewardRedeemMapper;
import cn.iocoder.yudao.module.reward.dal.mysql.reward.RewardMapper;
import com.alibaba.excel.util.DateUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.GET_LOCK_FAILED;
/**
* 根据规则生成各种code
*/
@Component
public class RewardGenCodeUtils {
@Resource
private RewardMapper rewardMapper;
@Resource
private RedisHelper redisHelper;
@Resource
private RedissonClient redissonClient;
@Resource
private RewardRedeemMapper rewardRedeemMapper;
/**
* 生成礼品ID
*/
public String generateRewardCode() {
// 礼品ID命名规则:G+年+5位序列号,例如G2400005
String key = "rewardCode:max:number";
StringBuilder code = new StringBuilder();
code.append("G");
code.append(DateUtils.format(new Date(), "yy"));
Long codeNum;
if (redisHelper.hasKey(key)) {
codeNum = redisHelper.incrBy(key, 1);
} else {
RLock lock = redissonClient.getLock("next:reward:code:lock");
try {
boolean lockSuccess = lock.tryLock(2, 2, TimeUnit.SECONDS);
if (!lockSuccess) {
throw exception(GET_LOCK_FAILED);
}
String currentMaxRewardCode = rewardMapper.getCurrentMaxRewardCode();
if (currentMaxRewardCode == null){
codeNum = 1L;
} else {
codeNum = Long.parseLong(currentMaxRewardCode.substring(3)) + 1;
}
redisHelper.set(key, String.valueOf(codeNum),10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw exception(GET_LOCK_FAILED);
} finally {
lock.unlock();
}
}
// 获得5位序列号,不足位前面补0
code.append(String.format("%05d", codeNum));
return code.toString();
}
/**
* 生成兑换记录编号
*/
public String generateRedemptionNumber() {
String key = "redemptionNumber:max:number";
// EC+年月+5位序列号,例如EC240900005
StringBuilder code = new StringBuilder();
code.append("EC");
String currentYearMonth = DateUtils.format(new Date(), "yyMM");
code.append(currentYearMonth);
Long codeNum;
if (redisHelper.hasKey(key)) {
codeNum = redisHelper.incrBy(key, 1);
} else {
RLock lock = redissonClient.getLock("next:redemptionNumber:code:lock");
try {
boolean lockSuccess = lock.tryLock(2, 2, TimeUnit.SECONDS);
if (!lockSuccess) {
throw exception(GET_LOCK_FAILED);
}
String currentMaxRedemptionNumber = rewardRedeemMapper.getCurrentMaxRedemptionNumber();
if (currentMaxRedemptionNumber == null){
codeNum = 1L;
} else {
codeNum = Long.parseLong(currentMaxRedemptionNumber.substring(6)) + 1;
}
redisHelper.set(key, String.valueOf(codeNum),10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw exception(GET_LOCK_FAILED);
} finally {
lock.unlock();
}
}
// 获得5位序列号,不足位前面补0
code.append(String.format("%05d", codeNum));
return code.toString();
}
public void historyRewardCodeFlush() {
long start = 1L;
redisHelper.delete("rewardCode:max:number");
List<RewardDO> rewardDOS = rewardMapper.selectList();
for (RewardDO rewardDO : rewardDOS) {
StringBuilder code = new StringBuilder();
code.append("G");
code.append(DateUtils.format(new Date(), "yy"));
code.append(String.format("%05d", start));
rewardDO.setCode(code.toString());
rewardMapper.updateById(rewardDO);
start += 1;
}
}
public void redemptionNumberFlush() {
long start = 1L;
redisHelper.delete("redemptionNumber:max:number");
List<RewardRedeemDO> rewardRedeemDOList = rewardRedeemMapper.selectList();
for (RewardRedeemDO rewardRedeemDO : rewardRedeemDOList) {
StringBuilder code = new StringBuilder();
code.append("EC");
String currentYearMonth = DateUtils.format(new Date(), "yyMM");
code.append(currentYearMonth);
code.append(String.format("%05d", start));
rewardRedeemDO.setRedemptionNumber(code.toString());
rewardRedeemMapper.updateById(rewardRedeemDO);
start += 1;
}
}
}
...@@ -12,6 +12,11 @@ public class RewardRedeemBaseVO { ...@@ -12,6 +12,11 @@ public class RewardRedeemBaseVO {
@ApiModelProperty(value = "id") @ApiModelProperty(value = "id")
@JsonSerialize(using = ToStringSerializer.class) @JsonSerialize(using = ToStringSerializer.class)
private Long id; private Long id;
/**
* 兑换记录编号
*/
@ApiModelProperty(value = "兑换记录编号")
private String redemptionNumber;
/** /**
* 会员id * 会员id
*/ */
......
...@@ -73,9 +73,13 @@ ...@@ -73,9 +73,13 @@
<include refid="pageCondition"/> <include refid="pageCondition"/>
order by er.create_time desc order by er.create_time desc
</select> </select>
<select id="getCurrentMaxRedemptionNumber" resultType="java.lang.String">
select redemption_number from ecw_reward_redeem order by redemption_number desc limit 1
</select>
<sql id="columns"> <sql id="columns">
err.id , err.id ,
err.redemption_number as redemptionNumber,
err.member_id as memberId, err.member_id as memberId,
err.reward_id as rewardId, err.reward_id as rewardId,
err.status, err.status,
......
...@@ -1057,7 +1057,7 @@ score.rule.update.error = only disabled rule can update ...@@ -1057,7 +1057,7 @@ score.rule.update.error = only disabled rule can update
score.rule.delete.error = only disabled rule can delete score.rule.delete.error = only disabled rule can delete
score.rule.status.error = score rule status error score.rule.status.error = score rule status error
score.rule.status.not.enable = score rule status not enable score.rule.status.not.enable = score rule status not enable
score.rule.unique.check.error = score rule unique check error score.rule.unique.check.error = The same rule already exists during the validity period
score.rule.transport.type.error = transport type error score.rule.transport.type.error = transport type error
score.rule.time.error = score rule time error score.rule.time.error = score rule time error
score.rule.period.error = score rule period error score.rule.period.error = score rule period error
......
...@@ -1001,13 +1001,13 @@ case.num.in.merge.pkg=\u6B64\u7BB1\u5DF2\u88AB\u5408\u5305\uFF0C\u8BF7\u626B\u63 ...@@ -1001,13 +1001,13 @@ case.num.in.merge.pkg=\u6B64\u7BB1\u5DF2\u88AB\u5408\u5305\uFF0C\u8BF7\u626B\u63
order.already.in.merge.pkg=\u8BA2\u5355\u5DF2\u5728\u5408\u5305\u7BB1\u4E0B order.already.in.merge.pkg=\u8BA2\u5355\u5DF2\u5728\u5408\u5305\u7BB1\u4E0B
customer.is.new.or.old.no.change=\u5BA2\u6237\u5F53\u524D\u4E1A\u7EE9\u7C7B\u578B\u662F{}\u5BA2\u6237\uFF0C\u4E0D\u9700\u8981\u66F4\u65B0 customer.is.new.or.old.no.change=\u5BA2\u6237\u5F53\u524D\u4E1A\u7EE9\u7C7B\u578B\u662F{}\u5BA2\u6237\uFF0C\u4E0D\u9700\u8981\u66F4\u65B0
order.is.pre.installed=\u8BA2\u5355\u5DF2\u9884\u88C5 order.is.pre.installed=\u8BA2\u5355\u5DF2\u9884\u88C5
order.is.not.pre.installed =\u8ba2\u5355\u672a\u9884\u88c5\uff0c\u4e0d\u80fd\u5408\u5305 order.is.not.pre.installed =\u8BA2\u5355\u672A\u9884\u88C5\uFF0C\u4E0D\u80FD\u5408\u5305
order.item.charging.not.null=\u8ba2\u5355\u5546\u54c1\u8ba1\u8d39\u65b9\u5f0f\u4e0d\u80fd\u4e3a\u7a7a order.item.charging.not.null=\u8BA2\u5355\u5546\u54C1\u8BA1\u8D39\u65B9\u5F0F\u4E0D\u80FD\u4E3A\u7A7A
order.item.is.pay.advance.not.null=\u8ba2\u5355\u5546\u54c1\u662f\u5426\u9884\u4ed8\u4e0d\u80fd\u4e3a\u7a7a order.item.is.pay.advance.not.null=\u8BA2\u5355\u5546\u54C1\u662F\u5426\u9884\u4ED8\u4E0D\u80FD\u4E3A\u7A7A
order.item.freight.currency.not.null=\u8ba2\u5355\u5546\u54c1\u8fd0\u8d39\u8d27\u5e01\u5355\u4f4d\u4e0d\u80fd\u4e3a\u7a7a order.item.freight.currency.not.null=\u8BA2\u5355\u5546\u54C1\u8FD0\u8D39\u8D27\u5E01\u5355\u4F4D\u4E0D\u80FD\u4E3A\u7A7A
order.item.freight.unit.not.null=\u8ba2\u5355\u5546\u54c1\u8fd0\u8d39\u8ba1\u91cf\u5355\u4f4d\u4e0d\u80fd\u4e3a\u7a7a order.item.freight.unit.not.null=\u8BA2\u5355\u5546\u54C1\u8FD0\u8D39\u8BA1\u91CF\u5355\u4F4D\u4E0D\u80FD\u4E3A\u7A7A
order.item.clearance.currency.not.null=\u8ba2\u5355\u5546\u54c1\u6e05\u5173\u8d39\u8d27\u5e01\u5355\u4f4d\u4e0d\u80fd\u4e3a\u7a7a order.item.clearance.currency.not.null=\u8BA2\u5355\u5546\u54C1\u6E05\u5173\u8D39\u8D27\u5E01\u5355\u4F4D\u4E0D\u80FD\u4E3A\u7A7A
order.item.clearance.unit.not.null=\u8ba2\u5355\u5546\u54c1\u6e05\u5173\u8d39\u8ba1\u91cf\u5355\u4f4d\u4e0d\u80fd\u4e3a\u7a7a order.item.clearance.unit.not.null=\u8BA2\u5355\u5546\u54C1\u6E05\u5173\u8D39\u8BA1\u91CF\u5355\u4F4D\u4E0D\u80FD\u4E3A\u7A7A
member.id.is.null=\u7F3A\u5C11\u4F1A\u5458id member.id.is.null=\u7F3A\u5C11\u4F1A\u5458id
score.count.error=\u79EF\u5206\u5FC5\u987B > 0 score.count.error=\u79EF\u5206\u5FC5\u987B > 0
member.score.not.enough = \u4F1A\u5458\u79EF\u5206\u4E0D\u8DB3 member.score.not.enough = \u4F1A\u5458\u79EF\u5206\u4E0D\u8DB3
...@@ -1058,7 +1058,7 @@ score.rule.update.error = \u53EA\u6709\u672A\u542F\u7528\u89C4\u5219\u53EF\u4EE5 ...@@ -1058,7 +1058,7 @@ score.rule.update.error = \u53EA\u6709\u672A\u542F\u7528\u89C4\u5219\u53EF\u4EE5
score.rule.delete.error = \u53EA\u6709\u672A\u542F\u7528\u53EF\u4EE5\u5220\u9664 score.rule.delete.error = \u53EA\u6709\u672A\u542F\u7528\u53EF\u4EE5\u5220\u9664
score.rule.status.error = \u79EF\u5206\u89C4\u5219\u72B6\u6001\u9519\u8BEF score.rule.status.error = \u79EF\u5206\u89C4\u5219\u72B6\u6001\u9519\u8BEF
score.rule.status.not.enable = \u79EF\u5206\u89C4\u5219\u672A\u542F\u7528 score.rule.status.not.enable = \u79EF\u5206\u89C4\u5219\u672A\u542F\u7528
score.rule.unique.check.error = \u79EF\u5206\u89C4\u5219\u552F\u4E00\u6027\u68C0\u67E5\u5931\u8D25 score.rule.unique.check.error = \u6709\u6548\u671F\u5185\u5DF2\u5B58\u5728\u76F8\u540C\u89C4\u5219
score.rule.transport.type.error = \u8FD0\u8F93\u7C7B\u578B\u9519\u8BEF score.rule.transport.type.error = \u8FD0\u8F93\u7C7B\u578B\u9519\u8BEF
score.rule.time.error = \u6D3B\u52A8\u65F6\u95F4\u4E0D\u5408\u6CD5 score.rule.time.error = \u6D3B\u52A8\u65F6\u95F4\u4E0D\u5408\u6CD5
score.rule.period.error = \u8FC7\u671F\u65F6\u95F4\u9519\u8BEF score.rule.period.error = \u8FC7\u671F\u65F6\u95F4\u9519\u8BEF
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment