Commit 702497cf authored by 332784038@qq.com's avatar 332784038@qq.com

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

parents 565acfa3 fb171e0f
...@@ -12,7 +12,11 @@ public enum ScoreSourceTypeEnum { ...@@ -12,7 +12,11 @@ public enum ScoreSourceTypeEnum {
SYSTEM_EXPIRED(3, "系统失效", ScoreOperateTypeEnum.REDUCE, null), SYSTEM_EXPIRED(3, "系统失效", ScoreOperateTypeEnum.REDUCE, null),
EXCHANGE_REWARD_CANCEL(4, "兑换礼品撤销", ScoreOperateTypeEnum.ADD, EXCHANGE_REWARD), EXCHANGE_REWARD_CANCEL(4, "兑换礼品撤销", ScoreOperateTypeEnum.ADD, EXCHANGE_REWARD),
;
ORDER_V(5, "订单V值", ScoreOperateTypeEnum.ADD, null),
REGISTER(6, "注册", ScoreOperateTypeEnum.ADD, null),
RECOMMEND(7, "推荐", ScoreOperateTypeEnum.ADD, null),
SHARE(8, "分享活动", ScoreOperateTypeEnum.ADD, null);
private final int value; private final int value;
...@@ -21,6 +25,7 @@ public enum ScoreSourceTypeEnum { ...@@ -21,6 +25,7 @@ public enum ScoreSourceTypeEnum {
private final ScoreOperateTypeEnum operateType; private final ScoreOperateTypeEnum operateType;
private final ScoreSourceTypeEnum reverseSource; private final ScoreSourceTypeEnum reverseSource;
ScoreSourceTypeEnum(int value, String name, ScoreOperateTypeEnum operateType, ScoreSourceTypeEnum reverseSource) { ScoreSourceTypeEnum(int value, String name, ScoreOperateTypeEnum operateType, ScoreSourceTypeEnum reverseSource) {
this.value = value; this.value = value;
this.name = name; this.name = name;
......
...@@ -49,10 +49,10 @@ ...@@ -49,10 +49,10 @@
<artifactId>yudao-module-depository-core</artifactId> <artifactId>yudao-module-depository-core</artifactId>
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<!-- <dependency>--> <dependency>
<!-- <groupId>cn.iocoder.boot</groupId>--> <groupId>cn.iocoder.boot</groupId>
<!-- <artifactId>yudao-module-order-core</artifactId>--> <artifactId>yudao-module-order-api</artifactId>
<!-- <version>${revision}</version>--> <version>${revision}</version>
<!-- </dependency>--> </dependency>
</dependencies> </dependencies>
</project> </project>
...@@ -40,7 +40,7 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*; ...@@ -40,7 +40,7 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
@Slf4j @Slf4j
@Service @Service
public class MemberUserScoreApiImpl implements MemberUserScoreApi{ public class MemberUserScoreApiImpl implements MemberUserScoreApi {
@Resource @Resource
private MemberUserScoreLogService logService; private MemberUserScoreLogService logService;
...@@ -75,7 +75,7 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{ ...@@ -75,7 +75,7 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
List<ScoreDetailChangeDto> detailInfos = saveScoreDetail(req, logId); List<ScoreDetailChangeDto> detailInfos = saveScoreDetail(req, logId);
saveScoreDetailReleation(req, detailInfos); saveScoreDetailReleation(req, detailInfos);
updateUserScore(req); updateUserScore(req);
publishDetailExpireEvent(req,detailInfos); publishDetailExpireEvent(req, detailInfos);
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw exception(GET_LOCK_FAILED); throw exception(GET_LOCK_FAILED);
} finally { } finally {
...@@ -85,7 +85,7 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{ ...@@ -85,7 +85,7 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
} }
private void publishDetailExpireEvent(MemberUserScoreOperateReqDTO req, List<ScoreDetailChangeDto> detailInfos) { private void publishDetailExpireEvent(MemberUserScoreOperateReqDTO req, List<ScoreDetailChangeDto> detailInfos) {
if (req.getSourceType().getReverseSource() == null || req.getOperateType() ==ScoreOperateTypeEnum.REDUCE) { if (req.getSourceType().getReverseSource() == null || req.getOperateType() == ScoreOperateTypeEnum.REDUCE) {
return; return;
} }
//判断回退流程,回退的积分是否过期.如果过期再走正常的过期扣积分流程 //判断回退流程,回退的积分是否过期.如果过期再走正常的过期扣积分流程
...@@ -122,12 +122,12 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{ ...@@ -122,12 +122,12 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
} }
} }
return req.getMemberIds().stream().map(memberId -> operateScore(MemberUserScoreOperateReqDTO.builder() return req.getMemberIds().stream().map(memberId -> operateScore(MemberUserScoreOperateReqDTO.builder()
.memberId(memberId) .memberId(memberId)
.scoreCount(req.getScoreCount()) .scoreCount(req.getScoreCount())
.operateType(req.getOperateType()) .operateType(req.getOperateType())
.sourceType(req.getSourceType()) .sourceType(req.getSourceType())
.extParam(req.getExtParam()) .extParam(req.getExtParam())
.build())) .build()))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
...@@ -158,24 +158,24 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{ ...@@ -158,24 +158,24 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
private void updateUserScore(MemberUserScoreOperateReqDTO req) { private void updateUserScore(MemberUserScoreOperateReqDTO req) {
memberUserScoreService.updateUserScore(MemberUserScoreUpdateReqDTO.builder() memberUserScoreService.updateUserScore(MemberUserScoreUpdateReqDTO.builder()
.memberId(req.getMemberId()) .memberId(req.getMemberId())
.scoreCount(req.getScoreCount()) .scoreCount(req.getScoreCount())
.operateType(req.getSourceType() == ScoreSourceTypeEnum.MANUAL_OPERATE ? .operateType(req.getSourceType() == ScoreSourceTypeEnum.MANUAL_OPERATE ?
req.getOperateType() : req.getSourceType().getOperateType()) req.getOperateType() : req.getSourceType().getOperateType())
.sourceType(req.getSourceType()) .sourceType(req.getSourceType())
.build()); .build());
} }
private List<ScoreDetailChangeDto> saveScoreDetail(MemberUserScoreOperateReqDTO req, Long scoreLogId) { private List<ScoreDetailChangeDto> saveScoreDetail(MemberUserScoreOperateReqDTO req, Long scoreLogId) {
return scoreDetailService.updateScoreDetail(MemberUserScoreDetailUpdateReqDto.builder() return scoreDetailService.updateScoreDetail(MemberUserScoreDetailUpdateReqDto.builder()
.memberId(req.getMemberId()) .memberId(req.getMemberId())
.scoreCount(req.getScoreCount()) .scoreCount(req.getScoreCount())
.operateType(req.getSourceType() == ScoreSourceTypeEnum.MANUAL_OPERATE ? .operateType(req.getSourceType() == ScoreSourceTypeEnum.MANUAL_OPERATE ?
req.getOperateType() : req.getSourceType().getOperateType()) req.getOperateType() : req.getSourceType().getOperateType())
.sourceType(req.getSourceType()) .sourceType(req.getSourceType())
.scoreLogId(scoreLogId) .scoreLogId(scoreLogId)
.expireDays(req.getExpireDays()) .expireDays(req.getExpireDays())
.releationId(req.getReleationId()) .releationId(req.getReleationId())
.build()); .build());
} }
...@@ -183,6 +183,7 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{ ...@@ -183,6 +183,7 @@ public class MemberUserScoreApiImpl implements MemberUserScoreApi{
return logService.createScoreLog(MemberUserScoreLogCreateReq.builder() return logService.createScoreLog(MemberUserScoreLogCreateReq.builder()
.memberId(req.getMemberId()) .memberId(req.getMemberId())
.scoreCount(req.getScoreCount()) .scoreCount(req.getScoreCount())
.ruleId(req.getRuleId())
.operateType(req.getSourceType() == ScoreSourceTypeEnum.MANUAL_OPERATE ? .operateType(req.getSourceType() == ScoreSourceTypeEnum.MANUAL_OPERATE ?
req.getOperateType().getValue() : req.getSourceType().getOperateType().getValue()) req.getOperateType().getValue() : req.getSourceType().getOperateType().getValue())
.sourceType(req.getSourceType().getValue()) .sourceType(req.getSourceType().getValue())
......
...@@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.member.controller.admin.level; ...@@ -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.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.service.level.MemberUserLevelConfigService; 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.MemberUserLevelConfigBaseRespVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelReqVO; import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigReqVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelUpdateVO; import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigUpdateVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
...@@ -35,7 +35,7 @@ public class MemberUserLevelConfigController { ...@@ -35,7 +35,7 @@ public class MemberUserLevelConfigController {
@PostMapping("/page") @PostMapping("/page")
@ApiOperation("列表") @ApiOperation("列表")
public CommonResult<PageResult<MemberUserLevelBaseRespVO>> getLevelPage(@Valid @RequestBody MemberUserLevelReqVO query) { public CommonResult<PageResult<MemberUserLevelConfigBaseRespVO>> getLevelPage(@Valid @RequestBody MemberUserLevelConfigReqVO query) {
return success(userLevelConfigService.getLevelPage(query)); return success(userLevelConfigService.getLevelPage(query));
} }
...@@ -47,13 +47,13 @@ public class MemberUserLevelConfigController { ...@@ -47,13 +47,13 @@ public class MemberUserLevelConfigController {
@PostMapping("/add") @PostMapping("/add")
@ApiOperation("新增") @ApiOperation("新增")
public CommonResult<Boolean> add(@Valid @RequestBody MemberUserLevelUpdateVO query) { public CommonResult<Boolean> add(@Valid @RequestBody MemberUserLevelConfigUpdateVO query) {
return success(userLevelConfigService.add(query)); return success(userLevelConfigService.add(query));
} }
@PostMapping("/update") @PostMapping("/update")
@ApiOperation("编辑") @ApiOperation("编辑")
public CommonResult<Boolean> update(@Valid @RequestBody MemberUserLevelUpdateVO query) { public CommonResult<Boolean> update(@Valid @RequestBody MemberUserLevelConfigUpdateVO query) {
return success(userLevelConfigService.updateLevel(query)); return success(userLevelConfigService.updateLevel(query));
} }
} }
package cn.iocoder.yudao.module.member.controller.admin.scoreRule; package cn.iocoder.yudao.module.member.controller.admin.scoreRule;
import cn.iocoder.yudao.framework.apollo.core.event.OrderInShippingEvent;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.util.ExcelUtils;
...@@ -15,6 +16,7 @@ import io.swagger.annotations.Api; ...@@ -15,6 +16,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.ListUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
...@@ -41,6 +43,8 @@ public class ScoreRuleController { ...@@ -41,6 +43,8 @@ public class ScoreRuleController {
private ScoreRuleService scoreRuleService; private ScoreRuleService scoreRuleService;
@Resource @Resource
private WarehouseService warehouseService; private WarehouseService warehouseService;
@Resource
private ApplicationContext applicationContext;
@PostMapping("/create") @PostMapping("/create")
@ApiOperation("创建积分规则") @ApiOperation("创建积分规则")
...@@ -119,6 +123,13 @@ public class ScoreRuleController { ...@@ -119,6 +123,13 @@ public class ScoreRuleController {
return success(list); return success(list);
} }
@GetMapping("/test-score-rule")
@ApiOperation("测试订单V值触发")
public CommonResult<Void> testScoreRule(@RequestParam Long orderId, @RequestParam String orderNo) {
applicationContext.publishEvent(new OrderInShippingEvent(orderId, orderNo));
return success(null);
}
@GetMapping("/export-excel") @GetMapping("/export-excel")
......
...@@ -27,6 +27,7 @@ import cn.iocoder.yudao.module.member.dal.dataobject.userEnterpriseAuth.UserEnte ...@@ -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.dal.dataobject.userOperationLog.UserOperationLogDO;
import cn.iocoder.yudao.module.member.enums.ErrorCodeConstants; import cn.iocoder.yudao.module.member.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.member.enums.UserAuditStatusEnum; 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.user.MemberUserService;
import cn.iocoder.yudao.module.member.service.userCardAuth.UserCardAuthService; import cn.iocoder.yudao.module.member.service.userCardAuth.UserCardAuthService;
import cn.iocoder.yudao.module.member.service.userEnterpriseAuth.UserEnterpriseAuthService; import cn.iocoder.yudao.module.member.service.userEnterpriseAuth.UserEnterpriseAuthService;
...@@ -35,6 +36,8 @@ import cn.iocoder.yudao.module.member.vo.userCardAuth.UserCardAuthBackVO; ...@@ -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.userCardAuth.UserCardAuthCreateReqVO;
import cn.iocoder.yudao.module.member.vo.userEnterpriseAuth.UserEnterpriseAuthBackVO; 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.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 cn.iocoder.yudao.module.member.vo.userOperationLog.UserOperationLogBackVO;
import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
...@@ -95,6 +98,9 @@ public class MemberUserController { ...@@ -95,6 +98,9 @@ public class MemberUserController {
@Resource @Resource
private PasswordEncoder passwordEncoder; private PasswordEncoder passwordEncoder;
@Resource
private MemberUserLevelConfigService memberUserLevelConfigService;
@GetMapping("/member-user-list") @GetMapping("/member-user-list")
@ApiOperation("获得会员帐号列表-下拉列表使用") @ApiOperation("获得会员帐号列表-下拉列表使用")
...@@ -136,6 +142,16 @@ public class MemberUserController { ...@@ -136,6 +142,16 @@ public class MemberUserController {
if (passwordEncoder.matches("88888888", user.getPassword())) { if (passwordEncoder.matches("88888888", user.getPassword())) {
userBackVO.setIsSimplePassword(Boolean.TRUE); 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.setPassword(null);
userBackVO.setBackLetterImg(null); userBackVO.setBackLetterImg(null);
return success(userBackVO); return success(userBackVO);
......
package cn.iocoder.yudao.module.member.controller.admin.user.vo; 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.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
...@@ -233,4 +234,26 @@ public class UserBackVO { ...@@ -233,4 +234,26 @@ public class UserBackVO {
@ApiModelProperty(value = "是否简单密码", example = "false") @ApiModelProperty(value = "是否简单密码", example = "false")
private Boolean isSimplePassword = Boolean.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 { ...@@ -31,5 +31,8 @@ public class UserQueryVO {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "创建结束时间") @ApiModelProperty(value = "创建结束时间")
private Date endCreateTime; private Date endCreateTime;
@ApiModelProperty(value = "客户编码")
private String customerCode;
@ApiModelProperty(value = "会员编码")
private String memberCode;
} }
...@@ -9,6 +9,7 @@ import lombok.*; ...@@ -9,6 +9,7 @@ import lombok.*;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.Date; import java.util.Date;
import java.util.Optional;
/** /**
* 会员用户 DO * 会员用户 DO
...@@ -237,4 +238,36 @@ public class MemberUserDO extends TenantBaseDO { ...@@ -237,4 +238,36 @@ public class MemberUserDO extends TenantBaseDO {
private String code; private String code;
private Integer holdScore; private Integer holdScore;
private Integer usedScore;
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> { ...@@ -161,12 +161,25 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
" uea.`create_time` as enterprise_audit_create_time,", " uea.`create_time` as enterprise_audit_create_time,",
" uea.`audit_time` as enterprise_audit_time," , " uea.`audit_time` as enterprise_audit_time," ,
" uea.`audit_remark` as enterprise_audit_remark,", " 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 ", "from member_user u ",
"left join member_user_enterprise e on e.user_id = u.id and e.deleted = 0 ", "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_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_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 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 ", "where ",
"u.deleted = 0 ", "u.deleted = 0 ",
"AND u.id = #{id} ", "AND u.id = #{id} ",
......
//package cn.iocoder.yudao.module.member.listener; package cn.iocoder.yudao.module.member.listener;
//
//import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.collection.CollUtil;
//import cn.hutool.json.JSONUtil; import cn.hutool.core.util.ArrayUtil;
//import cn.iocoder.yudao.framework.apollo.core.event.OrderInShippingEvent; import cn.hutool.json.JSONUtil;
//import cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi; import cn.iocoder.boot.module.order.api.OrderApi;
//import cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateReqDTO; import cn.iocoder.boot.module.order.api.dto.OrderObjectiveApiDO;
//import cn.iocoder.yudao.module.member.dal.dataobject.scoreRule.ScoreRuleDO; import cn.iocoder.boot.module.order.api.dto.OrderRespDTO;
//import cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum; import cn.iocoder.boot.module.order.enums.OrderStatusApiEnum;
//import cn.iocoder.yudao.module.member.enums.TransportTypeEnum; import cn.iocoder.yudao.framework.apollo.core.event.OrderInShippingEvent;
//import cn.iocoder.yudao.module.member.enums.YesOrNoTypeEnum; import cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi;
//import cn.iocoder.yudao.module.member.service.memberUserScoreLog.MemberUserScoreLogService; import cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateReqDTO;
//import cn.iocoder.yudao.module.member.service.scoreRule.ScoreRuleService; import cn.iocoder.yudao.module.member.dal.dataobject.scoreLog.MemberUserScoreLogDO;
//import cn.iocoder.yudao.module.member.vo.scoreRule.extra.ScoreRuleOrderVExtraVO; import cn.iocoder.yudao.module.member.dal.dataobject.scoreRule.ScoreRuleDO;
//import cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO; import cn.iocoder.yudao.module.member.enums.PlatformTypeEnum;
//import cn.iocoder.yudao.module.order.dal.dataobject.orderObjective.OrderObjectiveDO; import cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum;
//import cn.iocoder.yudao.module.order.enums.OrderStatusEnum; import cn.iocoder.yudao.module.member.enums.TransportTypeEnum;
//import cn.iocoder.yudao.module.order.service.order.OrderService; import cn.iocoder.yudao.module.member.enums.YesOrNoTypeEnum;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import cn.iocoder.yudao.module.member.service.scoreLog.MemberUserScoreLogService;
//import lombok.AllArgsConstructor; import cn.iocoder.yudao.module.member.service.scoreRule.ScoreRuleService;
//import lombok.extern.slf4j.Slf4j; import cn.iocoder.yudao.module.member.vo.scoreRule.extra.ScoreRuleOrderVExtraVO;
//import org.springframework.context.event.EventListener; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import org.springframework.stereotype.Component; import lombok.AllArgsConstructor;
// import lombok.extern.slf4j.Slf4j;
//import javax.annotation.Resource; import org.apache.commons.lang3.StringUtils;
//import java.math.BigDecimal; import org.springframework.context.event.EventListener;
//import java.math.RoundingMode; import org.springframework.stereotype.Component;
//import java.util.Date;
//import java.util.List; import javax.annotation.Resource;
//import java.util.Objects; import java.math.BigDecimal;
// import java.math.RoundingMode;
//@Component import java.util.Date;
//@AllArgsConstructor import java.util.HashMap;
//@Slf4j import java.util.List;
//public class OrderInShippingListener { import java.util.Objects;
// @Resource
// private OrderService orderService; @Component
// @Resource @AllArgsConstructor
// private ScoreRuleService scoreRuleService; @Slf4j
// @Resource public class OrderInShippingListener {
// private MemberUserScoreApi memberUserScoreApi; @Resource
// @Resource private OrderApi orderApi;
// private MemberUserScoreLogService memberUserScoreLogService; @Resource
// private ScoreRuleService scoreRuleService;
// @EventListener(OrderInShippingEvent.class) @Resource
// public void listen(OrderInShippingEvent event) { private MemberUserScoreApi memberUserScoreApi;
// Long orderId = event.getOrderId(); @Resource
// String orderNo = event.getOrderNo(); private MemberUserScoreLogService memberUserScoreLogService;
// OrderDO orderDO;
// if (orderId != null) { @EventListener(OrderInShippingEvent.class)
// orderDO = orderService.getById(orderId); public void listen(OrderInShippingEvent event) {
// } else { Long orderId = event.getOrderId();
// orderDO = orderService.selectOne(new LambdaQueryWrapper<OrderDO>().eq(OrderDO::getOrderNo, orderNo).last("limit 1")); String orderNo = event.getOrderNo();
// } OrderRespDTO order;
// if (Objects.isNull(orderDO)) { try {
// log.error("Order in shipping listening error: The order does not exist,orderId:{},orderNo:{}", orderId, orderNo); order = orderApi.getOrder(orderId, orderNo);
// } } catch (Exception e) {
// // 目的地信息 log.error("Order in shipping listener: Get order error,orderId:{},orderNo:{}", orderId, orderNo);
// OrderObjectiveDO orderObjectiveDO = orderDO.getOrderObjectiveDO(); return;
// // 订单状态应为起运 }
// if (!Objects.equals(orderDO.getStatus(), OrderStatusEnum.IN_SHIPPING.getValue())) { if (Objects.isNull(order)) {
// return; log.error("Order in shipping listener: The order does not exist,orderId:{},orderNo:{}", orderId, orderNo);
// } return;
// // 判断海运空运 }
// Integer transportId = orderDO.getTransportId(); // 订单状态应为起运
// ScoreRuleDO scoreRuleDO = scoreRuleService.getEnabledOrderVScoreRuleByTransportType(transportId); if (!Objects.equals(order.getStatus(), OrderStatusApiEnum.IN_SHIPPING.getValue())) {
// if (Objects.isNull(scoreRuleDO)) { return;
// log.info("No score rule match"); }
// return; // 判断海运空运
// } Integer transportId = order.getTransportId();
// // 是否过期 ScoreRuleDO scoreRuleDO = scoreRuleService.getEnabledOrderVScoreRuleByTransportType(transportId);
// if (scoreRuleDO.getEndTime().after(new Date())) { if (Objects.isNull(scoreRuleDO)) {
// log.info("The score rule has expired"); log.info("Order in shipping listener: No score rule match");
// return; return;
// } }
// ScoreRuleOrderVExtraVO extraInfo = JSONUtil.toBean(scoreRuleDO.getExtra(), ScoreRuleOrderVExtraVO.class); // 是否过期,或者活动还没开始
// // 是否首单,首单只加一次 if (!scoreRuleDO.getEndTime().after(new Date()) || !scoreRuleDO.getStartTime().before(new Date())) {
// if (extraInfo.getFirstOrder() == YesOrNoTypeEnum.YES.ordinal()){ log.info("Order in shipping listener: The score rule has expired");
// Long count = orderService.selectCount(new LambdaQueryWrapper<OrderDO>().eq(OrderDO::getUserId, orderDO.getUserId())); return;
// if (count > 1) { }
// log.info("Not first order"); // 目的地信息
// return; OrderObjectiveApiDO orderObjectiveDO = order.getOrderObjectiveDO();
// } ScoreRuleOrderVExtraVO extraInfo = JSONUtil.toBean(scoreRuleDO.getExtra(), ScoreRuleOrderVExtraVO.class);
// } // 提货点是否包含
// // 提货点是否包含 String[] warehouseIds = extraInfo.getReceiveAddr().split(",");
// String[] warehouseIds = extraInfo.getReceiveAddr().split(","); if (!ArrayUtil.contains(warehouseIds, orderObjectiveDO.getObjectiveWarehouseId().toString())) {
// if (!ArrayUtil.contains(warehouseIds, orderObjectiveDO.getObjectiveWarehouseId().toString())) { return;
// return; }
// } // 计算积分
// // 计算积分 List<ScoreRuleOrderVExtraVO.OrderVRule> orderVRules = extraInfo.getOrderVRule();
// Integer scoreCount = 0; Integer scoreCount = 0;
// List<ScoreRuleOrderVExtraVO.OrderVRule> orderVRule = extraInfo.getOrderVRule(); if (transportId == TransportTypeEnum.OCEAN_LCL.getValue()) {
// if (transportId == TransportTypeEnum.OCEAN_LCL.getValue()) { // 海运算重量
// // 海运算重量 BigDecimal orgVWeight = order.getOrgVWeight();
// BigDecimal orgVWeight = orderDO.getOrgVWeight(); scoreCount = computeScoreCount(orgVWeight, orderVRules);
// int w = orgVWeight.setScale(0, RoundingMode.HALF_UP).intValue(); } else if (transportId == TransportTypeEnum.SPECIAL_LINE_AIR_FREIGHT.getValue()) {
// for (ScoreRuleOrderVExtraVO.OrderVRule rule : orderVRule) { // 空运校验渠道
// if (rule.getLow() <= w && rule.getHigh() >= w) { // 渠道id
// scoreCount = rule.getScore(); Long channelId = order.getChannelId();
// break; String[] channels = extraInfo.getChannel().split(",");
// } if (!ArrayUtil.contains(channels, channelId.toString())) {
// } return;
// } else if (transportId == TransportTypeEnum.SPECIAL_LINE_AIR_FREIGHT.getValue()) { }
// // 空运校验渠道 // 空运算体积
// // 渠道id BigDecimal orgWVolume = order.getOrgWVolume();
// Long channelId = orderDO.getChannelId(); scoreCount = computeScoreCount(orgWVolume, orderVRules);
// String[] channels = extraInfo.getChannel().split(","); }
// if (!ArrayUtil.contains(channels, channelId.toString())) { if (scoreCount > scoreRuleDO.getGetScoreOnce()) {
// return; scoreCount = scoreRuleDO.getGetScoreOnce();
// } }
// // 空运算体积
// BigDecimal orgWVolume = orderDO.getOrgWVolume(); // 会员id
// int v = orgWVolume.setScale(0, RoundingMode.HALF_UP).intValue(); Long userId = order.getUserId();
// for (ScoreRuleOrderVExtraVO.OrderVRule rule : orderVRule) { // 订单入口
// if (rule.getLow() <= v && rule.getHigh() >= v) { String orderEntryString = extraInfo.getOrderEntry();
// scoreCount = rule.getScore(); if (StringUtils.isBlank(orderEntryString)) {
// break; log.info("Order in shipping listener: orderEntry is null");
// } return;
// } }
// } String[] orderEntry = orderEntryString.split(",");
// if (scoreCount > scoreRuleDO.getGetScoreOnce()){ // TODO:后台下单会员获取待确认
// scoreCount = scoreRuleDO.getGetScoreOnce(); if (userId <= 0) {
// } // 后台下单
// // 校验累计最高分,查member_user_score_log if (!ArrayUtil.contains(orderEntry, String.valueOf(PlatformTypeEnum.BACKEND.getValue()))) {
// log.info("Order in shipping listener: The order is placed by the background, userId:{}", userId);
// // 增加积分 return;
// // 会员id }
// Long userId = orderDO.getUserId(); //userId = order.getCustomerId();
// memberUserScoreApi.operateScore(MemberUserScoreOperateReqDTO.builder() } else if (!ArrayUtil.contains(orderEntry, String.valueOf(PlatformTypeEnum.APP.getValue())) && !ArrayUtil.contains(orderEntry, String.valueOf(PlatformTypeEnum.WEB.getValue()))) {
// .memberId(userId) log.info("Order in shipping listener: The order is placed by the app or web, userId:{}", userId);
// .scoreCount(scoreCount) return;
// .sourceType(ScoreSourceTypeEnum.EXCHANGE_REWARD) }
// .ruleId(scoreRuleDO.getId()) // 是否首单,首单只加一次
// .expireDays(scoreRuleDO.getScorePeriod()) if (extraInfo.getFirstOrder() == YesOrNoTypeEnum.YES.ordinal()) {
// .build() if (!orderApi.isFirstOrder(userId)) {
// ); log.info("Order in shipping listener: Not first order");
// } 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("Order in shipping listener: The user has reached the maximum score,userId:{},scoreRuleId:{}", userId, scoreRuleDO.getId());
return;
}
//if (userScoreTotalCount + scoreCount > scoreRuleDO.getMaxScoreTotal()) {
// scoreCount = scoreRuleDO.getMaxScoreTotal() - userScoreTotalCount;
//}
// 增加积分
try {
HashMap<String, Object> map = new HashMap<>();
map.put("orderId", orderId);
memberUserScoreApi.operateScore(MemberUserScoreOperateReqDTO.builder()
.memberId(userId)
.scoreCount(scoreCount)
.sourceType(ScoreSourceTypeEnum.ORDER_V)
.ruleId(scoreRuleDO.getId())
.expireDays(scoreRuleDO.getScorePeriod())
.extParam(map)
.build()
);
} catch (Exception e) {
log.error("Order in shipping listener: operateScore error", e);
}
}
/**
* 根据规则计算获取积分
*
* @param weightOrVolume 重量或体积
* @param orderVRules 规则
* @return
*/
private Integer computeScoreCount(BigDecimal weightOrVolume, List<ScoreRuleOrderVExtraVO.OrderVRule> orderVRules) {
Integer scoreCount = 0;
int w = weightOrVolume.setScale(0, RoundingMode.HALF_UP).intValue();
for (int i = orderVRules.size() - 1; i >= 0; i--) {
ScoreRuleOrderVExtraVO.OrderVRule orderVRule = orderVRules.get(i);
if (w > orderVRule.getHigh()) {
scoreCount = orderVRule.getScore();
break;
}
if (orderVRule.getLow() <= w && orderVRule.getHigh() > w) {
scoreCount = orderVRule.getScore();
break;
}
}
return scoreCount;
}
}
...@@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.member.service.level; ...@@ -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.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.service.IService; 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.dal.dataobject.level.MemberUserLevelConfigDO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelBaseRespVO; import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigBaseRespVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelReqVO; import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigReqVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelUpdateVO; import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigUpdateVO;
import java.util.List; import java.util.List;
...@@ -16,11 +16,13 @@ import java.util.List; ...@@ -16,11 +16,13 @@ import java.util.List;
*/ */
public interface MemberUserLevelConfigService extends IService<MemberUserLevelConfigDO> { public interface MemberUserLevelConfigService extends IService<MemberUserLevelConfigDO> {
PageResult<MemberUserLevelBaseRespVO> getLevelPage(MemberUserLevelReqVO query); PageResult<MemberUserLevelConfigBaseRespVO> getLevelPage(MemberUserLevelConfigReqVO query);
Boolean delete(List<Long> ids); 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; ...@@ -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.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberUserLevelConfigDO; 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.dal.mysql.memberUserLevel.MemberUserLevelConfigMapper;
import cn.iocoder.yudao.module.member.vo.memberUserScore.MemberUserScoreBackVO; import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigBaseRespVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelBaseRespVO; import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigReqVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelReqVO; import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelConfigUpdateVO;
import cn.iocoder.yudao.module.member.vo.userLevel.MemberUserLevelUpdateVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
...@@ -17,11 +16,11 @@ import org.springframework.context.annotation.Lazy; ...@@ -17,11 +16,11 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 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_CONFLICT;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.LEVEL_BOUND_RANGE_ERROR; import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.LEVEL_BOUND_RANGE_ERROR;
...@@ -42,14 +41,14 @@ public class MemberUserLevelConfigServiceImpl extends AbstractService<MemberUser ...@@ -42,14 +41,14 @@ public class MemberUserLevelConfigServiceImpl extends AbstractService<MemberUser
} }
@Override @Override
public PageResult<MemberUserLevelBaseRespVO> getLevelPage(MemberUserLevelReqVO query) { public PageResult<MemberUserLevelConfigBaseRespVO> getLevelPage(MemberUserLevelConfigReqVO query) {
int start = (query.getPageNo() - 1) * query.getPageSize(); int start = (query.getPageNo() - 1) * query.getPageSize();
int size = query.getPageSize(); int size = query.getPageSize();
LambdaQueryWrapper<MemberUserLevelConfigDO> wrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<MemberUserLevelConfigDO> wrapper = Wrappers.lambdaQuery();
wrapper.eq(MemberUserLevelConfigDO::getDeleted, 0); wrapper.eq(MemberUserLevelConfigDO::getDeleted, 0);
wrapper.last(String.format("limit %s, %s", start, size)); wrapper.last(String.format("limit %s, %s", start, size));
List<MemberUserLevelConfigDO> list = this.list(wrapper); 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(); Long total = memberUserLevelConfigMapper.selectCount();
return new PageResult<>(result, total, query.getPageSize(), query.getPageNo(), (total + query.getPageSize() - 1) / query.getPageSize()); 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 ...@@ -66,13 +65,13 @@ public class MemberUserLevelConfigServiceImpl extends AbstractService<MemberUser
} }
@Override @Override
public Boolean add(MemberUserLevelUpdateVO query) { public Boolean add(MemberUserLevelConfigUpdateVO query) {
validate(query); validate(query);
MemberUserLevelConfigDO memberUserLevelConfigDO = BeanUtil.copyProperties(query, MemberUserLevelConfigDO.class); MemberUserLevelConfigDO memberUserLevelConfigDO = BeanUtil.copyProperties(query, MemberUserLevelConfigDO.class);
return this.saveOrUpdate(memberUserLevelConfigDO); return this.saveOrUpdate(memberUserLevelConfigDO);
} }
private void validate(MemberUserLevelUpdateVO query) { private void validate(MemberUserLevelConfigUpdateVO query) {
if (query.getLowerCount() > query.getUpperCount()) { if (query.getLowerCount() > query.getUpperCount()) {
throw exception(LEVEL_BOUND_RANGE_ERROR); throw exception(LEVEL_BOUND_RANGE_ERROR);
} }
...@@ -93,9 +92,20 @@ public class MemberUserLevelConfigServiceImpl extends AbstractService<MemberUser ...@@ -93,9 +92,20 @@ public class MemberUserLevelConfigServiceImpl extends AbstractService<MemberUser
} }
@Override @Override
public Boolean updateLevel(MemberUserLevelUpdateVO query) { public Boolean updateLevel(MemberUserLevelConfigUpdateVO query) {
validate(query); validate(query);
MemberUserLevelConfigDO memberUserLevelConfigDO = BeanUtil.copyProperties(query, MemberUserLevelConfigDO.class); MemberUserLevelConfigDO memberUserLevelConfigDO = BeanUtil.copyProperties(query, MemberUserLevelConfigDO.class);
return this.saveOrUpdate(memberUserLevelConfigDO); 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);
}
} }
...@@ -402,7 +402,12 @@ public class MemberUserServiceImpl implements MemberUserService { ...@@ -402,7 +402,12 @@ public class MemberUserServiceImpl implements MemberUserService {
if (query.getBeginCreateTime() != null && query.getEndCreateTime() != null) { if (query.getBeginCreateTime() != null && query.getEndCreateTime() != null) {
wrapper.between("create_time", query.getBeginCreateTime(), query.getEndCreateTime()); 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(); Boolean isDeal = query.getIsDeal();
wrapper.apply(isDeal != null, "customer_status " + (Boolean.TRUE.equals(isDeal) ? " = 3 " : " != 3"), null); wrapper.apply(isDeal != null, "customer_status " + (Boolean.TRUE.equals(isDeal) ? " = 3 " : " != 3"), null);
......
...@@ -31,4 +31,6 @@ public class MemberUserScoreQueryVO extends PageParam { ...@@ -31,4 +31,6 @@ public class MemberUserScoreQueryVO extends PageParam {
private Date startTime; private Date startTime;
@ApiModelProperty(value = "会员创建时间结束") @ApiModelProperty(value = "会员创建时间结束")
private Date endTime; private Date endTime;
@ApiModelProperty(value = "会员id")
private Long memberId;
} }
...@@ -29,4 +29,6 @@ public class MemberUserScoreLogQueryVO extends PageParam { ...@@ -29,4 +29,6 @@ public class MemberUserScoreLogQueryVO extends PageParam {
private Date startTime; private Date startTime;
@ApiModelProperty(value = "结束时间") @ApiModelProperty(value = "结束时间")
private Date endTime; private Date endTime;
@ApiModelProperty(value = "会员id")
private Long memberId;
} }
...@@ -6,7 +6,7 @@ import lombok.Data; ...@@ -6,7 +6,7 @@ import lombok.Data;
@Data @Data
@ApiModel("管理后台 - 会员等级查询返回 VO") @ApiModel("管理后台 - 会员等级查询返回 VO")
public class MemberUserLevelBaseRespVO { public class MemberUserLevelConfigBaseRespVO {
@ApiModelProperty(value = "id") @ApiModelProperty(value = "id")
private Long id; private Long id;
/** /**
......
...@@ -10,7 +10,7 @@ import lombok.Data; ...@@ -10,7 +10,7 @@ import lombok.Data;
*/ */
@Data @Data
@ApiModel("管理后台 - 会员等级配置查询 VO") @ApiModel("管理后台 - 会员等级配置查询 VO")
public class MemberUserLevelReqVO extends PageParam { public class MemberUserLevelConfigReqVO extends PageParam {
@ApiModelProperty(value = "id") @ApiModelProperty(value = "id")
private Long id; private Long id;
} }
...@@ -8,7 +8,7 @@ import javax.validation.constraints.NotNull; ...@@ -8,7 +8,7 @@ import javax.validation.constraints.NotNull;
@Data @Data
@ApiModel("管理后台 - 会员等级编辑 VO") @ApiModel("管理后台 - 会员等级编辑 VO")
public class MemberUserLevelUpdateVO { public class MemberUserLevelConfigUpdateVO {
@ApiModelProperty(value = "id") @ApiModelProperty(value = "id")
private Long 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 @@ ...@@ -24,10 +24,15 @@
uea.`create_time` as enterprise_audit_create_time, uea.`create_time` as enterprise_audit_create_time,
uea.`audit_time` as enterprise_audit_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 from member_user u
left join member_user_card_auth uca on u.id = uca.user_id 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 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 where 1 = 1
and uca.deleted = 0 or uca.deleted is null and uca.deleted = 0 or uca.deleted is null
</sql> </sql>
......
...@@ -68,5 +68,8 @@ ...@@ -68,5 +68,8 @@
and musl.score_count &lt; #{query.scoreCount} and musl.score_count &lt; #{query.scoreCount}
</if> </if>
</if> </if>
<if test="query.memberId != null">
and musl.member_id = #{query.memberId}
</if>
</sql> </sql>
</mapper> </mapper>
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
<modules> <modules>
<module>yudao-module-order-core</module> <module>yudao-module-order-core</module>
<module>yudao-module-order-rest</module> <module>yudao-module-order-rest</module>
<module>yudao-module-order-api</module>
</modules> </modules>
<description> <description>
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-order</artifactId>
<version>${revision}</version>
</parent>
<artifactId>yudao-module-order-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package cn.iocoder.boot.module.order.api;
import cn.iocoder.boot.module.order.api.dto.OrderRespDTO;
/**
* 订单 api
*/
public interface OrderApi {
/**
* 根据订单id或编号获取订单
*/
OrderRespDTO getOrder(Long id, String orderNo);
/**
* 判断是否用户首单
*/
boolean isFirstOrder(Long userId);
}
package cn.iocoder.boot.module.order.api.dto;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
/**
* 订单目的仓库
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class OrderObjectiveApiDO extends BaseDO {
/**
* 主键ID
*/
private Long id;
/**
* 订单id
*/
private Long orderId;
/**
* 目的地id
*/
private Long objectiveId;
@ApiModelProperty(value = "目的国家id")
private Long objectiveCountryId;
@ApiModelProperty(value = "目的仓库id")
private Long objectiveWarehouseId;
/**
* 目的地详情
*/
private String objective;
/**
* 0调仓标志;1原始数据,实际的目的地仓库
*/
private Integer type;
/**
* 货到没到这个仓库:0未到;1已到
*/
private Boolean isThis;
}
package cn.iocoder.boot.module.order.api.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderRespDTO {
/**
* 主键ID
*/
private Long orderId;
/**
* 订单编号
*/
private String orderNo;
/**
* 快递单号
*/
private String number;
/**
* 运输方式id
*/
private Integer transportId;
/**
* 渠道ID
*/
private Long channelId;
/**
* 订单类型(可多选):1 集运服务 2 海外仓
*/
private String type;
/**
* 下单会员id
*/
private Long userId;
/**
* 客户经理ID
*/
private Long salesmanId;
/**
* 部门ID
*/
private Long deptId;
/**
* 唛头
*/
private String marks;
/**
* 订单状态详情见字典
*/
private Integer status;
/**
* 订单异常状态(字典 order_abnormal_state)
*/
private Integer abnormalState;
/**
* 订单入仓状态(字典 order_warehouse_in_status)
*/
private Integer inWarehouseState;
/**
* 订单出货状态(字典 order_shipment_state)
*/
private Integer shipmentState;
/**
* 上次订单主状态值
*/
private Integer oldStatus;
/**
* 上次订单入仓状态值
*/
private Integer oldInWarehouseState;
/**
* 上次订单出货状态值
*/
private Integer oldShipmentState;
/**
* 是否被删掉 1 删掉;0正常
*/
private Boolean isDel;
@ApiModelProperty(value = "代收金额")
private BigDecimal collectionProxy;
@ApiModelProperty(value = "代收货币ID")
private Integer collectionProxyCurrency;
/**
* 是否代收货款收款 0为否 1为是
*/
private Boolean isCollection;
/**
* 重货体积
*/
private BigDecimal wVolume;
/**
* 泡货重量
*/
private BigDecimal vWeight;
/**
* 原应收重货体积
*/
private BigDecimal orgWVolume;
/**
* 原应收泡货重量
*/
private BigDecimal orgVWeight;
@ApiModelProperty(value = "最小计量重量")
private BigDecimal minMeteringWeight = BigDecimal.ZERO;
@ApiModelProperty(value = "最小计量体积")
private BigDecimal minMeteringVolume = BigDecimal.ZERO;
@ApiModelProperty(value = "最小计量个数")
private BigDecimal minMeteringQuantity = BigDecimal.ZERO;
/**
* 重货标准基数
*/
private BigDecimal weightUnit;
/**
* 泡货标准基数
*/
private BigDecimal volumeUnit;
@ApiModelProperty(value = "原重货标准基数")
private BigDecimal orgWeightUnit;
@ApiModelProperty(value = "原泡货标准基数")
private BigDecimal orgVolumeUnit;
@ApiModelProperty(value = "计算使用的重货标准基数")
private BigDecimal useWeightUnit;
@ApiModelProperty(value = "计算使用的泡货标准基数")
private BigDecimal useVolumeUnit;
/**
* 入仓类型
*/
private Integer warehouseType;
/**
* 备注
*/
private String remarks;
/**
* 调仓始发仓
*/
private Long adjustToStartWarehouseId;
/**
* 调仓目的仓
*/
private Long adjustToDestWarehouseId;
/**
* 目的地调仓始发仓
*/
private Long destAdjustToStartWarehouseId;
/**
* 目的地调仓目的仓
*/
private Long destAdjustToDestWarehouseId;
@ApiModelProperty(value = "入仓数量", required = true)
private Integer sumQuantity;
/**
* 入仓件数
*/
private Integer sumNum;
/**
* 自定义入仓体积
*/
private BigDecimal customSumVolume;
/**
* 入仓体积
*/
private BigDecimal sumVolume;
/**
* 自定义入仓重量
*/
private BigDecimal customSumWeight;
/**
* 入仓重量
*/
private BigDecimal sumWeight;
/**
* 重货比
*/
private BigDecimal weightRatio;
/**
* 发货人的客户id
*/
private Long customerId;
/**
* 完成入仓的入仓体积
*/
private BigDecimal sumVolumeFinishedWarehouseIn;
/**
* 完成入仓的入仓重量
*/
private BigDecimal sumWeightFinishedWarehouseIn;
/**
* 完成入仓的箱/件数
*/
private Integer sumCartonsNumFinishedWarehouseIn;
/**
* 完成入仓的所有箱内总货物数量
*/
private Integer sumQuantityAllFinishedWarehouseIn;
/**
* 上次打包的入仓体积
*/
@ApiModelProperty(value = "上次打包的入仓体积")
private BigDecimal sumVolumePrevPacked;
/**
* 上次打包的入仓重量
*/
@ApiModelProperty(value = "上次打包的入仓重量")
private BigDecimal sumWeightPrevPacked;
/**
* 上次打包的箱/件数
*/
@ApiModelProperty(value = "上次打包的箱数")
private Integer sumCartonsNumPrevPacked;
/**
* 上次打包的所有箱内总货物数量
*/
@ApiModelProperty(value = "上次打包的所有箱内总货物数量")
private Integer sumQuantityAllPrevPacked;
@ApiModelProperty(value = "付款人: 1 发货人 2 收货人 3 自定义")
private Integer drawee;
@ApiModelProperty(value = "自定义付款人信息")
private String customDrawee;
@ApiModelProperty(value = "打包前入仓重量")
private BigDecimal weightBeforePack;
@ApiModelProperty(value = "打包后入仓重量")
private BigDecimal weightAfterPack;
@ApiModelProperty(value = "是否有收货人,1-是,0-否")
private Boolean hasConsignee = true;
@TableField(exist = false)
@ApiModelProperty(value = "目的地信息")
@NotNull(message = "目的地信息不能为空")
private OrderObjectiveApiDO orderObjectiveDO;
@TableField(exist = false)
@ApiModelProperty(value = "目的地ID")
private Long objectiveId;
@TableField(exist = false)
@ApiModelProperty(value = "目的地")
private String objectiveName;
}
package cn.iocoder.boot.module.order.enums;
import cn.hutool.core.util.ArrayUtil;
import cn.iocoder.yudao.framework.common.util.json.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
@AllArgsConstructor
@Getter
public enum OrderStatusApiEnum implements IntArrayValuable {
DRAFT(0, "草稿", "draft", "",""),
//1未使用
ORDER_PLACED(2, "已下单", "Order placed", "",""),
WAREHOUSING(3, "入仓中", "Warehousing in progress", "",""),
// SPECIAL_APPLY_PROGRESS(4, "特价申请中", "Special offer application in progress", "",""),
IN_WAREHOUSE(5, "已入仓", "Warehousing", "货物已入捷道%s","The shipment has been delivered to E&C %s"),
WITHDRAWN_EXPENSES_NOT_CLEARED(6, "已退仓-费用未清", "Withdrawn - expense not cleared", "",""),
WITHDRAWN(7, "已退仓", "Withdrawn", "",""),
WAREHOUSE_ADJUSTMENT(8, "调仓中", "Warehouse adjustment in progress", "",""),
MERGED_ORDER(9, "已合单", "Closed order", "",""),
SPLIT_ORDER(10, "已拆单", "Split order", "",""),
PRE_INSTALLED(11, "已预装", "Pre installed", "",""),
INSTALLED_CABINET(12, "已装柜", "Installed cabinet", "预计开船时间:","Estimated time of departure:"),
IN_SHIPPING(13, "航运中", "In shipping", "货物已出仓,预计到港时间:","The goods have been warehoused, and the estimated arrival time is:"),
ARRIVED(14, "已到目的港", "Arrived", "",""),
CLEARED(15, "已清关", "Cleared", "货物已清关","The shipment been cleared out"),
UNLOADED_CABINET(16, "已卸柜", "Unloaded cabinet", "",""),
TWP_WAY_TAKEOFF(17, "二程起飞", "Two way takeoff", "",""),
TWP_WAY_ARRIVAL(18, "二程到目的港", "Two way arrival", "",""),
// WRITTEN_OFF(19, "已核销", "Written off"),
PICKED_UP(20, "已提货", "Picked up", "提货时间:","Pickup time:"),
PART_PICKED_UP(21, "部分提货", "Part Picked up", "提货时间:","Pickup time:"),
//....预留定义
// TALLY(31, "理货", "tally", "", ""),
SHIPMENT(32, "出货", "shipment", "", ""),
// ORDER_UPDATE(50, "订单修改中", "Order update in progress", "",""),
CANCEL(88, "取消订单", "cancellation of order", "",""),
// 此状态为状态13的空运转义状态,当运输方式为空运时,状态13为已起飞
HAS_TAKEN_OFF(130, "已起飞", "Has taken off", "货物已起飞,预计在%s日期抵达%s机场","The shipment has departed China.ETA date to %s is %s"),
CUSTOMS_PASS_AIR(12421, "已报关", "Customs Declaration", "货物报关已放行,候机中","Shipment been released by China custom.waiting to departed China"),
CUSTOMS_PART_EXIT(12322, "已报关", "Customs Inspection", "报关查验退场,返回仓库中","Shipment been Inspected by China custom.waiting return to warehouse"),
CUSTOMS_FULL_EXIT(12323, "已报关", "Customs Inspection", "报关查验退场,返回仓库中","Shipment been Inspected by China custom.waiting return to warehouse"),
WAREHOUSED(32412,"出仓", "Sent out","",""),
UNLOADED_CABINET_AIR(16435,"到仓", "Location","货物已抵达捷道%s提货仓","The shipment been delivered at E&C %s branch"),
;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(OrderStatusApiEnum::getValue).toArray();
/**
* 类型
*/
private final Integer value;
/**
* 类型中文名
*/
private final String nameZh;
/**
* 类型英文名
*/
private final String nameEn;
/**
* 备注中文名
*/
private final String remarksZh;
/**
* 备注英文名
*/
private final String remarksEn;
public static OrderStatusApiEnum valueOf(Integer value) {
return ArrayUtil.firstMatch(orderStatus -> orderStatus.getValue().equals(value), OrderStatusApiEnum.values());
}
@Override
public int[] array() {
return ARRAYS;
}
}
...@@ -57,7 +57,11 @@ ...@@ -57,7 +57,11 @@
<artifactId>yudao-module-infra-impl</artifactId> <artifactId>yudao-module-infra-impl</artifactId>
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-order-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency> <dependency>
<groupId>com.itextpdf</groupId> <groupId>com.itextpdf</groupId>
......
package cn.iocoder.yudao.module.order.api;
import cn.iocoder.boot.module.order.api.OrderApi;
import cn.iocoder.boot.module.order.api.dto.OrderObjectiveApiDO;
import cn.iocoder.boot.module.order.api.dto.OrderRespDTO;
import cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderObjective.OrderObjectiveDO;
import cn.iocoder.yudao.module.order.service.order.OrderObjectiveService;
import cn.iocoder.yudao.module.order.service.order.OrderService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
@Service
@Validated
public class OrderApiImpl implements OrderApi {
@Resource
private OrderService orderService;
@Resource
private OrderObjectiveService objectiveService;
@Override
public OrderRespDTO getOrder(Long id, String orderNo) {
OrderDO orderDO;
if (id != null) {
orderDO = orderService.getById(id);
} else {
orderDO = orderService.selectOne(new LambdaQueryWrapper<OrderDO>().eq(OrderDO::getOrderNo, orderNo).last("limit 1"));
}
if (orderDO == null) {
return null;
}
OrderRespDTO orderRespDTO = new OrderRespDTO();
BeanUtils.copyProperties(orderDO, orderRespDTO);
OrderObjectiveDO orderObjectiveDO = objectiveService.getByOrderId(id);
if (orderObjectiveDO == null) {
return orderRespDTO;
}
OrderObjectiveApiDO orderObjectiveApiDO = new OrderObjectiveApiDO();
BeanUtils.copyProperties(orderObjectiveDO, orderObjectiveApiDO);
orderRespDTO.setOrderObjectiveDO(orderObjectiveApiDO);
return orderRespDTO;
}
@Override
public boolean isFirstOrder(Long userId) {
Long count = orderService.selectCount(new LambdaQueryWrapper<OrderDO>().eq(OrderDO::getUserId, userId));
return count <= 0;
}
}
...@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.reward.api.reward; ...@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.reward.api.reward;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.generator.SnowflakeGenerator; import cn.hutool.core.lang.generator.SnowflakeGenerator;
import cn.iocoder.yudao.framework.redis.helper.RedisDistributedLock; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi; 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.api.score.dto.MemberUserScoreOperateReqDTO;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
...@@ -18,12 +18,18 @@ import cn.iocoder.yudao.module.reward.dal.mysql.reward.RewardMapper; ...@@ -18,12 +18,18 @@ import cn.iocoder.yudao.module.reward.dal.mysql.reward.RewardMapper;
import cn.iocoder.yudao.module.reward.enums.RewardRedeemStatusEnum; import cn.iocoder.yudao.module.reward.enums.RewardRedeemStatusEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.*; import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 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.infra.enums.ErrorCodeConstants.GET_LOCK_FAILED;
...@@ -42,7 +48,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -42,7 +48,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
@Resource @Resource
private MemberUserApi memberUserApi; private MemberUserApi memberUserApi;
@Resource @Resource
private RedisDistributedLock redisDistributedLock; private RedissonClient redissonClient;
@Resource @Resource
private MemberUserScoreApi memberUserScoreApi; private MemberUserScoreApi memberUserScoreApi;
@Resource @Resource
...@@ -71,10 +77,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -71,10 +77,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
throw exception(REWARD_PICK_METHOD_NOT_ALLOW_CREATE); throw exception(REWARD_PICK_METHOD_NOT_ALLOW_CREATE);
} }
verifyMemberUser(redeemRewardReqVO, rewardDO); verifyMemberUser(redeemRewardReqVO, rewardDO);
boolean lock = false; String lockKey = "reward:redeem:lock:" + redeemRewardReqVO.getRewardId();
RLock lock = redissonClient.getLock(lockKey);
try { try {
lock = redisDistributedLock.lock("reward:redeem:lock:" + redeemRewardReqVO.getRewardId()); if (!lock.tryLock(2, 10, TimeUnit.SECONDS)) {
if (!lock) {
throw exception(GET_LOCK_FAILED); throw exception(GET_LOCK_FAILED);
} }
// 添加兑换记录 // 添加兑换记录
...@@ -83,10 +89,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -83,10 +89,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
updateMemberScore(redeemRewardReqVO, rewardDO, redeemId); updateMemberScore(redeemRewardReqVO, rewardDO, redeemId);
// 更新礼品 // 更新礼品
redeemReward(rewardDO, redeemRewardReqVO.getRewardCount()); redeemReward(rewardDO, redeemRewardReqVO.getRewardCount());
} catch (Exception e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw exception(GET_LOCK_FAILED);
} finally { } finally {
redisDistributedLock.releaseLock("reward:redeem:lock:" + redeemRewardReqVO.getRewardId()); lock.unlock();
} }
return null; return null;
} }
...@@ -118,7 +124,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -118,7 +124,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
RewardRedeemDO rewardRedeemDO = BeanUtil.copyProperties(redeemRewardReqVO, RewardRedeemDO.class); RewardRedeemDO rewardRedeemDO = BeanUtil.copyProperties(redeemRewardReqVO, RewardRedeemDO.class);
rewardRedeemDO.setId(snowflakeGenerator.next()); rewardRedeemDO.setId(snowflakeGenerator.next());
rewardRedeemDO.setStatus(RewardRedeemStatusEnum.REDEEMING.getValue()); rewardRedeemDO.setStatus(RewardRedeemStatusEnum.REDEEMING.getValue());
rewardRedeemDO.setScoreCount(redeemRewardReqVO.getRewardCount()* rewardDO.getPointsRequire()); rewardRedeemDO.setScoreCount(redeemRewardReqVO.getRewardCount() * rewardDO.getPointsRequire());
rewardRedeemMapper.insert(rewardRedeemDO); rewardRedeemMapper.insert(rewardRedeemDO);
return rewardRedeemDO.getId(); return rewardRedeemDO.getId();
} }
...@@ -156,10 +162,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -156,10 +162,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
throw exception(REWARD_COUNT_NOT_ENOUGH); throw exception(REWARD_COUNT_NOT_ENOUGH);
} }
} }
boolean lock = false; String lockKey = "reward:redeem:lock:" + rewardId;
RLock lock = redissonClient.getLock(lockKey);
try { try {
lock = redisDistributedLock.lock("reward:redeem:lock:" + rewardId); if (!lock.tryLock(2, 10, TimeUnit.SECONDS)) {
if (!lock) {
throw exception(GET_LOCK_FAILED); throw exception(GET_LOCK_FAILED);
} }
for (RedeemRewardReqVO redeemRewardReqVO : redeemRewardReqVOList) { for (RedeemRewardReqVO redeemRewardReqVO : redeemRewardReqVOList) {
...@@ -170,11 +176,13 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -170,11 +176,13 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
// 更新礼品 // 更新礼品
redeemReward(rewardDO, redeemRewardReqVO.getRewardCount()); redeemReward(rewardDO, redeemRewardReqVO.getRewardCount());
} }
} catch (Exception e) { } catch (ServiceException e) {
log.error("redeem reward exception",e); log.error("batch redeem rewards exception", e);
throw e; throw e;
} catch (InterruptedException e) {
throw exception(GET_LOCK_FAILED);
} finally { } finally {
redisDistributedLock.releaseLock("reward:redeem:lock:" + rewardId); lock.unlock();
} }
return null; return null;
} }
......
...@@ -32,4 +32,6 @@ public class RewardRedeemPageReqVO extends PageParam { ...@@ -32,4 +32,6 @@ public class RewardRedeemPageReqVO extends PageParam {
private Integer entrance; private Integer entrance;
@ApiModelProperty(value = "兑换网点") @ApiModelProperty(value = "兑换网点")
private Integer nodeId; private Integer nodeId;
@ApiModelProperty(value = "会员id")
private Long memberId;
} }
...@@ -151,5 +151,8 @@ ...@@ -151,5 +151,8 @@
<if test="req.endTime != null "> <if test="req.endTime != null ">
and err.create_time &lt;= #{req.endTime} and err.create_time &lt;= #{req.endTime}
</if> </if>
<if test="req.memberId != null">
and err.member_id = #{req.memberId}
</if>
</sql> </sql>
</mapper> </mapper>
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