Commit d6827fec authored by zhangfeng's avatar zhangfeng

Merge branch 'refs/heads/feature_member_score' into feature_member_score_zhangfeng

parents 733f1899 e3350382
......@@ -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,15 @@ 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(1004008013, "score.rule.field.error");
}
......@@ -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) {
......
......@@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.member.controller.admin.level;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.service.level.MemberUserLevelConfigService;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelBaseRespVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelReqVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelUpdateVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigBaseRespVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigReqVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigUpdateVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
......@@ -35,7 +35,7 @@ public class MemberUserLevelConfigController {
@PostMapping("/page")
@ApiOperation("列表")
public CommonResult<PageResult<MemberUserLevelBaseRespVO>> getLevelPage(@Valid @RequestBody MemberUserLevelReqVO query) {
public CommonResult<PageResult<MemberUserLevelConfigBaseRespVO>> getLevelPage(@Valid @RequestBody MemberUserLevelConfigReqVO query) {
return success(userLevelConfigService.getLevelPage(query));
}
......@@ -47,13 +47,13 @@ public class MemberUserLevelConfigController {
@PostMapping("/add")
@ApiOperation("新增")
public CommonResult<Boolean> add(@Valid @RequestBody MemberUserLevelUpdateVO query) {
public CommonResult<Boolean> add(@Valid @RequestBody MemberUserLevelConfigUpdateVO query) {
return success(userLevelConfigService.add(query));
}
@PostMapping("/update")
@ApiOperation("编辑")
public CommonResult<Boolean> update(@Valid @RequestBody MemberUserLevelUpdateVO query) {
public CommonResult<Boolean> update(@Valid @RequestBody MemberUserLevelConfigUpdateVO query) {
return success(userLevelConfigService.updateLevel(query));
}
}
......@@ -27,6 +27,7 @@ import cn.iocoder.yudao.module.member.dal.dataobject.userEnterpriseAuth.UserEnte
import cn.iocoder.yudao.module.member.dal.dataobject.userOperationLog.UserOperationLogDO;
import cn.iocoder.yudao.module.member.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.member.enums.UserAuditStatusEnum;
import cn.iocoder.yudao.module.member.service.level.MemberUserLevelConfigService;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import cn.iocoder.yudao.module.member.service.userCardAuth.UserCardAuthService;
import cn.iocoder.yudao.module.member.service.userEnterpriseAuth.UserEnterpriseAuthService;
......@@ -35,6 +36,8 @@ import cn.iocoder.yudao.module.member.vo.userCardAuth.UserCardAuthBackVO;
import cn.iocoder.yudao.module.member.vo.userCardAuth.UserCardAuthCreateReqVO;
import cn.iocoder.yudao.module.member.vo.userEnterpriseAuth.UserEnterpriseAuthBackVO;
import cn.iocoder.yudao.module.member.vo.userEnterpriseAuth.UserEnterpriseAuthCreateReqVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigBaseRespVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserScoreLevelVO;
import cn.iocoder.yudao.module.member.vo.userOperationLog.UserOperationLogBackVO;
import com.alibaba.excel.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
......@@ -95,6 +98,9 @@ public class MemberUserController {
@Resource
private PasswordEncoder passwordEncoder;
@Resource
private MemberUserLevelConfigService memberUserLevelConfigService;
@GetMapping("/member-user-list")
@ApiOperation("获得会员帐号列表-下拉列表使用")
......@@ -136,6 +142,16 @@ public class MemberUserController {
if (passwordEncoder.matches("88888888", user.getPassword())) {
userBackVO.setIsSimplePassword(Boolean.TRUE);
}
MemberUserLevelConfigBaseRespVO userScoreLevelVO = memberUserLevelConfigService.getLevelByCount(user.getTotalScore());
MemberUserScoreLevelVO scoreLevelVO = MemberUserScoreLevelVO.builder().memberId(user.getId())
.memberCode(user.getMemberCode())
.holdScore(user.getHoldScore())
.expiredScore(user.getExpiredScore())
.usedScore(user.getUsedScore())
.levelIcon(userScoreLevelVO.getIcon())
.levelName(userScoreLevelVO.getName())
.build();
userBackVO.setUserScoreLevelInfo(scoreLevelVO);
userBackVO.setPassword(null);
userBackVO.setBackLetterImg(null);
return success(userBackVO);
......
package cn.iocoder.yudao.module.member.controller.admin.user.vo;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserScoreLevelVO;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
......@@ -233,4 +234,26 @@ public class UserBackVO {
@ApiModelProperty(value = "是否简单密码", example = "false")
private Boolean isSimplePassword = Boolean.FALSE;
/**
* 客户编码
*/
@ApiModelProperty(value = "客户编码")
private String customerCode;
/**
* 客户编码
*/
@ApiModelProperty(value = "客户id")
private Long customerId;
@ApiModelProperty(value = "会员编码")
private String memberCode;
@ApiModelProperty(value = "会员积分信息")
private MemberUserScoreLevelVO userScoreLevelInfo;
@ApiModelProperty(value = "会员国家中文")
private String countryTitleZh;
@ApiModelProperty(value = "会员国家英文")
private String countryTitleEn;
@ApiModelProperty(value = "会员城市中文")
private String cityTitleZh;
@ApiModelProperty(value = "会员国家英文")
private String cityTitleEn;
}
......@@ -31,5 +31,8 @@ public class UserQueryVO {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "创建结束时间")
private Date endCreateTime;
@ApiModelProperty(value = "客户编码")
private String customerCode;
@ApiModelProperty(value = "会员编码")
private String memberCode;
}
......@@ -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;
}
......@@ -9,6 +9,7 @@ import lombok.*;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.Date;
import java.util.Optional;
/**
* 会员用户 DO
......@@ -235,6 +236,38 @@ public class MemberUserDO extends TenantBaseDO {
private Boolean isDeal;
private String code;
@TableField(exist = false)
private Integer holdScore;
@TableField(exist = false)
private Integer usedScore;
@TableField(exist = false)
private Integer expiredScore;
/**
* 客户编码
*/
@TableField(exist = false)
private String customerCode;
/**
* 客户编码
*/
@TableField(exist = false)
private Long customerId;
@TableField(exist = false)
private String memberCode;
@TableField(exist = false)
private String countryTitleZh;
@TableField(exist = false)
private String countryTitleEn;
@TableField(exist = false)
private String cityTitleZh;
@TableField(exist = false)
private String cityTitleEn;
public Integer getTotalScore() {
return Optional.ofNullable(holdScore).orElse(0)
+ Optional.ofNullable(usedScore).orElse(0)
+ Optional.ofNullable(expiredScore).orElse(0);
}
}
......@@ -161,12 +161,25 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
" uea.`create_time` as enterprise_audit_create_time,",
" uea.`audit_time` as enterprise_audit_time," ,
" uea.`audit_remark` as enterprise_audit_remark,",
" ifnull( mus.`hold_score`, 0) as hold_score",
" ec.id as customerId,",
" ec.number as customerCode,",
" u.code as memberCode,",
" er.title_zh as countryTitleZh,",
" er.title_en as countryTitleEn,",
" ert.title_zh as cityTitleZh,",
" ert.title_en as cityTitleEn,",
" ifnull( mus.`hold_score`, 0) as hold_score,",
" ifnull( mus.`used_score`, 0) as used_score,",
" ifnull( mus.`expired_score`, 0) as expired_score",
"from member_user u ",
"left join member_user_enterprise e on e.user_id = u.id and e.deleted = 0 ",
"left join member_user_card_auth uca on u.id = uca.user_id and uca.deleted = 0 " ,
"left join member_user_enterprise_auth uea on u.id = uea.user_id and uea.deleted = 0 ",
"left join member_user_score mus on u.id = mus.member_id and mus.deleted = 0 ",
"left join ecw_customer_contacts ecc on u.id = ecc.userid and ecc.is_default = 1 and ecc.deleted = 0",
"left join ecw_customer ec on ecc.customer_id = ec.id and ec.deleted = 0",
"left join ecw_region er on er.id = u.country",
"left join ecw_region ert on ert.id = u.city",
"where ",
"u.deleted = 0 ",
"AND u.id = #{id} ",
......
......@@ -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) {
......
......@@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.member.service.level;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.service.IService;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberUserLevelConfigDO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelBaseRespVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelReqVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelUpdateVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigBaseRespVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigReqVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigUpdateVO;
import java.util.List;
......@@ -16,11 +16,13 @@ import java.util.List;
*/
public interface MemberUserLevelConfigService extends IService<MemberUserLevelConfigDO> {
PageResult<MemberUserLevelBaseRespVO> getLevelPage(MemberUserLevelReqVO query);
PageResult<MemberUserLevelConfigBaseRespVO> getLevelPage(MemberUserLevelConfigReqVO query);
Boolean delete(List<Long> ids);
Boolean add(MemberUserLevelUpdateVO query);
Boolean add(MemberUserLevelConfigUpdateVO query);
Boolean updateLevel(MemberUserLevelUpdateVO query);
Boolean updateLevel(MemberUserLevelConfigUpdateVO query);
MemberUserLevelConfigBaseRespVO getLevelByCount(Integer scoreCount);
}
......@@ -5,10 +5,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberUserLevelConfigDO;
import cn.iocoder.yudao.module.member.dal.mysql.memberUserLevel.MemberUserLevelConfigMapper;
import cn.iocoder.yudao.module.member.vo.memberUserScore.MemberUserScoreBackVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelBaseRespVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelReqVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelUpdateVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigBaseRespVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigReqVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigUpdateVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
......@@ -17,11 +16,11 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.GET_LOCK_FAILED;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.LEVEL_BOUND_RANGE_CONFLICT;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.LEVEL_BOUND_RANGE_ERROR;
......@@ -42,14 +41,14 @@ public class MemberUserLevelConfigServiceImpl extends AbstractService<MemberUser
}
@Override
public PageResult<MemberUserLevelBaseRespVO> getLevelPage(MemberUserLevelReqVO query) {
public PageResult<MemberUserLevelConfigBaseRespVO> getLevelPage(MemberUserLevelConfigReqVO query) {
int start = (query.getPageNo() - 1) * query.getPageSize();
int size = query.getPageSize();
LambdaQueryWrapper<MemberUserLevelConfigDO> wrapper = Wrappers.lambdaQuery();
wrapper.eq(MemberUserLevelConfigDO::getDeleted, 0);
wrapper.last(String.format("limit %s, %s", start, size));
List<MemberUserLevelConfigDO> list = this.list(wrapper);
List<MemberUserLevelBaseRespVO> result = list.stream().map(i -> BeanUtil.copyProperties(i, MemberUserLevelBaseRespVO.class)).collect(Collectors.toList());
List<MemberUserLevelConfigBaseRespVO> result = list.stream().map(i -> BeanUtil.copyProperties(i, MemberUserLevelConfigBaseRespVO.class)).collect(Collectors.toList());
Long total = memberUserLevelConfigMapper.selectCount();
return new PageResult<>(result, total, query.getPageSize(), query.getPageNo(), (total + query.getPageSize() - 1) / query.getPageSize());
}
......@@ -66,13 +65,13 @@ public class MemberUserLevelConfigServiceImpl extends AbstractService<MemberUser
}
@Override
public Boolean add(MemberUserLevelUpdateVO query) {
public Boolean add(MemberUserLevelConfigUpdateVO query) {
validate(query);
MemberUserLevelConfigDO memberUserLevelConfigDO = BeanUtil.copyProperties(query, MemberUserLevelConfigDO.class);
return this.saveOrUpdate(memberUserLevelConfigDO);
}
private void validate(MemberUserLevelUpdateVO query) {
private void validate(MemberUserLevelConfigUpdateVO query) {
if (query.getLowerCount() > query.getUpperCount()) {
throw exception(LEVEL_BOUND_RANGE_ERROR);
}
......@@ -93,9 +92,20 @@ public class MemberUserLevelConfigServiceImpl extends AbstractService<MemberUser
}
@Override
public Boolean updateLevel(MemberUserLevelUpdateVO query) {
public Boolean updateLevel(MemberUserLevelConfigUpdateVO query) {
validate(query);
MemberUserLevelConfigDO memberUserLevelConfigDO = BeanUtil.copyProperties(query, MemberUserLevelConfigDO.class);
return this.saveOrUpdate(memberUserLevelConfigDO);
}
@Override
public MemberUserLevelConfigBaseRespVO getLevelByCount(Integer scoreCount) {
List<MemberUserLevelConfigDO> levelConfigList = this.list();
List<MemberUserLevelConfigDO> sortLevelConfig = levelConfigList.stream()
.sorted(Comparator.comparing(MemberUserLevelConfigDO::getLowerCount))
.collect(Collectors.toList());
MemberUserLevelConfigDO memberUserLevelConfigDO = sortLevelConfig.stream().filter(config -> config.getLowerCount() >= scoreCount && config.getUpperCount() <= scoreCount)
.findAny().orElse(sortLevelConfig.get(sortLevelConfig.size() - 1));
return BeanUtil.copyProperties(memberUserLevelConfigDO, MemberUserLevelConfigBaseRespVO.class);
}
}
......@@ -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);
}
}
......@@ -402,7 +402,12 @@ public class MemberUserServiceImpl implements MemberUserService {
if (query.getBeginCreateTime() != null && query.getEndCreateTime() != null) {
wrapper.between("create_time", query.getBeginCreateTime(), query.getEndCreateTime());
}
if (StringUtils.isNotBlank(query.getCustomerCode())) {
wrapper.like("customerCode", query.getCustomerCode());
}
if (StringUtils.isNotBlank(query.getMemberCode())) {
wrapper.like("code", query.getMemberCode());
}
//成交状态
Boolean isDeal = query.getIsDeal();
wrapper.apply(isDeal != null, "customer_status " + (Boolean.TRUE.equals(isDeal) ? " = 3 " : " != 3"), null);
......
......@@ -31,4 +31,6 @@ public class MemberUserScoreQueryVO extends PageParam {
private Date startTime;
@ApiModelProperty(value = "会员创建时间结束")
private Date endTime;
@ApiModelProperty(value = "会员id")
private Long memberId;
}
......@@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.member.vo.memberUserScoreLog;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......@@ -18,6 +20,7 @@ import java.util.Map;
@ApiModel("管理后台 - 积分记录查询 VO")
public class MemberUserScoreLogBackVO {
@ApiModelProperty(value = "积分记录id")
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@ApiModelProperty(value = "会员id")
private Long memberId;
......
......@@ -17,4 +17,5 @@ public class MemberUserScoreLogCreateReq {
private Integer sourceType;
private Long ruleId;
private Map<String, Object> extParam;
private String uniqueId;
}
......@@ -29,4 +29,6 @@ public class MemberUserScoreLogQueryVO extends PageParam {
private Date startTime;
@ApiModelProperty(value = "结束时间")
private Date endTime;
@ApiModelProperty(value = "会员id")
private Long memberId;
}
......@@ -6,7 +6,7 @@ import lombok.Data;
@Data
@ApiModel("管理后台 - 会员等级查询返回 VO")
public class MemberUserLevelBaseRespVO {
public class MemberUserLevelConfigBaseRespVO {
@ApiModelProperty(value = "id")
private Long id;
/**
......
......@@ -10,7 +10,7 @@ import lombok.Data;
*/
@Data
@ApiModel("管理后台 - 会员等级配置查询 VO")
public class MemberUserLevelReqVO extends PageParam {
public class MemberUserLevelConfigReqVO extends PageParam {
@ApiModelProperty(value = "id")
private Long id;
}
......@@ -8,7 +8,7 @@ import javax.validation.constraints.NotNull;
@Data
@ApiModel("管理后台 - 会员等级编辑 VO")
public class MemberUserLevelUpdateVO {
public class MemberUserLevelConfigUpdateVO {
@ApiModelProperty(value = "id")
private Long id;
/**
......
package cn.iocoder.yudao.module.member.vo.userLevel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@ApiModel("管理后台 - 会员积分等级 VO")
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MemberUserScoreLevelVO {
@ApiModelProperty(value = "会员id")
private Long memberId;
@ApiModelProperty(value = "会员编码")
private String memberCode;
@ApiModelProperty(value = "持有积分")
private Integer holdScore;
@ApiModelProperty(value = "已使用积分")
private Integer usedScore;
@ApiModelProperty(value = "过期积分")
private Integer expiredScore;
@ApiModelProperty(value = "会员等级名称")
private String levelName;
@ApiModelProperty(value = "会员等级图标")
private String levelIcon;
}
......@@ -24,10 +24,15 @@
uea.`create_time` as enterprise_audit_create_time,
uea.`audit_time` as enterprise_audit_time,
uea.`audit_remark` as enterprise_audit_remark
uea.`audit_remark` as enterprise_audit_remark,
ec.id as customerId,
ec.number as customerCode,
u.code as memberCode
from member_user u
left join member_user_card_auth uca on u.id = uca.user_id
left join member_user_enterprise_auth uea on u.id = uea.user_id
left join ecw_customer_contacts ecc on u.id = ecc.userid
left join ecw_customer ec on ec.id = ecc.customer_id
where 1 = 1
and uca.deleted = 0 or uca.deleted is null
</sql>
......
......@@ -68,5 +68,8 @@
and musl.score_count &lt; #{query.scoreCount}
</if>
</if>
<if test="query.memberId != null">
and musl.member_id = #{query.memberId}
</if>
</sql>
</mapper>
......@@ -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());
}
......
......@@ -86,14 +86,14 @@ public class RedeemRewardController {
@PostMapping("record/cancel/check")
@ApiOperation("撤销检查")
public CommonResult<RedeemCancelCheckRespVO> cancelCheck(@Valid @RequestBody RewardRedeemUpdateReqVO reqVO) {
return success(rewardRedeemService.cancelCheck(reqVO));
public CommonResult<RedeemCancelCheckRespVO> cancelCheck(@Valid @RequestBody RewardRedeemIdReqVO req) {
return success(rewardRedeemService.cancelCheck(req));
}
@PostMapping("record/cancel")
@ApiOperation("撤销")
public CommonResult<Boolean> cancel(@Valid @RequestBody RewardRedeemUpdateReqVO reqVO) {
return success(rewardRedeemService.cancel(reqVO));
public CommonResult<Boolean> cancel(@Valid @RequestBody RewardRedeemIdReqVO req) {
return success(rewardRedeemService.cancel(req));
}
@PostMapping("record/import/template")
......
......@@ -34,7 +34,7 @@ public interface RewardRedeemService extends IService<RewardRedeemDO> {
RecordInfoImportRespVO recordImport(List<RedeemInfoImportExcelVO> dataList);
Boolean cancel(RewardRedeemUpdateReqVO reqVO);
Boolean cancel(RewardRedeemIdReqVO req);
RedeemCancelCheckRespVO cancelCheck(RewardRedeemUpdateReqVO reqVO);
RedeemCancelCheckRespVO cancelCheck(RewardRedeemIdReqVO req);
}
......@@ -208,7 +208,7 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
@Override
public RecordInfoImportRespVO recordImport(List<RedeemInfoImportExcelVO> dataList) {
if (CollectionUtils.isEmpty(dataList)) {
return RecordInfoImportRespVO.builder().build();
return RecordInfoImportRespVO.builder().redeemIdFailedMap(Collections.emptyMap()).build();
}
if (dataList.size() > MAX_IMPORT_RECORD_COUNT) {
throw exception(ErrorCodeConstants.REDEEM_IMPORT_MAX_COUNT, MAX_IMPORT_RECORD_COUNT);
......@@ -241,17 +241,17 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
return rewardRedeemDO;
}).collect(Collectors.toList());
this.updateBatchById(saveDataList);
return RecordInfoImportRespVO.builder().build();
return RecordInfoImportRespVO.builder().redeemIdFailedMap(Collections.emptyMap()).build();
}
@Override
@Transactional
public Boolean cancel(RewardRedeemUpdateReqVO reqVO) {
@Transactional(rollbackFor = Exception.class)
public Boolean cancel(RewardRedeemIdReqVO req) {
//取消兑换 状态改为已取消 回退扣减的积分 ,如果存在已过期的积分,则直接过期
if (reqVO.getId() == null) {
if (req.getId() == null) {
throw exception(ErrorCodeConstants.REWARD_REDEEM_NOT_EXIST);
}
RewardRedeemDO rewardRedeemDO = this.getById(reqVO.getId());
RewardRedeemDO rewardRedeemDO = this.getById(req.getId());
if (rewardRedeemDO == null) {
throw exception(ErrorCodeConstants.REWARD_REDEEM_NOT_EXIST);
}
......@@ -259,7 +259,7 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
throw exception(ErrorCodeConstants.REDEEM_CANCEL_STATUS_ERROR);
}
LambdaUpdateWrapper<RewardRedeemDO> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(RewardRedeemDO::getId, reqVO.getId());
updateWrapper.eq(RewardRedeemDO::getId, req.getId());
updateWrapper.eq(RewardRedeemDO::getStatus, RewardRedeemStatusEnum.REDEEMING.getValue());
updateWrapper.set(RewardRedeemDO::getStatus, RewardRedeemStatusEnum.CANCELED.getValue());
boolean updateSuccess = this.update(null, updateWrapper);
......@@ -267,23 +267,21 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
throw exception(ErrorCodeConstants.REDEEM_CANCEL_STATUS_ERROR);
}
Map<String, Object> extParam = new HashMap<>();
extParam.put("redeemId", reqVO.getId());
extParam.put("redeemId", req.getId());
memberUserScoreApi.operateScore(MemberUserScoreOperateReqDTO.builder()
.memberId(rewardRedeemDO.getMemberId())
.sourceType(ScoreSourceTypeEnum.EXCHANGE_REWARD_CANCEL)
.scoreCount(rewardRedeemDO.getScoreCount())
.extParam(extParam)
.releationId(String.valueOf(reqVO.getId()))
.memberId(rewardRedeemDO.getMemberId())
.sourceType(ScoreSourceTypeEnum.EXCHANGE_REWARD_CANCEL)
.scoreCount(rewardRedeemDO.getScoreCount())
.extParam(extParam)
.releationId(String.valueOf(req.getId()))
.uniqueId(ScoreSourceTypeEnum.EXCHANGE_REWARD_CANCEL + "_" + req.getId())
.build());
return true;
}
@Override
public RedeemCancelCheckRespVO cancelCheck(RewardRedeemUpdateReqVO reqVO) {
if (reqVO.getId() == null) {
throw exception(ErrorCodeConstants.REWARD_REDEEM_NOT_EXIST);
}
RewardRedeemDO rewardRedeemDO = this.getById(reqVO.getId());
public RedeemCancelCheckRespVO cancelCheck(RewardRedeemIdReqVO req) {
RewardRedeemDO rewardRedeemDO = this.getById(req.getId());
if (rewardRedeemDO == null) {
throw exception(ErrorCodeConstants.REWARD_REDEEM_NOT_EXIST);
}
......@@ -291,7 +289,7 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
throw exception(ErrorCodeConstants.REDEEM_CANCEL_STATUS_ERROR);
}
List<ReleationScoreExpireInfoDTO> scoreExpireInfo = memberUserScoreApi
.getScoreExpireInfo(String.valueOf(reqVO.getId()), ScoreSourceTypeEnum.EXCHANGE_REWARD);
.getScoreExpireInfo(String.valueOf(req.getId()), ScoreSourceTypeEnum.EXCHANGE_REWARD);
int totalExpireScore = scoreExpireInfo.stream().filter(e -> e.getExpireDate() != null && e.getExpireDate().compareTo(new Date()) < 0)
.mapToInt(ReleationScoreExpireInfoDTO::getScoreCount).sum();
return RedeemCancelCheckRespVO.builder().expireCount(totalExpireScore).build();
......
package cn.iocoder.yudao.module.reward.vo.reward;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......@@ -8,6 +10,7 @@ import java.util.Date;
@Data
public class RewardRedeemBaseVO {
@ApiModelProperty(value = "id")
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 会员id
......
package cn.iocoder.yudao.module.reward.vo.reward;
import lombok.Data;
@Data
public class RewardRedeemIdReqVO {
private Long id;
}
......@@ -32,4 +32,6 @@ public class RewardRedeemPageReqVO extends PageParam {
private Integer entrance;
@ApiModelProperty(value = "兑换网点")
private Integer nodeId;
@ApiModelProperty(value = "会员id")
private Long memberId;
}
......@@ -36,4 +36,6 @@ public class RewardRedeemPageRespVO extends RewardRedeemBaseVO {
@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
......@@ -151,5 +154,8 @@
<if test="req.endTime != null ">
and err.create_time &lt;= #{req.endTime}
</if>
<if test="req.memberId != null">
and err.member_id = #{req.memberId}
</if>
</sql>
</mapper>
......@@ -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