|
@@ -2,9 +2,7 @@ package shop.alien.store.service.impl;
|
|
|
|
|
|
|
|
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.metadata.IPage;
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
@@ -15,10 +13,8 @@ import shop.alien.entity.store.vo.RewardRuleTreeNodeVo;
|
|
|
import shop.alien.mapper.UserActionRewardRuleMapper;
|
|
import shop.alien.mapper.UserActionRewardRuleMapper;
|
|
|
import shop.alien.store.service.UserActionRewardRuleService;
|
|
import shop.alien.store.service.UserActionRewardRuleService;
|
|
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
|
-import java.util.LinkedHashMap;
|
|
|
|
|
-import java.util.List;
|
|
|
|
|
-import java.util.Map;
|
|
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 用户行为奖励规则配置表 服务实现类
|
|
* 用户行为奖励规则配置表 服务实现类
|
|
@@ -34,98 +30,148 @@ public class UserActionRewardRuleServiceImpl extends ServiceImpl<UserActionRewar
|
|
|
private final UserActionRewardRuleMapper userActionRewardRuleMapper;
|
|
private final UserActionRewardRuleMapper userActionRewardRuleMapper;
|
|
|
|
|
|
|
|
|
|
|
|
|
- // TODO 垃圾代码,运营活动
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public List<RewardRuleTreeNodeVo> getRewardRuleList(int page, int size, String role, String action, String reward, Integer status) {
|
|
public List<RewardRuleTreeNodeVo> getRewardRuleList(int page, int size, String role, String action, String reward, Integer status) {
|
|
|
|
|
+ // 查询所有数据(不分页,因为需要构建完整树形结构)
|
|
|
LambdaQueryWrapper<UserActionRewardRule> queryWrapper = new LambdaQueryWrapper<>();
|
|
LambdaQueryWrapper<UserActionRewardRule> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.like(StringUtils.isNotEmpty(role), UserActionRewardRule::getRole, role);
|
|
|
|
|
- queryWrapper.like(StringUtils.isNotEmpty(action), UserActionRewardRule::getAction, action);
|
|
|
|
|
- queryWrapper.like(StringUtils.isNotEmpty(reward), UserActionRewardRule::getReward, reward);
|
|
|
|
|
- queryWrapper.eq(status != null, UserActionRewardRule::getStatus, status);
|
|
|
|
|
queryWrapper.eq(UserActionRewardRule::getDeleteFlag, 0);
|
|
queryWrapper.eq(UserActionRewardRule::getDeleteFlag, 0);
|
|
|
- queryWrapper.orderByAsc(UserActionRewardRule::getSortOrder);
|
|
|
|
|
- queryWrapper.orderByDesc(UserActionRewardRule::getCreatedTime);
|
|
|
|
|
- IPage<UserActionRewardRule> userActionRewardRuleIPage = userActionRewardRuleMapper.selectPage(new Page<>(page, size), queryWrapper);
|
|
|
|
|
-
|
|
|
|
|
- // 将平铺的数据构造成树形结构(role -> action -> reward)
|
|
|
|
|
- // 第一级:按role分组
|
|
|
|
|
- Map<String, Map<String, List<UserActionRewardRule>>> roleMap = new LinkedHashMap<>();
|
|
|
|
|
- for (UserActionRewardRule record : userActionRewardRuleIPage.getRecords()) {
|
|
|
|
|
- String r = record.getRole();
|
|
|
|
|
- String a = record.getAction();
|
|
|
|
|
-
|
|
|
|
|
- // role 层
|
|
|
|
|
- Map<String, List<UserActionRewardRule>> actionMap = roleMap.computeIfAbsent(r, k -> new LinkedHashMap<>());
|
|
|
|
|
- // action 层
|
|
|
|
|
- List<UserActionRewardRule> ruleList = actionMap.computeIfAbsent(a, k -> new ArrayList<>());
|
|
|
|
|
- // 叶子节点:具体规则
|
|
|
|
|
- ruleList.add(record);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 如果指定了status,需要过滤
|
|
|
|
|
+ if (status != null) {
|
|
|
|
|
+ queryWrapper.eq(UserActionRewardRule::getStatus, status);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 构造成前端需要的树形结构
|
|
|
|
|
- List<RewardRuleTreeNodeVo> result = new ArrayList<>();
|
|
|
|
|
- for (Map.Entry<String, Map<String, List<UserActionRewardRule>>> roleEntry : roleMap.entrySet()) {
|
|
|
|
|
- String roleValue = roleEntry.getKey();
|
|
|
|
|
- Map<String, List<UserActionRewardRule>> actionMap = roleEntry.getValue();
|
|
|
|
|
-
|
|
|
|
|
- // 第一级节点:role
|
|
|
|
|
- RewardRuleTreeNodeVo roleNode = new RewardRuleTreeNodeVo();
|
|
|
|
|
- roleNode.setValue(roleValue);
|
|
|
|
|
- roleNode.setLabel(roleValue);
|
|
|
|
|
- // role的disabled:如果该role下所有action都是禁用的,则role也禁用
|
|
|
|
|
- boolean roleDisabled = true;
|
|
|
|
|
- for (List<UserActionRewardRule> rules : actionMap.values()) {
|
|
|
|
|
- for (UserActionRewardRule rule : rules) {
|
|
|
|
|
- if (rule.getStatus() != null && rule.getStatus() == 0) {
|
|
|
|
|
- roleDisabled = false;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+
|
|
|
|
|
+ queryWrapper.orderByDesc(UserActionRewardRule::getSortOrder);
|
|
|
|
|
+ queryWrapper.orderByAsc(UserActionRewardRule::getId);
|
|
|
|
|
+
|
|
|
|
|
+ List<UserActionRewardRule> allRecords = userActionRewardRuleMapper.selectList(queryWrapper);
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有查询条件,先过滤出匹配的节点ID集合
|
|
|
|
|
+ Set<Integer> matchedNodeIds = new HashSet<>();
|
|
|
|
|
+ if (StringUtils.isNotEmpty(role) || StringUtils.isNotEmpty(action) || StringUtils.isNotEmpty(reward)) {
|
|
|
|
|
+ for (UserActionRewardRule record : allRecords) {
|
|
|
|
|
+ boolean matched = false;
|
|
|
|
|
+ if (StringUtils.isNotEmpty(role) && record.getLevel() == 1 && record.getName().contains(role)) {
|
|
|
|
|
+ matched = true;
|
|
|
}
|
|
}
|
|
|
- if (!roleDisabled) {
|
|
|
|
|
- break;
|
|
|
|
|
|
|
+ if (StringUtils.isNotEmpty(action) && record.getLevel() == 2 && record.getName().contains(action)) {
|
|
|
|
|
+ matched = true;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- roleNode.setDisabled(roleDisabled);
|
|
|
|
|
-
|
|
|
|
|
- // 第二级节点:action
|
|
|
|
|
- List<RewardRuleTreeNodeVo> actionNodes = new ArrayList<>();
|
|
|
|
|
- for (Map.Entry<String, List<UserActionRewardRule>> actionEntry : actionMap.entrySet()) {
|
|
|
|
|
- String actionValue = actionEntry.getKey();
|
|
|
|
|
- List<UserActionRewardRule> rules = actionEntry.getValue();
|
|
|
|
|
-
|
|
|
|
|
- RewardRuleTreeNodeVo actionNode = new RewardRuleTreeNodeVo();
|
|
|
|
|
- actionNode.setValue(actionValue);
|
|
|
|
|
- actionNode.setLabel(actionValue);
|
|
|
|
|
- // action的disabled:如果该action下所有reward都是禁用的,则action也禁用
|
|
|
|
|
- boolean actionDisabled = true;
|
|
|
|
|
- for (UserActionRewardRule rule : rules) {
|
|
|
|
|
- if (rule.getStatus() != null && rule.getStatus() == 0) {
|
|
|
|
|
- actionDisabled = false;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (StringUtils.isNotEmpty(reward) && record.getLevel() == 3 && record.getName().contains(reward)) {
|
|
|
|
|
+ matched = true;
|
|
|
}
|
|
}
|
|
|
- actionNode.setDisabled(actionDisabled);
|
|
|
|
|
-
|
|
|
|
|
- // 第三级节点:reward
|
|
|
|
|
- List<RewardRuleTreeNodeVo> rewardNodes = new ArrayList<>();
|
|
|
|
|
- for (UserActionRewardRule rule : rules) {
|
|
|
|
|
- String rewardValue = rule.getReward();
|
|
|
|
|
- RewardRuleTreeNodeVo rewardNode = new RewardRuleTreeNodeVo();
|
|
|
|
|
- rewardNode.setValue(rewardValue);
|
|
|
|
|
- rewardNode.setLabel(rewardValue);
|
|
|
|
|
- // reward的disabled:根据status判断,0-禁用,1-启用
|
|
|
|
|
- rewardNode.setDisabled(rule.getStatus() == 1);
|
|
|
|
|
- rewardNodes.add(rewardNode);
|
|
|
|
|
|
|
+ if (matched) {
|
|
|
|
|
+ // 收集该节点及其所有父节点和子节点
|
|
|
|
|
+ collectRelatedNodeIds(record.getId(), allRecords, matchedNodeIds);
|
|
|
}
|
|
}
|
|
|
- actionNode.setChildren(rewardNodes);
|
|
|
|
|
- actionNodes.add(actionNode);
|
|
|
|
|
}
|
|
}
|
|
|
- roleNode.setChildren(actionNodes);
|
|
|
|
|
- result.add(roleNode);
|
|
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有匹配条件,只保留匹配的节点
|
|
|
|
|
+ if (!matchedNodeIds.isEmpty()) {
|
|
|
|
|
+ allRecords = allRecords.stream()
|
|
|
|
|
+ .filter(record -> matchedNodeIds.contains(record.getId()))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 构建树形结构:使用parent_id关联
|
|
|
|
|
+ Map<Integer, List<UserActionRewardRule>> childrenMap = new LinkedHashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 先收集所有节点,按parent_id分组
|
|
|
|
|
+ for (UserActionRewardRule record : allRecords) {
|
|
|
|
|
+ Integer parentId = record.getParentId() == null ? 0 : record.getParentId();
|
|
|
|
|
+ childrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(record);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 递归构建树形结构
|
|
|
|
|
+ List<RewardRuleTreeNodeVo> result = new ArrayList<>();
|
|
|
|
|
+ List<UserActionRewardRule> rootNodes = childrenMap.getOrDefault(0, new ArrayList<>());
|
|
|
|
|
+ for (UserActionRewardRule rootNode : rootNodes) {
|
|
|
|
|
+ if (rootNode.getLevel() == 1) {
|
|
|
|
|
+ RewardRuleTreeNodeVo roleNode = buildTreeNode(rootNode, childrenMap);
|
|
|
|
|
+ result.add(roleNode);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 对结果进行分页处理(只对第一级节点分页)
|
|
|
|
|
+ if (result.size() > 0) {
|
|
|
|
|
+ int start = (page - 1) * size;
|
|
|
|
|
+ int end = Math.min(start + size, result.size());
|
|
|
|
|
+ if (start < result.size()) {
|
|
|
|
|
+ return result.subList(start, end);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 收集相关节点ID(包括父节点和子节点)
|
|
|
|
|
+ */
|
|
|
|
|
+ private void collectRelatedNodeIds(Integer nodeId, List<UserActionRewardRule> allRecords, Set<Integer> nodeIds) {
|
|
|
|
|
+ if (nodeIds.contains(nodeId)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ nodeIds.add(nodeId);
|
|
|
|
|
+
|
|
|
|
|
+ // 查找当前节点
|
|
|
|
|
+ UserActionRewardRule currentNode = allRecords.stream()
|
|
|
|
|
+ .filter(r -> r.getId().equals(nodeId))
|
|
|
|
|
+ .findFirst()
|
|
|
|
|
+ .orElse(null);
|
|
|
|
|
+
|
|
|
|
|
+ if (currentNode == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 向上查找父节点
|
|
|
|
|
+ if (currentNode.getParentId() != null && currentNode.getParentId() != 0) {
|
|
|
|
|
+ collectRelatedNodeIds(currentNode.getParentId(), allRecords, nodeIds);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 向下查找子节点
|
|
|
|
|
+ for (UserActionRewardRule record : allRecords) {
|
|
|
|
|
+ if (nodeId.equals(record.getParentId())) {
|
|
|
|
|
+ collectRelatedNodeIds(record.getId(), allRecords, nodeIds);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 递归构建树形节点
|
|
|
|
|
+ */
|
|
|
|
|
+ private RewardRuleTreeNodeVo buildTreeNode(UserActionRewardRule node, Map<Integer, List<UserActionRewardRule>> childrenMap) {
|
|
|
|
|
+ RewardRuleTreeNodeVo treeNode = new RewardRuleTreeNodeVo();
|
|
|
|
|
+ treeNode.setValue(node.getName());
|
|
|
|
|
+ treeNode.setLabel(node.getName());
|
|
|
|
|
+ // disabled逻辑:status=1表示启用,所以disabled应该是status!=1
|
|
|
|
|
+ treeNode.setDisabled(node.getStatus() == null || node.getStatus() != 1);
|
|
|
|
|
+
|
|
|
|
|
+ // 获取子节点
|
|
|
|
|
+ List<UserActionRewardRule> children = childrenMap.getOrDefault(node.getId(), new ArrayList<>());
|
|
|
|
|
+ if (!children.isEmpty()) {
|
|
|
|
|
+ List<RewardRuleTreeNodeVo> childNodes = new ArrayList<>();
|
|
|
|
|
+ // 按sort_order降序排序,然后按id升序排序
|
|
|
|
|
+ children.sort((a, b) -> {
|
|
|
|
|
+ int sortCompare = Integer.compare(
|
|
|
|
|
+ b.getSortOrder() == null ? 0 : b.getSortOrder(),
|
|
|
|
|
+ a.getSortOrder() == null ? 0 : a.getSortOrder()
|
|
|
|
|
+ );
|
|
|
|
|
+ if (sortCompare != 0) {
|
|
|
|
|
+ return sortCompare;
|
|
|
|
|
+ }
|
|
|
|
|
+ return Integer.compare(a.getId(), b.getId());
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ for (UserActionRewardRule child : children) {
|
|
|
|
|
+ RewardRuleTreeNodeVo childNode = buildTreeNode(child, childrenMap);
|
|
|
|
|
+ childNodes.add(childNode);
|
|
|
|
|
+ }
|
|
|
|
|
+ treeNode.setChildren(childNodes);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return treeNode;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public UserActionRewardRule getRewardRuleById(Integer id) {
|
|
public UserActionRewardRule getRewardRuleById(Integer id) {
|
|
@@ -145,13 +191,22 @@ public class UserActionRewardRuleServiceImpl extends ServiceImpl<UserActionRewar
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 校验必填字段
|
|
// 校验必填字段
|
|
|
- if (StringUtils.isEmpty(rewardRule.getAction())) {
|
|
|
|
|
- return R.fail("行为不能为空");
|
|
|
|
|
|
|
+ if (StringUtils.isEmpty(rewardRule.getName())) {
|
|
|
|
|
+ return R.fail("名称不能为空");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (rewardRule.getLevel() == null || rewardRule.getLevel() < 1 || rewardRule.getLevel() > 3) {
|
|
|
|
|
+ return R.fail("层级必须为1(角色)、2(行为)或3(奖励)");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (rewardRule.getLevel() > 1 && rewardRule.getParentId() == null) {
|
|
|
|
|
+ return R.fail("非根节点必须指定父节点ID");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
if (rewardRule.getId() == null) {
|
|
if (rewardRule.getId() == null) {
|
|
|
// 新增
|
|
// 新增
|
|
|
|
|
+ if (rewardRule.getParentId() == null) {
|
|
|
|
|
+ rewardRule.setParentId(0); // 根节点parent_id为0
|
|
|
|
|
+ }
|
|
|
if (rewardRule.getStatus() == null) {
|
|
if (rewardRule.getStatus() == null) {
|
|
|
rewardRule.setStatus(1); // 默认启用
|
|
rewardRule.setStatus(1); // 默认启用
|
|
|
}
|
|
}
|
|
@@ -186,12 +241,21 @@ public class UserActionRewardRuleServiceImpl extends ServiceImpl<UserActionRewar
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
|
|
+ // 查找所有需要删除的节点ID(包括子节点)
|
|
|
|
|
+ Set<Integer> nodeIdsToDelete = new HashSet<>();
|
|
|
|
|
+ collectChildNodeIds(id, nodeIdsToDelete);
|
|
|
|
|
+
|
|
|
|
|
+ if (nodeIdsToDelete.isEmpty()) {
|
|
|
|
|
+ return R.fail("删除失败,记录不存在或已删除");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 批量逻辑删除
|
|
|
LambdaUpdateWrapper<UserActionRewardRule> updateWrapper = new LambdaUpdateWrapper<>();
|
|
LambdaUpdateWrapper<UserActionRewardRule> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
- updateWrapper.eq(UserActionRewardRule::getId, id)
|
|
|
|
|
|
|
+ updateWrapper.in(UserActionRewardRule::getId, nodeIdsToDelete)
|
|
|
.set(UserActionRewardRule::getDeleteFlag, 1);
|
|
.set(UserActionRewardRule::getDeleteFlag, 1);
|
|
|
int result = userActionRewardRuleMapper.update(null, updateWrapper);
|
|
int result = userActionRewardRuleMapper.update(null, updateWrapper);
|
|
|
if (result > 0) {
|
|
if (result > 0) {
|
|
|
- return R.data("删除成功");
|
|
|
|
|
|
|
+ return R.data("删除成功,共删除 " + result + " 条记录(含子节点)");
|
|
|
} else {
|
|
} else {
|
|
|
return R.fail("删除失败,记录不存在或已删除");
|
|
return R.fail("删除失败,记录不存在或已删除");
|
|
|
}
|
|
}
|
|
@@ -200,6 +264,26 @@ public class UserActionRewardRuleServiceImpl extends ServiceImpl<UserActionRewar
|
|
|
return R.fail("删除失败:" + e.getMessage());
|
|
return R.fail("删除失败:" + e.getMessage());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 递归收集所有子节点ID
|
|
|
|
|
+ */
|
|
|
|
|
+ private void collectChildNodeIds(Integer parentId, Set<Integer> nodeIds) {
|
|
|
|
|
+ if (nodeIds.contains(parentId)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ nodeIds.add(parentId);
|
|
|
|
|
+
|
|
|
|
|
+ // 查找所有子节点
|
|
|
|
|
+ LambdaQueryWrapper<UserActionRewardRule> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ queryWrapper.eq(UserActionRewardRule::getParentId, parentId)
|
|
|
|
|
+ .eq(UserActionRewardRule::getDeleteFlag, 0);
|
|
|
|
|
+ List<UserActionRewardRule> children = userActionRewardRuleMapper.selectList(queryWrapper);
|
|
|
|
|
+
|
|
|
|
|
+ for (UserActionRewardRule child : children) {
|
|
|
|
|
+ collectChildNodeIds(child.getId(), nodeIds);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public R<String> updateRewardRuleStatus(Integer id, Integer status) {
|
|
public R<String> updateRewardRuleStatus(Integer id, Integer status) {
|