Commit ec8e84d5 authored by zhaobiyan's avatar zhaobiyan

Merge branch 'feature_member_score_zby' into feature_member_score

# Conflicts:
#	yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
#	yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/api/score/MemberUserScoreApiImpl.java
parents 87815697 3d427878
......@@ -41,4 +41,6 @@ public class MemberUserScoreBatchOperateReqDTO {
* 扩展参数
*/
private Map<String, Object> extParam;
private String uniqueId;
}
......@@ -12,6 +12,10 @@ import java.util.Map;
@Builder
@ToString
public class MemberUserScoreOperateReqDTO {
/**
* 唯一键 增加积分时必须,做幂等判断使用
*/
private String uniqueId;
/**
* 会员id
*/
......
......@@ -45,14 +45,20 @@ public interface ErrorCodeConstants {
ErrorCode SCORE_COUNT_ERROR = new ErrorCode(1004008002, "score.count.error");
ErrorCode MEMBER_SCORE_NOT_ENOUGH = new ErrorCode(1004008003, "member.score.not.enough");
ErrorCode SCORE_RULE_NOT_EXISTS = new ErrorCode(1004008004, "score.rule.not.exists");
ErrorCode SCORE_RULE_DELETE_ERROR = new ErrorCode(1004008005, "score.rule.delete.error");
ErrorCode SCORE_RULE_UPDATE_ERROR = new ErrorCode(1004008006, "score.rule.update.error");
ErrorCode SCORE_RULE_FIELD_ERROR = new ErrorCode(1004008007, "score.rule.field.error");
ErrorCode REVERSE_SOURCE_NO_RELEATION_ID = new ErrorCode(1004008008, "reverse.source.no.releation.id");
ErrorCode LEVEL_BOUND_RANGE_ERROR = new ErrorCode(1004008009, "level.bound.range.error");
ErrorCode LEVEL_BOUND_RANGE_CONFLICT = new ErrorCode(1004008010, "level.bound.range.conflict");
ErrorCode REVERSE_SOURCE_NO_RELEATION_ID = new ErrorCode(1004008004, "reverse.source.no.releation.id");
ErrorCode LEVEL_BOUND_RANGE_ERROR = new ErrorCode(1004008005, "level.bound.range.error");
ErrorCode LEVEL_BOUND_RANGE_CONFLICT = new ErrorCode(1004008006, "level.bound.range.conflict");
ErrorCode SOURCE_TYPE_IS_NULL = new ErrorCode(1004008007, "source.type.is.null");
ErrorCode SCORE_OPERATE_MUST_HAVE_UNIQUE_ID = new ErrorCode(1004008008, "score.operate.must.have.unique.id");
ErrorCode SCORE_OPERATE_IDEMPOTENT_ERROR = new ErrorCode(1004008009, "score.operate.idempotent.error");
ErrorCode SCORE_RULE_NOT_EXISTS = new ErrorCode(1004008010, "score.rule.not.exists");
ErrorCode SCORE_RULE_DELETE_ERROR = new ErrorCode(1004008011, "score.rule.delete.error");
ErrorCode SCORE_RULE_UPDATE_ERROR = new ErrorCode(1004008012, "score.rule.update.error");
ErrorCode SCORE_RULE_FIELD_ERROR = new ErrorCode(10040080013, "score.rule.field.error");
ErrorCode REVERSE_SOURCE_NO_RELEATION_ID = new ErrorCode(1004008014, "reverse.source.no.releation.id");
ErrorCode LEVEL_BOUND_RANGE_ERROR = new ErrorCode(1004008015, "level.bound.range.error");
ErrorCode LEVEL_BOUND_RANGE_CONFLICT = new ErrorCode(1004008016, "level.bound.range.conflict");
}
......@@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.member.api.score.dto.*;
import cn.iocoder.yudao.module.member.dal.dataobject.score.MemberUserScoreDO;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreDetail.MemberUserScoreDetailDO;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreDetailReleation.MemberUserScoreDetailReleationDO;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreLog.MemberUserScoreLogDO;
import cn.iocoder.yudao.module.member.dto.ScoreDetailChangeDto;
import cn.iocoder.yudao.module.member.enums.MemberScoreDetailReleationStatueEnum;
import cn.iocoder.yudao.module.member.enums.ScoreOperateTypeEnum;
......@@ -64,6 +65,16 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi {
if (req.getScoreCount() <= 0) {
throw exception(SCORE_COUNT_ERROR);
}
if (req.getSourceType() == null) {
throw exception(SOURCE_TYPE_IS_NULL);
}
if (StringUtils.isBlank(req.getUniqueId())) {
throw exception(SCORE_OPERATE_MUST_HAVE_UNIQUE_ID);
}
MemberUserScoreLogDO memberUserScoreLogDO = logService.getByUniqueId(req.getUniqueId());
if (memberUserScoreLogDO != null) {
throw exception(SCORE_OPERATE_IDEMPOTENT_ERROR);
}
String lockKey = "member:operate:score:" + req.getMemberId();
RLock lock = redissonClient.getLock(lockKey);
try {
......@@ -122,12 +133,13 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi {
}
}
return req.getMemberIds().stream().map(memberId -> operateScore(MemberUserScoreOperateReqDTO.builder()
.memberId(memberId)
.scoreCount(req.getScoreCount())
.operateType(req.getOperateType())
.sourceType(req.getSourceType())
.extParam(req.getExtParam())
.build()))
.memberId(memberId)
.scoreCount(req.getScoreCount())
.operateType(req.getOperateType())
.sourceType(req.getSourceType())
.extParam(req.getExtParam())
.uniqueId(req.getUniqueId() + "_" + memberId)
.build()))
.collect(Collectors.toList());
}
......@@ -188,6 +200,7 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi {
req.getOperateType().getValue() : req.getSourceType().getOperateType().getValue())
.sourceType(req.getSourceType().getValue())
.extParam(req.getExtParam())
.uniqueId(req.getUniqueId())
.build());
}
}
......@@ -64,6 +64,7 @@ public class MemberUserScoreExpireTask implements JobHandler {
.memberId(memberUserScoreDetailDO.getMemberId())
.scoreCount(memberUserScoreDetailDO.getRemainCount())
.sourceType(ScoreSourceTypeEnum.SYSTEM_EXPIRED)
.uniqueId(ScoreSourceTypeEnum.SYSTEM_EXPIRED +"_"+ memberUserScoreDetailDO.getId() + "_" + System.currentTimeMillis())
.extParam(extParam)
.build());
} catch (Exception e) {
......
......@@ -60,6 +60,7 @@ public class MemberUserScoreController {
.operateType(ScoreOperateTypeEnum.parseByValue(query.getOperateType()))
.sourceType(ScoreSourceTypeEnum.MANUAL_OPERATE)
.extParam(extParam)
.uniqueId(ScoreSourceTypeEnum.MANUAL_OPERATE + "_" + System.currentTimeMillis())
.build());
return success(null);
}
......
......@@ -32,4 +32,6 @@ public class MemberUserScoreLogDO extends BaseDO {
private Long ruleId;
private String extParam = "{}";
private String uniqueId;
}
......@@ -55,6 +55,7 @@ public class MemberUserScoreDetailExpireListener {
.memberId(detail.getMemberId())
.scoreCount(detail.getRemainCount())
.sourceType(ScoreSourceTypeEnum.SYSTEM_EXPIRED)
.uniqueId(ScoreSourceTypeEnum.SYSTEM_EXPIRED +"_"+ detail.getId() + "_" + System.currentTimeMillis())
.extParam(extParam)
.build());
} catch (Exception e) {
......
......@@ -17,4 +17,6 @@ public interface MemberUserScoreLogService extends IService<MemberUserScoreLogDO
PageResult<MemberUserScoreLogBackVO> getPage(MemberUserScoreLogQueryVO query);
Long createScoreLog(MemberUserScoreLogCreateReq createReq);
MemberUserScoreLogDO getByUniqueId(String uniqueId);
}
......@@ -10,6 +10,8 @@ import cn.iocoder.yudao.module.member.vo.memberUserScoreLog.MemberUserScoreLogBa
import cn.iocoder.yudao.module.member.vo.memberUserScoreLog.MemberUserScoreLogCreateReq;
import cn.iocoder.yudao.module.member.vo.memberUserScoreLog.MemberUserScoreLogQueryVO;
import cn.iocoder.yudao.module.system.service.dict.DictTypeService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
......@@ -59,10 +61,18 @@ public class MemberUserScoreLogServiceImpl extends AbstractService<MemberUserSco
userScoreLogDO.setOperateType(createReq.getOperateType());
userScoreLogDO.setSourceType(createReq.getSourceType());
userScoreLogDO.setRuleId(createReq.getRuleId());
userScoreLogDO.setUniqueId(createReq.getUniqueId());
if (createReq.getExtParam() != null) {
userScoreLogDO.setExtParam(JSONUtil.toJsonStr(createReq.getExtParam()));
}
this.saveOrUpdate(userScoreLogDO);
return userScoreLogDO.getId();
}
@Override
public MemberUserScoreLogDO getByUniqueId(String uniqueId) {
LambdaQueryWrapper<MemberUserScoreLogDO> wrapper = Wrappers.lambdaQuery();
wrapper.eq(MemberUserScoreLogDO::getUniqueId, uniqueId);
return this.selectOne(wrapper);
}
}
......@@ -17,4 +17,5 @@ public class MemberUserScoreLogCreateReq {
private Integer sourceType;
private Long ruleId;
private Map<String, Object> extParam;
private String uniqueId;
}
......@@ -116,6 +116,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
.sourceType(ScoreSourceTypeEnum.EXCHANGE_REWARD)
.scoreCount(redeemRewardReqVO.getRewardCount() * rewardDO.getPointsRequire())
.releationId(String.valueOf(redeemId))
.uniqueId(ScoreSourceTypeEnum.EXCHANGE_REWARD + "_" + redeemId)
.extParam(extParam)
.build());
}
......
......@@ -274,6 +274,7 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
.scoreCount(rewardRedeemDO.getScoreCount())
.extParam(extParam)
.releationId(String.valueOf(req.getId()))
.uniqueId(ScoreSourceTypeEnum.EXCHANGE_REWARD_CANCEL + "_" + req.getId())
.build());
return true;
}
......
......@@ -35,4 +35,7 @@ public class RewardRedeemPageRespVO extends RewardRedeemBaseVO {
private String currencyTitleEn;
@ApiModelProperty(value = "快递公司名称")
private String courierCompanyName;
private Integer holdScore;
private Integer pointsRequire;
}
......@@ -22,7 +22,7 @@
left join ecw_express ee on err.courier_company = ee.id
where 1=1
<include refid="pageCondition"/>
order by er.create_time desc
order by err.create_time desc
limit #{start}, #{size}
</select>
<select id="pageCount" resultType="java.lang.Integer">
......@@ -39,10 +39,13 @@
</select>
<select id="detail" resultType="cn.iocoder.yudao.module.reward.vo.reward.RewardRedeemPageRespVO">
select
mus.hold_score as holdScore,
er.points_require as pointsRequire,
<include refid="columns"/>
from ecw_reward_redeem err
left join ecw_reward er on err.reward_id = er.id
left join member_user mu on mu.id = err.member_id
left join member_user_score mus on mu.id = mus.member_id
left join ecw_node en on er.node_id = en.id
left join system_user suc on suc.id = er.creator
left join system_user suu on suu.id = er.updater
......
......@@ -1023,4 +1023,5 @@ currency.not.exist = currency not exist
date.format.error = date format error, for example : 2024-01-01 12:11:11
redeem.cancel.status.error = record status must be redeeming
level.bound.range.error = upper count must greater than lower count
level.bound.range.conflict = score range exist conflict
\ No newline at end of file
level.bound.range.conflict = score range exist conflict
score.operate.idempotent.error = idempotent key conflict
\ No newline at end of file
......@@ -1027,4 +1027,5 @@ currency.not.exist = \u5E01\u79CD\u4E0D\u5B58\u5728
date.format.error = \u65E5\u671F\u683C\u5F0F\u4E0D\u6B63\u786E, \u6B63\u786E\u683C\u5F0F\u53C2\u8003: 2024-01-01 12:11:11
redeem.cancel.status.error = \u5151\u6362\u4E2D\u72B6\u6001\u7684\u8BB0\u5F55\u624D\u80FD\u64A4\u9500
level.bound.range.error = \u4E0A\u754C\u6570\u503C\u5FC5\u987B\u5927\u4E8E\u4E0B\u754C\u6570\u503C
level.bound.range.conflict = \u79EF\u5206\u8303\u56F4\u5B58\u5728\u51B2\u7A81
\ No newline at end of file
level.bound.range.conflict = \u79EF\u5206\u8303\u56F4\u5B58\u5728\u51B2\u7A81
score.operate.idempotent.error = \u5E42\u7B49key\u51B2\u7A81
\ No newline at end of file
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