Commit 87cfb3cf authored by zhaobiyan's avatar zhaobiyan

Merge branch 'feature_member_score' into dev

parents bb7c9049 f0cc8fba
......@@ -43,4 +43,7 @@ public class AppAuthRegReqVO {
@ApiModelProperty(value = "英文名称", required = false, example = "+86")
private String englishName;
@ApiModelProperty(value = "推荐码", required = false)
private String referralCode;
}
......@@ -95,6 +95,8 @@ public class MemberUserDO extends TenantBaseDO {
*/
private String controlPassword;
private String referralCode;
///**
// * 是否身份认证
// */
......@@ -235,6 +237,9 @@ public class MemberUserDO extends TenantBaseDO {
*/
private Boolean isDeal;
private Integer country;
private Integer city;
private String code;
@TableField(exist = false)
private Integer holdScore;
......
package cn.iocoder.yudao.module.member.mq.consumer.score.core;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQuery;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreRule.ScoreRuleDO;
import cn.iocoder.yudao.module.member.enums.ScoreRuleStatusEnum;
import cn.iocoder.yudao.module.member.enums.ScoreRuleTypeEnum;
import cn.iocoder.yudao.module.member.enums.TransportTypeEnum;
import cn.iocoder.yudao.module.member.service.scoreRule.ScoreRuleService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
/**
* 半成品
* @author zhangfeng
*/
public abstract class AbstractScoreRuleStrategy implements ScoreRuleStrategy {
private static ScoreRuleDO orderVShipScoreRule = null;
private static ScoreRuleDO orderVFlyScoreRule = null;
private static ScoreRuleDO registerScoreRule = null;
private static ScoreRuleDO recommendScoreRule = null;
protected ScoreRuleService scoreRuleService;
@Autowired
public AbstractScoreRuleStrategy(ScoreRuleService scoreRuleService) {
this.scoreRuleService = scoreRuleService;
}
public ScoreRuleDO getEnableScoreRuleByType(ScoreRuleTypeEnum scoreRuleType) {
ScoreRuleDO scoreRuleDO = scoreRuleService.selectOne(new LambdaQuery<ScoreRuleDO>()
.eq(ScoreRuleDO::getType, scoreRuleType.getValue())
.eq(ScoreRuleDO::getStatus, ScoreRuleStatusEnum.ENABLED.getValue()));
if (scoreRuleDO != null) {
// 校验一下活动开始结束时间
if (!scoreRuleDO.getEndTime().after(new Date()) || !scoreRuleDO.getStartTime().before(new Date())) {
return null;
} else {
recommendScoreRule = scoreRuleDO;
return recommendScoreRule;
}
}
return null;
}
public ScoreRuleDO getEnableScoreRuleByType(ScoreRuleTypeEnum scoreRuleType, TransportTypeEnum transportType) {
ScoreRuleDO scoreRuleDO = null;
switch (scoreRuleType) {
case ORDER_V:
scoreRuleDO = scoreRuleService.getEnabledOrderVScoreRuleByTransportType(transportType.getValue());
if (scoreRuleDO != null) {
if (!scoreRuleDO.getEndTime().after(new Date()) || !scoreRuleDO.getStartTime().before(new Date())) {
return null;
}
if (transportType == TransportTypeEnum.OCEAN_LCL) {
orderVShipScoreRule = scoreRuleDO;
return orderVShipScoreRule;
}
if (transportType == TransportTypeEnum.SPECIAL_LINE_AIR_FREIGHT) {
orderVFlyScoreRule = scoreRuleDO;
return orderVFlyScoreRule;
}
}
break;
case RECOMMEND:
case REGISTER:
return getEnableScoreRuleByType(scoreRuleType);
}
return null;
}
@Override
public void refreshScoreRule(ScoreRuleTypeEnum scoreRuleType) {
switch (scoreRuleType) {
case ORDER_V:
orderVShipScoreRule = null;
orderVFlyScoreRule = null;
break;
case RECOMMEND:
recommendScoreRule = null;
break;
case REGISTER:
registerScoreRule = null;
break;
}
}
}
......@@ -37,27 +37,29 @@ import java.util.Objects;
*/
@Service
@Slf4j
public class OderVStrategy implements ScoreRuleStrategy {
public class OderVStrategy extends AbstractScoreRuleStrategy {
@Resource
private OrderApi orderApi;
@Resource
private ScoreRuleService scoreRuleService;
@Resource
private MemberUserScoreApi memberUserScoreApi;
@Resource
private MemberUserScoreLogService memberUserScoreLogService;
@Resource
private CustomerContactsService customerContactsService;
public OderVStrategy(ScoreRuleService scoreRuleService) {
super(scoreRuleService);
}
@Override
public void addScore(ScoreMessage message) {
log.info("订单V值增加积分");
log.info("Received order V message,orderID:{}", message.getOrderId());
Long orderId = message.getOrderId();
OrderRespDTO order;
try {
order = orderApi.getOrder(orderId, "");
} catch (Exception e) {
log.error("Order in shipping listener: Get order error,orderId:{},orderNo:{}", orderId, "");
log.error("Order in shipping listener: Get order error,orderId:{}", orderId, e);
return;
}
if (Objects.isNull(order)) {
......@@ -72,12 +74,12 @@ public class OderVStrategy implements ScoreRuleStrategy {
Integer transportId = order.getTransportId();
ScoreRuleDO scoreRuleDO = scoreRuleService.getEnabledOrderVScoreRuleByTransportType(transportId);
if (Objects.isNull(scoreRuleDO)) {
log.info("Order in shipping listener: No score rule match");
log.info("Order in shipping listener: No score rule match,orderID:{}", orderId);
return;
}
// 是否过期,或者活动还没开始
if (!scoreRuleDO.getEndTime().after(new Date()) || !scoreRuleDO.getStartTime().before(new Date())) {
log.info("Order in shipping listener: The score rule has expired");
log.info("Order in shipping listener: The score rule has expired,scoreRuleID:{}", scoreRuleDO.getId());
return;
}
// 目的地信息
......@@ -117,7 +119,7 @@ public class OderVStrategy implements ScoreRuleStrategy {
// 订单入口
String orderEntryString = extraInfo.getOrderEntry();
if (StringUtils.isBlank(orderEntryString)) {
log.info("Order in shipping listener: orderEntry is null");
log.info("Order in shipping listener: orderEntry is null,scoreRuleID:{}", scoreRuleDO.getId());
return;
}
String[] orderEntry = orderEntryString.split(",");
......@@ -149,7 +151,7 @@ public class OderVStrategy implements ScoreRuleStrategy {
// 是否首单,首单只加一次
if (extraInfo.getFirstOrder() == YesOrNoTypeEnum.YES.ordinal()) {
if (!orderApi.isFirstOrder(userId)) {
log.info("Order in shipping listener: Not first order");
log.info("Order in shipping listener: Not first order,userId:{}", userId);
return;
}
}
......@@ -182,16 +184,19 @@ public class OderVStrategy implements ScoreRuleStrategy {
.sourceType(ScoreSourceTypeEnum.ORDER_V)
.ruleId(scoreRuleDO.getId())
.expireDays(scoreRuleDO.getScorePeriod())
.releationId(String.valueOf(orderId))
.uniqueId(String.valueOf(orderId))
.extParam(map)
.build()
);
} catch (Exception e) {
log.error("Order in shipping listener: operateScore error", e);
}
log.info("Order V rule add score success,ruleID:{},orderID:{},userID:{}", scoreRuleDO.getId(), message.getOrderId(), userId);
}
@Override
public ScoreRuleTypeEnum getScoreRuleType() {
public ScoreRuleTypeEnum getStrategyScoreRuleType() {
return ScoreRuleTypeEnum.ORDER_V;
}
......
package cn.iocoder.yudao.module.member.mq.consumer.score.core;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQuery;
import cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi;
import cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateReqDTO;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreLog.MemberUserScoreLogDO;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreRule.ScoreRuleDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.enums.ScoreRuleStatusEnum;
import cn.iocoder.yudao.module.member.enums.ScoreRuleTypeEnum;
import cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum;
import cn.iocoder.yudao.module.member.mq.message.ScoreMessage;
import cn.iocoder.yudao.module.member.service.scoreLog.MemberUserScoreLogService;
import cn.iocoder.yudao.module.member.service.scoreRule.ScoreRuleService;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* @author zhangfeng
*/
@Service
@Slf4j
public class RecommendStrategy implements ScoreRuleStrategy{
public class RecommendStrategy extends AbstractScoreRuleStrategy {
@Resource
private MemberUserScoreApi memberUserScoreApi;
@Resource
private MemberUserService memberUserService;
@Resource
private MemberUserScoreLogService memberUserScoreLogService;
public RecommendStrategy(ScoreRuleService scoreRuleService) {
super(scoreRuleService);
}
@Override
public void addScore(ScoreMessage message) {
log.info("推荐增加积分");
Long userId = message.getUserId();
log.info("Received Recommend message,userID:{}", userId);
ScoreRuleDO scoreRuleDO = scoreRuleService.selectOne(new LambdaQuery<ScoreRuleDO>()
.eq(ScoreRuleDO::getType, ScoreRuleTypeEnum.RECOMMEND.getValue())
.eq(ScoreRuleDO::getStatus, ScoreRuleStatusEnum.ENABLED.getValue()));
if (scoreRuleDO == null) {
log.info("Recommend rule is not exist,userID:{}", userId);
return;
}
// 是否过期,或者活动还没开始
if (!scoreRuleDO.getEndTime().after(new Date()) || !scoreRuleDO.getStartTime().before(new Date())) {
log.info("Recommend listener: The score rule has expired,scoreRuleID:{}", scoreRuleDO.getId());
return;
}
MemberUserDO memberUserDO = memberUserService.getUser(userId);
if (memberUserDO == null) {
log.info("Recommend listener: The user does not exist,userID:{}", userId);
return;
}
// 校验累计最高分
Integer userScoreTotalCount = 0;
LambdaQueryWrapper<MemberUserScoreLogDO> scoreLogQueryWrapper = new LambdaQueryWrapper<>();
scoreLogQueryWrapper.eq(MemberUserScoreLogDO::getMemberId, userId)
.eq(MemberUserScoreLogDO::getRuleId, scoreRuleDO.getId());
List<MemberUserScoreLogDO> memberUserScoreLogs = memberUserScoreLogService.selectList(scoreLogQueryWrapper);
if (CollUtil.isNotEmpty(memberUserScoreLogs)) {
for (MemberUserScoreLogDO memberUserScoreLog : memberUserScoreLogs) {
userScoreTotalCount += memberUserScoreLog.getScoreCount();
}
}
if (userScoreTotalCount >= scoreRuleDO.getMaxScoreTotal()) {
log.info("Recommend listener: The user has reached the maximum score,userId:{},scoreRuleId:{}", userId, scoreRuleDO.getId());
return;
}
try {
HashMap<String, Object> map = new HashMap<>();
map.put("userId", userId);
map.put("userNameZh", message.getUserNameZh());
map.put("userNameEn", message.getUserNameEn());
String desensitizedPhoneNumber = message.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
map.put("phone", desensitizedPhoneNumber);
memberUserScoreApi.operateScore(MemberUserScoreOperateReqDTO.builder()
.memberId(userId)
.scoreCount(scoreRuleDO.getGetScoreOnce())
.sourceType(ScoreSourceTypeEnum.RECOMMEND)
.ruleId(scoreRuleDO.getId())
.uniqueId(userId + "_" + message.getRecommendUserId())
.expireDays(scoreRuleDO.getScorePeriod())
.build());
} catch (Exception e) {
log.error("Recommend listener: operateScore error", e);
}
log.info("Recommend rule add score success,ruleID:{},userID:{}", scoreRuleDO.getId(), userId);
}
@Override
public ScoreRuleTypeEnum getScoreRuleType() {
public ScoreRuleTypeEnum getStrategyScoreRuleType() {
return ScoreRuleTypeEnum.RECOMMEND;
}
}
package cn.iocoder.yudao.module.member.mq.consumer.score.core;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQuery;
import cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi;
import cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateReqDTO;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreRule.ScoreRuleDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.enums.ScoreRuleStatusEnum;
import cn.iocoder.yudao.module.member.enums.ScoreRuleTypeEnum;
import cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum;
import cn.iocoder.yudao.module.member.mq.message.ScoreMessage;
import cn.iocoder.yudao.module.member.service.scoreRule.ScoreRuleService;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
/**
* @author zhangfeng
*/
@Service
@Slf4j
public class RegisterStrategy implements ScoreRuleStrategy{
public class RegisterStrategy extends AbstractScoreRuleStrategy {
@Resource
private MemberUserScoreApi memberUserScoreApi;
@Resource
private MemberUserService memberUserService;
public RegisterStrategy(ScoreRuleService scoreRuleService) {
super(scoreRuleService);
}
@Override
public void addScore(ScoreMessage message) {
log.info("注册增加积分");
Long userId = message.getUserId();
log.info("Received register message,userID:{}", userId);
ScoreRuleDO scoreRuleDO = scoreRuleService.selectOne(new LambdaQuery<ScoreRuleDO>()
.eq(ScoreRuleDO::getType, ScoreRuleTypeEnum.REGISTER.getValue())
.eq(ScoreRuleDO::getStatus, ScoreRuleStatusEnum.ENABLED.getValue()));
if (scoreRuleDO == null) {
log.info("Register rule is not exist,userID:{}", userId);
return;
}
// 是否过期,或者活动还没开始
if (!scoreRuleDO.getEndTime().after(new Date()) || !scoreRuleDO.getStartTime().before(new Date())) {
log.info("Register listener: The score rule has expired,scoreRuleID:{}", scoreRuleDO.getId());
return;
}
MemberUserDO memberUserDO = memberUserService.getUser(userId);
if (memberUserDO == null) {
log.info("Register listener: The user does not exist,userID:{}", userId);
return;
}
//TODO:校验注册入口,目前表没加
try {
HashMap<String, Object> map = new HashMap<>();
map.put("userId", userId);
map.put("userNameZh", message.getUserNameZh());
map.put("userNameEn", message.getUserNameEn());
String desensitizedPhoneNumber = message.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
map.put("phone", desensitizedPhoneNumber);
memberUserScoreApi.operateScore(MemberUserScoreOperateReqDTO.builder()
.memberId(userId)
.scoreCount(scoreRuleDO.getGetScoreOnce())
.sourceType(ScoreSourceTypeEnum.REGISTER)
.ruleId(scoreRuleDO.getId())
.uniqueId(String.valueOf(userId))
.expireDays(scoreRuleDO.getScorePeriod())
.build());
} catch (Exception e) {
log.error("Register listener: operateScore error", e);
}
log.info("Register rule add score success,ruleID:{},userID:{}", scoreRuleDO.getId(), userId);
}
@Override
public ScoreRuleTypeEnum getScoreRuleType() {
public ScoreRuleTypeEnum getStrategyScoreRuleType() {
return ScoreRuleTypeEnum.REGISTER;
}
}
......@@ -7,5 +7,6 @@ import cn.iocoder.yudao.module.member.mq.message.ScoreMessage;
*/
public interface ScoreRuleStrategy {
void addScore(ScoreMessage message);
ScoreRuleTypeEnum getScoreRuleType();
ScoreRuleTypeEnum getStrategyScoreRuleType();
void refreshScoreRule(ScoreRuleTypeEnum scoreRuleType);
}
......@@ -17,7 +17,7 @@ public class ScoreRuleStrategyFactory {
@Autowired
public void setStrategyFactory(List<ScoreRuleStrategy> strategyList) {
for (ScoreRuleStrategy strategy : strategyList) {
strategies.put(strategy.getScoreRuleType(), strategy);
strategies.put(strategy.getStrategyScoreRuleType(), strategy);
}
}
......
......@@ -12,8 +12,39 @@ import lombok.*;
@NoArgsConstructor
@AllArgsConstructor
public class ScoreMessage extends AbstractStreamMessage {
/**
* 积分规则类型所有消息必填
*/
private ScoreRuleTypeEnum scoreRuleType;
/**
* 订单ID:订单V值消息必填
*/
private Long orderId;
/**
* userID:注册,推荐必填(加分的人)
*/
private Long userId;
/**
* 被推荐的会员ID:推荐必填
*/
private Long recommendUserId;
/**
* 中文名:注册,推荐必填,推荐时填推荐人的信息
*/
private String userNameZh;
/**
* 英文名:注册,推荐必填,推荐时填推荐人的信息
*/
private String userNameEn;
/**
* userID:注册,推荐必填,推荐时填推荐人的信息
*/
private String phone;
/**
* 推荐码:推荐必填
*/
private String recommendCode;
@Override
public String getStreamKey() {
return "member.score.add";
......
......@@ -117,7 +117,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
}
// 获得获得注册用户
MemberUserDO user = userService.createUser(reqVO.getMobile(), userIp, reqVO.getPassword(),reqVO.getAreaCode(), reqVO.getEnglishName());
MemberUserDO user = userService.createUser(reqVO.getMobile(), userIp, reqVO.getPassword(),reqVO.getAreaCode(), reqVO.getEnglishName(), reqVO.getReferralCode());
Assert.notNull(user, "创建用户失败,结果为空");
//记录日志
......
package cn.iocoder.yudao.module.member.service.user;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.validation.Mobile;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.module.member.api.user.dto.UserSelectReqVO;
import cn.iocoder.yudao.module.member.controller.admin.user.vo.UserBackVO;
......@@ -51,9 +50,10 @@ public interface MemberUserService {
* @param mobile
* @param registerIp
* @param password
* @param referralCode
* @return
*/
MemberUserDO createUser(String mobile, String registerIp, String password, String areaCode, String englishName);
MemberUserDO createUser(String mobile, String registerIp, String password, String areaCode, String englishName, String referralCode);
/**
* 更新用户的最后登陆信息
......
......@@ -172,7 +172,7 @@ public class MemberUserServiceImpl implements MemberUserService {
}
String englishName = maskMobileNumber(mobile);
// 用户不存在,则进行创建
user = this.createUser(mobile, registerIp, null, areaCode, englishName);
user = this.createUser(mobile, registerIp, null, areaCode, englishName, null);
//记录日志
UserOperationLogCreateReqVO userOperationLogCreateReqVO = new UserOperationLogCreateReqVO();
......@@ -202,7 +202,7 @@ public class MemberUserServiceImpl implements MemberUserService {
@Override
@Transactional(rollbackFor = Exception.class)
public MemberUserDO createUser(String mobile, String registerIp, String password, String areacode, String englishName) {
public MemberUserDO createUser(String mobile, String registerIp, String password, String areacode, String englishName, String referralCode) {
// 生成密码
/* if (StrUtil.isBlank(password)) {
password = IdUtil.fastSimpleUUID();
......@@ -222,6 +222,7 @@ public class MemberUserServiceImpl implements MemberUserService {
user.setEnglishName(englishName);
user.setNickname(englishName);
user.setCode(getNextMemberCode());
user.setReferralCode(referralCode);
memberUserMapper.insert(user);
//站内信
InternalMessageCreateDto dto = InternalMessageCreateDto.builder().toIdList(Arrays.asList(user.getId()))
......
......@@ -51,4 +51,11 @@ public class MemberUpdateReqVO{
@ApiModelProperty(value = "地址")
private String address;
@ApiModelProperty(value = "国家")
private Long country;
@ApiModelProperty(value = "城市")
private Long city;
}
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