Commit 82b82afb authored by zhangfeng's avatar zhangfeng

Merge branch 'release-feat-zhangfeng' into 'release'

Release feat zhangfeng

See merge request !29
parents e71f5ef0 e6d0eeed
......@@ -11,7 +11,7 @@
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 15/08/2024 11:03:15
Date: 18/10/2024 09:26:20
*/
SET NAMES utf8mb4;
......@@ -35,6 +35,6 @@ CREATE TABLE `member_user_address` (
`updater` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人',
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员收货地址表' ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员收货地址表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
......@@ -11,7 +11,7 @@
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 15/08/2024 11:03:24
Date: 18/10/2024 09:26:20
*/
SET NAMES utf8mb4;
......@@ -33,6 +33,6 @@ CREATE TABLE `member_user_level_config` (
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员等级配置表' ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员等级配置表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
......@@ -11,7 +11,7 @@
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 15/08/2024 11:03:34
Date: 18/10/2024 09:26:20
*/
SET NAMES utf8mb4;
......@@ -33,6 +33,6 @@ CREATE TABLE `member_user_score` (
`updater` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人',
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员积分表' ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员积分表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
......@@ -11,7 +11,7 @@
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 15/08/2024 11:03:47
Date: 18/10/2024 09:26:54
*/
SET NAMES utf8mb4;
......
......@@ -11,7 +11,7 @@
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 15/08/2024 11:03:55
Date: 18/10/2024 09:27:05
*/
SET NAMES utf8mb4;
......@@ -34,6 +34,6 @@ CREATE TABLE `member_user_score_detail_releation` (
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 23 CHARACTER SET = tis620 COLLATE = tis620_thai_ci COMMENT = '会员积分详情关联表' ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = tis620 COLLATE = tis620_thai_ci COMMENT = '会员积分详情关联表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
......@@ -11,7 +11,7 @@
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 15/08/2024 11:04:03
Date: 18/10/2024 09:27:20
*/
SET NAMES utf8mb4;
......
......@@ -11,7 +11,7 @@
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 06/09/2024 11:23:57
Date: 18/10/2024 09:27:30
*/
SET NAMES utf8mb4;
......@@ -26,8 +26,8 @@ CREATE TABLE `score_rule` (
`code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '规则编号',
`type` int NOT NULL COMMENT '指标类型',
`title_zh` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则标题中文',
`title_en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '规则标题英文',
`desc_zh` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '规则说明中文',
`title_en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则标题英文',
`desc_zh` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则说明中文',
`desc_en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则说明英文',
`cover_image_zh` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '封面图中文',
`cover_image_en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '封面图英文',
......@@ -47,6 +47,6 @@ CREATE TABLE `score_rule` (
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新者',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '积分规则表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
/*
Navicat Premium Data Transfer
Source Server : jiedao-uat
Source Server Type : MySQL
Source Server Version : 80031 (8.0.31)
Source Host : 159.75.224.138:2297
Source Schema : jiedao
Target Server Type : MySQL
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 18/10/2024 09:27:40
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for score_rule_share_fail_trigger
-- ----------------------------
DROP TABLE IF EXISTS `score_rule_share_fail_trigger`;
CREATE TABLE `score_rule_share_fail_trigger` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`share_record_id` bigint NOT NULL COMMENT '分享记录id',
`trigger_time` datetime NOT NULL COMMENT '点击时间',
`ip_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '点击ip',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 23 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
/*
Navicat Premium Data Transfer
Source Server : jiedao-uat
Source Server Type : MySQL
Source Server Version : 80031 (8.0.31)
Source Host : 159.75.224.138:2297
Source Schema : jiedao
Target Server Type : MySQL
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 18/10/2024 09:27:47
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for score_rule_share_record
-- ----------------------------
DROP TABLE IF EXISTS `score_rule_share_record`;
CREATE TABLE `score_rule_share_record` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '分享编号',
`member_id` bigint NOT NULL COMMENT '会员id',
`rule_id` bigint NOT NULL COMMENT '积分规则id',
`total_score` int NULL DEFAULT 0 COMMENT '总积分',
`last_trigger_time` datetime NULL DEFAULT NULL COMMENT '最后触发时间',
`create_time` datetime NOT NULL COMMENT '创建时间',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者',
`update_time` datetime NOT NULL COMMENT '更新时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新者',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 64 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '分享记录表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
......@@ -11,7 +11,7 @@
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 15/08/2024 11:04:36
Date: 18/10/2024 09:28:59
*/
SET NAMES utf8mb4;
......@@ -31,7 +31,7 @@ CREATE TABLE `ecw_reward` (
`img_en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '英文礼品图片',
`img_fr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '法文礼品图片',
`points_require` int NOT NULL COMMENT '兑换所需积分',
`node_id` int NOT NULL COMMENT '兑换网点',
`node_id` int NOT NULL COMMENT '提货点id(对应仓库warehouse_id)',
`exchange_count` int NULL DEFAULT 0 COMMENT '已兑换次数',
`quantity_remain` int NOT NULL COMMENT '剩余数量',
`start_time` datetime NULL DEFAULT NULL COMMENT '活动开始时间',
......@@ -49,6 +49,6 @@ CREATE TABLE `ecw_reward` (
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `unique_code`(`code` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 38 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '礼品' ROW_FORMAT = DYNAMIC;
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '礼品' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
......@@ -11,7 +11,7 @@
Target Server Version : 80031 (8.0.31)
File Encoding : 65001
Date: 06/09/2024 11:26:34
Date: 18/10/2024 09:29:09
*/
SET NAMES utf8mb4;
......@@ -27,6 +27,7 @@ CREATE TABLE `ecw_reward_redeem` (
`member_id` bigint NOT NULL COMMENT '会员id',
`reward_id` bigint NOT NULL COMMENT '礼品id',
`status` int NULL DEFAULT NULL COMMENT '兑换状态',
`hold_score_before_redeem` int NULL DEFAULT 0 COMMENT '兑换前持有的积分',
`score_count` int NOT NULL COMMENT '积分数量',
`reward_count` int NOT NULL COMMENT '兑换数量',
`redeem_type` int NOT NULL COMMENT '兑换方式',
......
......@@ -50,11 +50,24 @@ public class AppAuthController {
// if (StringUtils.isNotBlank(mobile)) {
// reqVO.setMobile(mobile);
// }
String token = authService.reg(reqVO, getClientIP(), getUserAgent());
String token = authService.reg(reqVO, getClientIP(), getUserAgent(), true);
// 返回结果
return success(AppAuthLoginRespVO.builder().token(token).build());
}
@PostMapping("/share-page/reg")
@ApiOperation("分享页面使用手机注册")
@OperateLog(enable = false)
@Idempotent(timeout = 5)
public CommonResult<Boolean> sharePageReg(@RequestBody @Valid AppAuthRegReqVO reqVO) {
String mobileCode = reqVO.getAreaCode() + StrUtil.COLON + reqVO.getMobile();
paramValidatorApi.validatorMobile(mobileCode);
authService.reg(reqVO, getClientIP(), getUserAgent(), false);
// 返回结果
return success(true);
}
@PostMapping("/login")
@ApiOperation("使用手机 + 密码登录")
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
......@@ -110,7 +123,7 @@ public class AppAuthController {
}
@PostMapping("/update-password")
@ApiOperation(value = "修改用户密码",notes = "用户修改密码时使用")
@ApiOperation(value = "修改用户密码", notes = "用户修改密码时使用")
@PreAuthenticated
@Idempotent(timeout = 5)
public CommonResult<Boolean> updatePassword(@RequestBody @Valid AppAuthUpdatePasswordReqVO reqVO) {
......@@ -129,7 +142,7 @@ public class AppAuthController {
}
@PostMapping("/update-control-password")
@ApiOperation(value = "修改用户控货密码",notes = "用户修改控货密码时使用")
@ApiOperation(value = "修改用户控货密码", notes = "用户修改控货密码时使用")
@PreAuthenticated
public CommonResult<Boolean> updateControlPassword(@RequestBody @Valid AppAuthUpdatePasswordReqVO reqVO) {
authService.updateControlPassword(getLoginUserId(), reqVO);
......
......@@ -5,7 +5,7 @@ import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.boot.module.order.api.OrderApi;
import cn.iocoder.boot.module.order.api.dto.OrderItemRespDTO;
import cn.iocoder.boot.module.order.api.dto.OrderObjectiveApiDO;
import cn.iocoder.boot.module.order.api.dto.OrderOperateLogDTO;
import cn.iocoder.boot.module.order.api.dto.OrderRespDTO;
import cn.iocoder.boot.module.order.enums.OrderStatusApiEnum;
import cn.iocoder.yudao.module.customer.dal.dataobject.customerContacts.CustomerContactsDO;
......@@ -13,12 +13,16 @@ import cn.iocoder.yudao.module.customer.service.customerContacts.CustomerContact
import cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi;
import cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateReqDTO;
import cn.iocoder.yudao.module.member.dal.dataobject.scoreRule.ScoreRuleDO;
import cn.iocoder.yudao.module.member.enums.*;
import cn.iocoder.yudao.module.member.enums.PlatformTypeEnum;
import cn.iocoder.yudao.module.member.enums.ScoreRuleTypeEnum;
import cn.iocoder.yudao.module.member.enums.ScoreSourceTypeEnum;
import cn.iocoder.yudao.module.member.enums.TransportTypeEnum;
import cn.iocoder.yudao.module.member.mq.message.ScoreMessage;
import cn.iocoder.yudao.module.member.service.scoreLog.MemberUserScoreLogService;
import cn.iocoder.yudao.module.member.service.scoreRule.ScoreRuleService;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import cn.iocoder.yudao.module.member.vo.scoreRule.extra.ScoreRuleOrderVExtraVO;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.RedissonMultiLock;
......@@ -35,6 +39,8 @@ import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import static cn.iocoder.yudao.module.member.enums.TransportTypeEnum.SPECIAL_LINE_AIR_FREIGHT;
/**
* @author zhangfeng
*/
......@@ -54,13 +60,12 @@ public class OrderVStrategy extends AbstractScoreRuleStrategy {
@Override
public void addScore(ScoreMessage message) {
Long orderId = message.getOrderId();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
log.error("Order in shipping listener: Thread sleep error", e);
}
log.info("Received order V message,orderID:{}", message.getOrderId());
Long orderId = message.getOrderId();
// 获取订单信息
OrderRespDTO order;
try {
......@@ -74,64 +79,72 @@ public class OrderVStrategy extends AbstractScoreRuleStrategy {
return;
}
orderId = order.getOrderId();
log.info("Received order V message,orderID:{}", orderId);
OrderOperateLogDTO orderOperateLogDTO = new OrderOperateLogDTO();
orderOperateLogDTO.setOrderId(orderId);
orderOperateLogDTO.setCreatorName("订单V值规则");
orderOperateLogDTO.setType("积分操作");
orderOperateLogDTO.setUserType(2);
orderOperateLogDTO.setMsg("订单起航/起运计算积分");
StringBuilder logBody = new StringBuilder();
// 订单状态应为起运
if (!Objects.equals(order.getStatus(), OrderStatusApiEnum.IN_SHIPPING.getValue())) {
log.info("Order in shipping listener: The order status is not in shipping,orderID:{}", orderId);
return;
}
// 增加订单无收货人时校验
long consigneeId = 0;
if (Objects.isNull(order.getOrderConsigneeDO()) || Objects.isNull(order.getOrderConsigneeDO().getCustomerId())) {
log.info("Order in shipping listener: The order consignee is empty,orderID:{}", orderId);
} else {
consigneeId = order.getOrderConsigneeDO().getCustomerId();
}
// 获取订单规则
Integer transportId = order.getTransportId();
ScoreRuleDO scoreRuleDO = scoreRuleService.getEnableScoreRuleByType(ScoreRuleTypeEnum.ORDER_V, TransportTypeEnum.parseByValue(transportId));
ScoreRuleDO scoreRuleDO = this.getMatchRule(order, consigneeId);
if (Objects.isNull(scoreRuleDO)) {
log.info("Order in shipping listener: No score rule match,orderID:{}", orderId);
orderOperateLogDTO.setBody(JSONObject.toJSONString(logBody.append("无匹配积分规则;")));
orderApi.createOrderOperateLog(orderOperateLogDTO);
return;
}
// 规则是否包含目的地提货点,0代表所有提货点
OrderObjectiveApiDO orderObjectiveDO = order.getOrderObjectiveDO();
orderOperateLogDTO.setCreator(scoreRuleDO.getCode());
ScoreRuleOrderVExtraVO extraInfo = JSONUtil.toBean(scoreRuleDO.getExtra(), ScoreRuleOrderVExtraVO.class);
String[] warehouseIds = extraInfo.getReceiveAddr().split(",");
if (!Objects.equals(warehouseIds[0], "0") && !ArrayUtil.contains(warehouseIds, orderObjectiveDO.getObjectiveWarehouseId().toString())) {
log.info("Order in shipping listener: The rule does not contain the order destination warehouse,orderID:{},warehouseId:{}", orderId, orderObjectiveDO.getObjectiveWarehouseId().toString());
return;
}
String lockKey1;
if (order.getUserId() > 0) {
lockKey1 = "score:rule:order:lock:" + order.getUserId();
} else {
lockKey1 = "score:rule:order:lock:" + order.getOrderConsignorDO().getCustomerId();
}
// 增加订单无收货人时校验
long consigneeId = 0;
if (Objects.isNull(order.getOrderConsigneeDO()) || Objects.isNull(order.getOrderConsigneeDO().getCustomerId())) {
log.info("Order in shipping listener: The order consignee is empty,orderID:{}", orderId);
} else {
consigneeId = order.getOrderConsigneeDO().getCustomerId();
}
String lockKey2 = "score:rule:order:lock:" + consigneeId;
RLock lock1 = redissonClient.getLock(lockKey1);
RLock lock2 = redissonClient.getLock(lockKey2);
RLock lock2 = consigneeId == 0 ? null : redissonClient.getLock(lockKey2);
RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2);
try {
boolean tryLock = multiLock.tryLock(2, 10, TimeUnit.SECONDS);
if (!tryLock) {
log.error("Order in shipping listener: get lock error, orderId:{}", orderId);
}
// 获取需要添加积分的用户 发货人
List<Long> userIds = getAddScoreUser(order.getUserId(), order.getOrderConsignorDO().getCustomerId(), consigneeId, extraInfo, scoreRuleDO);
// 获取需要添加积分的会员
List<Long> userIds = getAddScoreUser(order.getUserId(), order.getOrderConsignorDO().getCustomerId(), consigneeId, scoreRuleDO, logBody);
if (CollectionUtil.isEmpty(userIds)) {
log.info("Order in shipping listener: consignor and consignee are not bound to the member, orderId:{}", orderId);
orderOperateLogDTO.setBody(JSONObject.toJSONString(logBody));
orderApi.createOrderOperateLog(orderOperateLogDTO);
return;
}
// 计算积分
Integer scoreCount = getScoreCount(transportId, order.getChannelId(), extraInfo.getChannel(), extraInfo.getOrderVRule(), orderId);
Integer scoreCount = getScoreCount(order.getTransportId(), extraInfo.getOrderVRule(), orderId);
logBody.append("根据").append(scoreRuleDO.getCode()).append("规则计算积分为:").append(scoreCount).append(";");
if (scoreCount == 0) {
log.info("Order in shipping listener: The score count is less than or equal to 0,orderId:{}", orderId);
orderOperateLogDTO.setBody(JSONObject.toJSONString(logBody));
orderApi.createOrderOperateLog(orderOperateLogDTO);
return;
}
// 增加积分
for (Long userId : userIds) {
try {
HashMap<String, Object> map = new HashMap<>();
HashMap<String, Object> map = new HashMap<>(1);
map.put("orderId", orderId);
memberUserScoreApi.operateScore(MemberUserScoreOperateReqDTO.builder()
.memberId(userId)
......@@ -144,7 +157,7 @@ public class OrderVStrategy extends AbstractScoreRuleStrategy {
.extParam(map)
.build()
);
log.info("Order V rule add score success,ruleID:{},orderID:{},userID:{}", scoreRuleDO.getId(), message.getOrderId(), userId);
log.info("Order V rule add score success,ruleID:{},orderID:{},userID:{}", scoreRuleDO.getId(), orderId, userId);
} catch (Exception e) {
log.error("Order in shipping listener: operateScore error", e);
}
......@@ -154,19 +167,19 @@ public class OrderVStrategy extends AbstractScoreRuleStrategy {
} finally {
multiLock.unlock();
}
orderOperateLogDTO.setBody(JSONObject.toJSONString(logBody.append("获取积分成功")));
orderApi.createOrderOperateLog(orderOperateLogDTO);
}
/**
* 根据规则获得要加多少分
*
* @param transportId
* @param channelId
* @param allowChannels
* @param orderVRules
* @param orderId
* @return
*/
private Integer getScoreCount(Integer transportId, Long channelId, List<Long> allowChannels, List<ScoreRuleOrderVExtraVO.OrderVRule> orderVRules, Long orderId) {
private Integer getScoreCount(Integer transportId, List<ScoreRuleOrderVExtraVO.OrderVRule> orderVRules, Long orderId) {
Integer scoreCount = 0;
List<OrderItemRespDTO> orderItems = orderApi.getOrderItemsByOrderId(orderId);
if (orderItems == null) {
......@@ -182,12 +195,7 @@ public class OrderVStrategy extends AbstractScoreRuleStrategy {
if (transportId == TransportTypeEnum.OCEAN_LCL.getValue()) {
// 海运算体积
scoreCount = computeScoreCount(totalVolume, orderVRules);
} else if (transportId == TransportTypeEnum.SPECIAL_LINE_AIR_FREIGHT.getValue()) {
// 空运校验渠道
// 渠道id
if (!allowChannels.contains(channelId)) {
return 0;
}
} else if (transportId == SPECIAL_LINE_AIR_FREIGHT.getValue()) {
// 空运算重量
scoreCount = computeScoreCount(totalWeight, orderVRules);
}
......@@ -197,41 +205,46 @@ public class OrderVStrategy extends AbstractScoreRuleStrategy {
/**
* 获取需要加分的用户
*/
private List<Long> getAddScoreUser(Long userId, Long consignorId, Long consigneeId, ScoreRuleOrderVExtraVO extraInfo, ScoreRuleDO scoreRuleDO) {
private List<Long> getAddScoreUser(Long userId, Long consignorId, Long consigneeId, ScoreRuleDO scoreRuleDO, StringBuilder logNote) {
ArrayList<Long> users = new ArrayList<>();
// 发货人和收货人都要判断给分
boolean isBackendOrder = userId <= 0;
// 校验订单入口
if (!isOrderEntryValid(extraInfo.getOrderEntry(), isBackendOrder)) {
return null;
}
logNote.append("此订单为").append(isBackendOrder ? "后台" : "客户端").append("下单;");
// 如果是后台下单,重新获取发货人用户ID
if (isBackendOrder) {
userId = getCustomerMemberId(consignorId);
if (userId == null) {
CustomerContactsDO contactsDO = getCustomerMemberId(consignorId);
if (contactsDO == null || contactsDO.getUserid() == 0) {
userId = 0L;
logNote.append("发货人未绑定会员;");
} else {
userId = contactsDO.getUserid();
logNote.append("发货人绑定会员:").append(contactsDO.getUsername()).append(",会员ID:").append(userId).append(";");
}
}
// 校验首单:发货和收货都算首单,按客户查,只有发货人收货人都是首单才算首单
if (!isFirstOrderValid(consignorId, consigneeId, extraInfo)) {
return null;
}
// 校验积分上限,添加加分用户列表
if (isBackendOrder && isUserScoreMaxed(userId, scoreRuleDO)) {
log.info("Order in shipping listener: The user has reached the maximum score, userId:{}, scoreRuleId:{}", userId, scoreRuleDO.getId());
logNote.append("发货人").append(scoreRuleDO.getCode()).append("规则积分已到上限;");
} else {
addValidUser(users, userId);
}
// 判断收货人
if (consigneeId == null || consigneeId <= 0) {
logNote.append("此订单无收货人;");
return users;
}
Long consigneeMemberId = getCustomerMemberId(consigneeId);
if (consigneeMemberId != null && consigneeMemberId > 0) {
CustomerContactsDO consigneeMemberDO = getCustomerMemberId(consigneeId);
if (consigneeMemberDO == null) {
logNote.append("收货人未绑定会员;");
}
Long consigneeMemberId = consigneeMemberDO == null ? 0L : consigneeMemberDO.getUserid();
if (consigneeMemberId > 0) {
logNote.append("收货人绑定会员:").append(consigneeMemberDO.getUsername()).append(",会员ID:").append(consigneeMemberId).append(";");
if (consigneeMemberId.equals(userId)) {
log.info("Order in shipping listener: The consignee is the same as the sender, userId:{}", userId);
} else if (isBackendOrder && isUserScoreMaxed(consigneeMemberId, scoreRuleDO)) {
logNote.append("收货人").append(scoreRuleDO.getCode()).append("规则积分已到上限;");
log.info("Order in shipping listener: The consignee has reached the maximum score, userId:{}, scoreRuleId:{}", consigneeMemberId, scoreRuleDO.getId());
} else {
users.add(consigneeMemberId);
......@@ -258,20 +271,67 @@ public class OrderVStrategy extends AbstractScoreRuleStrategy {
}
/**
* 校验是否为首单且首单是否有效
* 获取匹配的规则
*
* @param order
* @param consigneeId
* @return
*/
private boolean isFirstOrderValid(Long consignorId, Long consigneeId, ScoreRuleOrderVExtraVO extraInfo) {
if (extraInfo.getFirstOrder() == YesOrNoTypeEnum.YES.ordinal()) {
if (!orderApi.isFirstOrder(consignorId)) {
log.info("Order in shipping listener: consignor not first order,consignorId:{}", consignorId);
private ScoreRuleDO getMatchRule(OrderRespDTO order, long consigneeId) {
List<ScoreRuleDO> scoreRuleDOs = scoreRuleService.getEnableOrderVRule();
if (CollectionUtil.isEmpty(scoreRuleDOs)) {
return null;
}
// 运输方式
Integer transportId = order.getTransportId();
// 首单
Integer isFirstOrder = isFirstOrderValid(order.getOrderConsignorDO().getCustomerId(), consigneeId);
// 提货点
String warehouseId = order.getOrderObjectiveDO().getObjectiveWarehouseId().toString();
// 渠道
Long channelId = order.getChannelId();
// 订单入口
boolean isBackendOrder = order.getUserId() <= 0;
return scoreRuleDOs.stream().filter(scoreRuleDO -> {
ScoreRuleOrderVExtraVO extraInfo = JSONUtil.toBean(scoreRuleDO.getExtra(), ScoreRuleOrderVExtraVO.class);
if (!isOrderEntryValid(extraInfo.getOrderEntry(), isBackendOrder)) {
return false;
}
if (!transportId.equals(extraInfo.getTransportType())) {
return false;
}
if (!isFirstOrder.equals(extraInfo.getFirstOrder())) {
return false;
}
if (!orderApi.isFirstOrder(consigneeId)) {
log.info("Order in shipping listener: consignee not first order,consigneeId:{}", consigneeId);
String[] warehouseIds = extraInfo.getReceiveAddr().split(",");
// 0代表所有提货点
if (!Objects.equals(warehouseIds[0], "0") && !ArrayUtil.contains(warehouseIds, warehouseId)) {
return false;
}
if (transportId.equals(SPECIAL_LINE_AIR_FREIGHT.getValue())) {
if (!extraInfo.getChannel().contains(channelId)) {
return false;
}
}
return true;
}).findFirst().orElse(null);
}
/**
* 校验是否为首单
*/
private Integer isFirstOrderValid(Long consignorId, Long consigneeId) {
// 发货和收货都算首单,按客户查,只有发货人收货人都是首单才算首单
if (!orderApi.isFirstOrder(consignorId)) {
log.info("Order in shipping listener: consignor not first order,consignorId:{}", consignorId);
return 1;
}
return true;
if (consigneeId != 0 && !orderApi.isFirstOrder(consigneeId)) {
log.info("Order in shipping listener: consignee not first order,consigneeId:{}", consigneeId);
return 1;
}
return 0;
}
/**
......@@ -295,17 +355,17 @@ public class OrderVStrategy extends AbstractScoreRuleStrategy {
}
/**
* 根据客户id获取会员id
* 根据客户id获取会员
*
* @param customerId
* @return
*/
private Long getCustomerMemberId(Long customerId) {
private CustomerContactsDO getCustomerMemberId(Long customerId) {
List<CustomerContactsDO> customerContacts = customerContactsService.getCustomerContactsListByCustomerId(customerId);
if (!CollectionUtil.isEmpty(customerContacts)) {
for (CustomerContactsDO customerContact : customerContacts) {
if (customerContact.getIsDefault() == 1 && customerContact.getUserid() != null) {
return customerContact.getUserid();
return customerContact;
}
}
}
......
......@@ -22,7 +22,7 @@ public interface MemberAuthService extends SecurityAuthFrameworkService {
* @param userAgent 用户 UA
* @return 身份令牌,使用 JWT 方式
*/
String reg(@Valid AppAuthRegReqVO reqVO, String userIp, String userAgent);
String reg(@Valid AppAuthRegReqVO reqVO, String userIp, String userAgent, Boolean isAutoLogin);
/**
* 检查号码是否唯一
......
......@@ -111,7 +111,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
}
@Override
public String reg(@Valid AppAuthRegReqVO reqVO, String userIp, String userAgent) {
public String reg(@Valid AppAuthRegReqVO reqVO, String userIp, String userAgent, Boolean isAutoLogin) {
// 校验验证码
smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MEMBER_REG.getScene(), userIp));
......@@ -134,6 +134,9 @@ public class MemberAuthServiceImpl implements MemberAuthService {
.setContent("手机注册成功");
userOperationLogService.createUserOperationLog(userOperationLogCreateReqVO);
if (!isAutoLogin) {
return null;
}
// 执行登陆
this.createLoginLog(user.getMobile(), LoginLogTypeEnum.LOGIN_USERNAME, LoginResultEnum.SUCCESS);
LoginUser loginUser = AuthConvert.INSTANCE.convert(user);
......
......@@ -109,20 +109,12 @@ public interface ScoreRuleService extends IService<ScoreRuleDO> {
ScoreRuleDO getEnabledOrderVScoreRuleByTransportType(Integer transportType);
/**
* 根据类型获取已启用积分规则
* 根据类型获取已启用积分规则(仅推荐和注册)
* @param scoreRuleType
* @return
*/
ScoreRuleDO getEnableScoreRuleByType(ScoreRuleTypeEnum scoreRuleType);
/**
* 根据类型获取已启用积分规则(带运输类型)
* @param scoreRuleType
* @param transportType
* @return
*/
ScoreRuleDO getEnableScoreRuleByType(ScoreRuleTypeEnum scoreRuleType, TransportTypeEnum transportType);
List<WarehouseTreeRegionSimpleVO> getWarehouseTreeRegionListSimple();
/**
......@@ -151,4 +143,10 @@ public interface ScoreRuleService extends IService<ScoreRuleDO> {
* @return
*/
Boolean setScoreRuleSwitch(SwitchReqVo switchReqVo);
/**
* 获取当前时间已启用的订单V值规则
* @return
*/
List<ScoreRuleDO> getEnableOrderVRule();
}
......@@ -31,6 +31,7 @@ import cn.iocoder.yudao.module.member.vo.scoreRule.extra.ScoreRuleRegisterExtraV
import cn.iocoder.yudao.module.member.vo.scoreRule.extra.ScoreRuleShareExtraVO;
import cn.iocoder.yudao.module.member.vo.scoreRule.extra.ScoreRulerRecommendExtraVO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
......@@ -48,6 +49,8 @@ import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.member.enums.TransportTypeEnum.OCEAN_LCL;
import static cn.iocoder.yudao.module.member.enums.TransportTypeEnum.SPECIAL_LINE_AIR_FREIGHT;
/**
* 积分规则 Service 实现类
......@@ -108,25 +111,25 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
throw exception(SCORE_RULE_EXTRA_ERROR);
}
Integer transportType = extraOrderV.getTransportType();
if (transportType != TransportTypeEnum.OCEAN_LCL.getValue() && transportType != TransportTypeEnum.SPECIAL_LINE_AIR_FREIGHT.getValue()) {
if (transportType != OCEAN_LCL.getValue() && transportType != SPECIAL_LINE_AIR_FREIGHT.getValue()) {
throw exception(SCORE_RULE_TRANSPORT_TYPE_ERROR);
}
scoreRuleUniqueCheck(scoreRuleIn.getType(), transportType, scoreRuleIn.getStartTime(), scoreRuleIn.getEndTime(), null);
orderVUniqueCheck(extraOrderV, scoreRuleIn.getStartTime(), scoreRuleIn.getEndTime(), null);
} else {
scoreRuleUniqueCheck(scoreRuleIn.getType(), null, scoreRuleIn.getStartTime(), scoreRuleIn.getEndTime(), null);
scoreRuleUniqueCheck(scoreRuleIn.getType(), scoreRuleIn.getStartTime(), scoreRuleIn.getEndTime(), null);
}
}
}
/**
* 积分规则唯一性校验
* 积分规则唯一性校验(订单V值单独校验)
*
* @param type 类型
* @param transportType 运输类型(订单V值传)
* @param newScoreRuleStart 新积分规则开始时间
* @param delayId 延期时的规则id
* @param newScoreRuleStart 新规则的开始时间
* @param newScoreRuleEnd 新规则的结束时间
* @param delayId 延期规则的id
*/
private void scoreRuleUniqueCheck(Integer type, Integer transportType, Date newScoreRuleStart, Date newScoreRuleEnd, Long delayId) {
private void scoreRuleUniqueCheck(Integer type, Date newScoreRuleStart, Date newScoreRuleEnd, Long delayId) {
LambdaQuery<ScoreRuleDO> scoreRuleDOLambdaQuery = new LambdaQuery<>();
scoreRuleDOLambdaQuery.eq(ScoreRuleDO::getStatus, ScoreRuleStatusEnum.ENABLED.getValue())
.eq(ScoreRuleDO::getType, type);
......@@ -137,22 +140,131 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
if (scoreRuleDOS == null || scoreRuleDOS.isEmpty()) {
return;
}
if (transportType != null) {
for (ScoreRuleDO scoreRuleDO : scoreRuleDOS) {
ScoreRuleOrderVExtraVO bean = JSONUtil.toBean(scoreRuleDO.getExtra(), ScoreRuleOrderVExtraVO.class);
if (Objects.equals(bean.getTransportType(), transportType) && verifyTimeOverlap(newScoreRuleStart, newScoreRuleEnd, scoreRuleDO)) {
throw exception(SCORE_RULE_UNIQUE_CHECK_ERROR);
for (ScoreRuleDO scoreRuleDO : scoreRuleDOS) {
if (verifyTimeOverlap(newScoreRuleStart, newScoreRuleEnd, scoreRuleDO)) {
throw exception(SCORE_RULE_UNIQUE_CHECK_ERROR, scoreRuleDO.getCode());
}
}
}
/**
* 订单V规则唯一性校验
*
* @param extraOrderV 订单v值额外信息
* @param newScoreRuleStart 新规则的开始时间
* @param newScoreRuleEnd 新规则的结束时间
* @param delayId 延期时的规则id
*/
private void orderVUniqueCheck(ScoreRuleOrderVExtraVO extraOrderV, Date newScoreRuleStart, Date newScoreRuleEnd, Long delayId) {
LambdaQuery<ScoreRuleDO> scoreRuleDOLambdaQuery = new LambdaQuery<>();
scoreRuleDOLambdaQuery.eq(ScoreRuleDO::getStatus, ScoreRuleStatusEnum.ENABLED.getValue())
.eq(ScoreRuleDO::getType, ScoreRuleTypeEnum.ORDER_V.getValue());
if (delayId != null) {
scoreRuleDOLambdaQuery.ne(ScoreRuleDO::getId, delayId);
}
List<ScoreRuleDO> scoreRuleDOS = scoreRuleMapper.selectList(scoreRuleDOLambdaQuery);
if (scoreRuleDOS == null || scoreRuleDOS.isEmpty()) {
return;
}
for (ScoreRuleDO scoreRuleDO : scoreRuleDOS) {
ScoreRuleOrderVExtraVO oldExtraVO = JSONUtil.toBean(scoreRuleDO.getExtra(), ScoreRuleOrderVExtraVO.class);
if (verifyTimeOverlap(newScoreRuleStart, newScoreRuleEnd, scoreRuleDO) && isSameOrderVRule(oldExtraVO, extraOrderV)) {
throw exception(SCORE_RULE_UNIQUE_CHECK_ERROR, scoreRuleDO.getCode());
}
}
}
private boolean isSameOrderVRule(ScoreRuleOrderVExtraVO oldExtraVO, ScoreRuleOrderVExtraVO extraOrderV) {
return oldExtraVO.getTransportType().equals(extraOrderV.getTransportType()) &&
Objects.equals(oldExtraVO.getFirstOrder(), extraOrderV.getFirstOrder()) &&
verifyReceiveAddr(oldExtraVO, extraOrderV) &&
verifyChannel(oldExtraVO, extraOrderV) &&
verifyOrderEntry(oldExtraVO.getOrderEntry(), extraOrderV.getOrderEntry());
}
private boolean verifyChannel(ScoreRuleOrderVExtraVO oldExtraVO, ScoreRuleOrderVExtraVO extraOrderV) {
// 运输方式空运时,判断渠道是否有交集
if (oldExtraVO.getTransportType().equals(SPECIAL_LINE_AIR_FREIGHT.getValue())) {
List<Long> oldChannel = oldExtraVO.getChannel();
List<Long> newChannel = extraOrderV.getChannel();
if (CollectionUtils.isEmpty(oldChannel) || CollectionUtils.isEmpty(newChannel)) {
return false;
}
return CollectionUtils.containsAny(oldChannel, newChannel);
}
return false;
}
private boolean verifyReceiveAddr(ScoreRuleOrderVExtraVO oldExtraVO, ScoreRuleOrderVExtraVO extraOrderV) {
List<String> oldReceiveAddrList = Arrays.asList(oldExtraVO.getReceiveAddr().split(","));
List<String> newReceiveAddrList = new ArrayList<>();
// 如果是前端传入的,国家,城市,仓库id从receiveAddrList中获取
if (extraOrderV.getReceiveAddrList() != null) {
List<List<Long>> receiveAddrList = extraOrderV.getReceiveAddrList();
if (extraOrderV.getReceiveAddrList().isEmpty()) {
throw exception(SCORE_RULE_RECEIVE_ADDRESS_ERROR);
}
for (List<Long> integers : receiveAddrList) {
try {
newReceiveAddrList.add(integers.get(2).toString());
} catch (Exception e) {
throw exception(SCORE_RULE_RECEIVE_ADDRESS_ERROR);
}
}
} else {
for (ScoreRuleDO scoreRuleDO : scoreRuleDOS) {
if (verifyTimeOverlap(newScoreRuleStart, newScoreRuleEnd, scoreRuleDO)) {
throw exception(SCORE_RULE_UNIQUE_CHECK_ERROR);
}
newReceiveAddrList = Arrays.asList(extraOrderV.getReceiveAddr().split(","));
}
// 如果有一个选的是全部,则返回true
if (oldReceiveAddrList.contains("0") || newReceiveAddrList.contains("0")) {
return true;
}
// 如果两个集合有交集,则返回true
return CollectionUtils.containsAny(oldReceiveAddrList, newReceiveAddrList);
}
private boolean verifyOrderEntry(String oldOrderEntry, String newOrderEntry) {
List<String> oldEntryList = Arrays.asList(oldOrderEntry.split(","));
List<String> newEntryList = Arrays.asList(newOrderEntry.split(","));
// 对订单入口进行归类后比较
Set<String> categorizedSources1 = categorizeOrderEntry(oldEntryList);
Set<String> categorizedSources2 = categorizeOrderEntry(newEntryList);
// 如果一个规则归类为 "ALL",则无论另一个是什么都算相同
if (categorizedSources1.contains("ALL") || categorizedSources2.contains("ALL")) {
return true;
}
// 仅当分类后的集合完全一致时才算相同
return categorizedSources1.equals(categorizedSources2);
}
private Set<String> categorizeOrderEntry(List<String> orderEntrys) {
Set<String> categorizedSources = new HashSet<>();
boolean hasBackend = false;
boolean hasClient = false;
for (String orderEntry : orderEntrys) {
if (orderEntry.equals("1")) {
hasBackend = true;
} else if (orderEntry.equals("2") || orderEntry.equals("3")) {
hasClient = true;
}
}
// 如果同时有后台和客户端,归为 "ALL"
if (hasBackend && hasClient) {
categorizedSources.add("ALL");
} else {
if (hasBackend) {
categorizedSources.add("BACKEND");
}
if (hasClient) {
categorizedSources.add("CLIENT");
}
}
return categorizedSources;
}
/**
* 校验规则时间区间是否有交集
*/
......@@ -194,7 +306,7 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
if (extraOrderV.getFirstOrder() != YesOrNoTypeEnum.YES.ordinal() && extraOrderV.getFirstOrder() != YesOrNoTypeEnum.NO.ordinal()) {
throw exception(SCORE_RULE_FIRST_ORDER_ERROR);
}
if (extraOrderV.getTransportType() != TransportTypeEnum.OCEAN_LCL.getValue() && extraOrderV.getTransportType() != TransportTypeEnum.SPECIAL_LINE_AIR_FREIGHT.getValue()) {
if (extraOrderV.getTransportType() != OCEAN_LCL.getValue() && extraOrderV.getTransportType() != SPECIAL_LINE_AIR_FREIGHT.getValue()) {
throw exception(SCORE_RULE_TRANSPORT_TYPE_ERROR);
}
// 国家,城市,仓库id从receiveAddrList中获取
......@@ -389,9 +501,9 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
if (scoreRuleDO.getType() != ScoreRuleTypeEnum.SHARE.getValue()) {
if (scoreRuleDO.getType() == ScoreRuleTypeEnum.ORDER_V.getValue()) {
ScoreRuleOrderVExtraVO extraOrderV = JSONUtil.toBean(scoreRuleDO.getExtra(), ScoreRuleOrderVExtraVO.class);
scoreRuleUniqueCheck(scoreRuleDO.getType(), extraOrderV.getTransportType(), scoreRuleDO.getStartTime(), scoreRuleDO.getEndTime(), null);
orderVUniqueCheck(extraOrderV, scoreRuleDO.getStartTime(), scoreRuleDO.getEndTime(), null);
} else {
scoreRuleUniqueCheck(scoreRuleDO.getType(), null, scoreRuleDO.getStartTime(), scoreRuleDO.getEndTime(), null);
scoreRuleUniqueCheck(scoreRuleDO.getType(), scoreRuleDO.getStartTime(), scoreRuleDO.getEndTime(), null);
}
}
upScoreRuleDO.setStatus(scoreRuleStatusReqVO.getStatus());
......@@ -435,9 +547,9 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
// 新时间区间规则唯一校验
if (scoreRuleDO.getType() == ScoreRuleTypeEnum.ORDER_V.getValue()) {
ScoreRuleOrderVExtraVO extraOrderV = JSONUtil.toBean(scoreRuleDO.getExtra(), ScoreRuleOrderVExtraVO.class);
scoreRuleUniqueCheck(scoreRuleDO.getType(), extraOrderV.getTransportType(), scoreRuleDO.getStartTime(), delayReqVO.getEndTime(), scoreRuleDO.getId());
orderVUniqueCheck(extraOrderV, scoreRuleDO.getStartTime(), delayReqVO.getEndTime(), scoreRuleDO.getId());
} else {
scoreRuleUniqueCheck(scoreRuleDO.getType(), null, scoreRuleDO.getStartTime(), delayReqVO.getEndTime(), scoreRuleDO.getId());
scoreRuleUniqueCheck(scoreRuleDO.getType(), scoreRuleDO.getStartTime(), delayReqVO.getEndTime(), scoreRuleDO.getId());
}
ScoreRuleDO upScoreRuleDO = new ScoreRuleDO();
upScoreRuleDO.setId(delayReqVO.getId());
......@@ -447,7 +559,7 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
@Override
public ScoreRuleDO getEnabledOrderVScoreRuleByTransportType(Integer transportType) {
if (transportType != TransportTypeEnum.OCEAN_LCL.getValue() && transportType != TransportTypeEnum.SPECIAL_LINE_AIR_FREIGHT.getValue()) {
if (transportType != OCEAN_LCL.getValue() && transportType != SPECIAL_LINE_AIR_FREIGHT.getValue()) {
throw exception(SCORE_RULE_TRANSPORT_TYPE_ERROR);
}
LambdaQuery<ScoreRuleDO> lambdaQuery = new LambdaQuery<>();
......@@ -485,28 +597,6 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
return enableScoreRule;
}
@Override
public ScoreRuleDO getEnableScoreRuleByType(ScoreRuleTypeEnum scoreRuleType, TransportTypeEnum transportType) {
ScoreRuleDO enableScoreRule;
switch (scoreRuleType) {
case ORDER_V:
enableScoreRule = scoreRuleRedisDao.getEnableScoreRule(scoreRuleType, transportType);
if (enableScoreRule == null) {
enableScoreRule = getEnabledOrderVScoreRuleByTransportType(transportType.getValue());
if (enableScoreRule == null) {
return null;
}
scoreRuleRedisDao.setEnableScoreRule(enableScoreRule);
}
return enableScoreRule;
case RECOMMEND:
case REGISTER:
return getEnableScoreRuleByType(scoreRuleType);
default:
return null;
}
}
@Override
public List<WarehouseTreeRegionSimpleVO> getWarehouseTreeRegionListSimple() {
List<WarehouseTreeRegionVO> list = ListUtils.sum(
......@@ -615,4 +705,15 @@ public class ScoreRuleServiceImpl extends AbstractService<ScoreRuleMapper, Score
public Boolean setScoreRuleSwitch(SwitchReqVo switchReqVo) {
return scoreRuleRedisDao.setScoreRuleSwitch(switchReqVo.getSwitchState());
}
@Override
public List<ScoreRuleDO> getEnableOrderVRule() {
LambdaQueryWrapper<ScoreRuleDO> queryWrapper = new LambdaQuery<ScoreRuleDO>()
.eq(ScoreRuleDO::getType, ScoreRuleTypeEnum.ORDER_V.getValue())
.eq(ScoreRuleDO::getStatus, ScoreRuleStatusEnum.ENABLED.getValue())
.lt(ScoreRuleDO::getStartTime, LocalDateTime.now())
.gt(ScoreRuleDO::getEndTime, LocalDateTime.now());
List<ScoreRuleDO> scoreRuleDOS = scoreRuleMapper.selectList(queryWrapper);
return scoreRuleDOS;
}
}
package cn.iocoder.boot.module.order.api;
import cn.iocoder.boot.module.order.api.dto.OrderItemRespDTO;
import cn.iocoder.boot.module.order.api.dto.OrderOperateLogDTO;
import cn.iocoder.boot.module.order.api.dto.OrderRespDTO;
import java.util.List;
......@@ -21,6 +22,10 @@ public interface OrderApi {
* 根据订单id获取所有订单项
*/
List<OrderItemRespDTO> getOrderItemsByOrderId(Long orderId);
/**
* 添加订单操作日志
*/
void createOrderOperateLog(OrderOperateLogDTO orderId);
/**
......
package cn.iocoder.boot.module.order.api.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 订单操作日志 DTO
*/
@Data
public class OrderOperateLogDTO {
@ApiModelProperty(value = "订单ID", required = true)
@NotNull(message = "订单ID不能为空")
private Long orderId;
@ApiModelProperty(value = "变更后订单详情数据")
private String body;
@ApiModelProperty(value = "请求地址")
private String requestUrl;
@ApiModelProperty(value = "变更类型")
private String type;
@ApiModelProperty(value = "变更描述")
private String msg;
@ApiModelProperty(value = "备注说明")
private String note;
@ApiModelProperty(value = "操作人类型:1 会员 2 管理员")
private Integer userType;
@ApiModelProperty(value = "创建者")
private String creator;
@ApiModelProperty(value = "创建者名称")
private String creatorName;
}
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
......
......@@ -13,6 +13,8 @@ import cn.iocoder.yudao.module.order.dal.dataobject.orderItem.OrderItemDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderObjective.OrderObjectiveDO;
import cn.iocoder.yudao.module.order.service.order.*;
import cn.iocoder.yudao.module.order.service.order.impl.OrderItemServiceImpl;
import cn.iocoder.yudao.module.order.service.orderOperateLog.OrderOperateLogService;
import cn.iocoder.yudao.module.order.vo.orderOperateLog.OrderOperateLogCreateReqVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Joiner;
import org.springframework.beans.BeanUtils;
......@@ -45,6 +47,8 @@ public class OrderApiImpl implements OrderApi {
private OrderItemServiceImpl orderItemService;
@Resource
private OrderConsignorService orderConsignorService;
@Resource
private OrderOperateLogService orderOperateLogService;
@Override
public OrderRespDTO getOrder(Long id, String orderNo) {
......@@ -101,6 +105,13 @@ public class OrderApiImpl implements OrderApi {
return null;
}
@Override
public void createOrderOperateLog(OrderOperateLogDTO orderOperateLogDTO) {
OrderOperateLogCreateReqVO createReqVO = new OrderOperateLogCreateReqVO();
BeanUtils.copyProperties(orderOperateLogDTO, createReqVO);
orderOperateLogService.createOrderAsyncOperateLog(createReqVO);
}
@Override
public boolean mergeOrder(Long customerIdSaved, Long customerIdDeleted) {
......
......@@ -95,7 +95,15 @@ public class RewardRedeemServiceImpl extends AbstractService<RewardRedeemMapper,
if (id == null) {
return null;
}
return rewardRedeemMapper.detail(id);
RewardRedeemPageRespVO detail = rewardRedeemMapper.detail(id);
if (detail != null && detail.getEntrance() != PlatformTypeEnum.BACKEND.getValue()) {
detail.setCreatorName(detail.getMemberNameZh());
// 刚创建时更新人显示为兑换人
if (detail.getUpdateTime().equals(detail.getCreateTime())) {
detail.setUpdaterName(detail.getMemberNameZh());
}
}
return detail;
}
@Override
......
......@@ -1058,7 +1058,7 @@ score.rule.update.error = only disabled rule can update
score.rule.delete.error = only disabled rule can delete
score.rule.status.error = score rule status error
score.rule.status.not.enable = score rule status not enable
score.rule.unique.check.error = The same rule already exists during the validity period
score.rule.unique.check.error = The same rule already exists during the validity period: {}
score.rule.transport.type.error = transport type error
score.rule.time.error = score rule time error
score.rule.period.error = score rule period error
......
......@@ -1059,7 +1059,7 @@ score.rule.update.error = \u53EA\u6709\u672A\u542F\u7528\u89C4\u5219\u53EF\u4EE5
score.rule.delete.error = \u53EA\u6709\u672A\u542F\u7528\u53EF\u4EE5\u5220\u9664
score.rule.status.error = \u79EF\u5206\u89C4\u5219\u72B6\u6001\u9519\u8BEF
score.rule.status.not.enable = \u79EF\u5206\u89C4\u5219\u672A\u542F\u7528
score.rule.unique.check.error = \u6709\u6548\u671F\u5185\u5DF2\u5B58\u5728\u76F8\u540C\u89C4\u5219
score.rule.unique.check.error = \u6709\u6548\u671F\u5185\u5DF2\u5B58\u5728\u76F8\u540C\u89C4\u5219\uFF1A{}
score.rule.transport.type.error = \u8FD0\u8F93\u7C7B\u578B\u9519\u8BEF
score.rule.time.error = \u6D3B\u52A8\u65F6\u95F4\u4E0D\u5408\u6CD5
score.rule.period.error = \u8FC7\u671F\u65F6\u95F4\u9519\u8BEF
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment