Jelajahi Sumber

bugfix:运营活动表修改,直接自关联三级结构

lyx 1 Minggu lalu
induk
melakukan
8cc5b4b504

+ 16 - 12
alien-entity/src/main/java/shop/alien/entity/store/UserActionRewardRule.java

@@ -18,30 +18,34 @@ import java.util.Date;
 @Data
 @JsonInclude
 @TableName("user_action_reward_rule")
-@ApiModel(value = "UserActionRewardRule", description = "用户行为奖励规则配置表")
+@ApiModel(value = "UserActionRewardRule", description = "用户行为奖励规则配置表(3级树形结构)")
 public class UserActionRewardRule {
 
-    @ApiModelProperty(value = "主键")
+    @ApiModelProperty(value = "主键ID")
     @TableId(value = "id", type = IdType.AUTO)
     private Integer id;
 
-    @ApiModelProperty(value = "角色(如:当用户)")
-    @TableField("role")
-    private String role;
+    @ApiModelProperty(value = "父节点ID,0表示根节点(第一级:角色)")
+    @TableField("parent_id")
+    private Integer parentId;
 
-    @ApiModelProperty(value = "行为(如:核销并评论、核销、打卡)")
-    @TableField("action")
-    private String action;
+    @ApiModelProperty(value = "层级:1-角色,2-行为,3-奖励")
+    @TableField("level")
+    private Integer level;
 
-    @ApiModelProperty(value = "奖励(如:优惠券、红包)")
-    @TableField("reward")
-    private String reward;
+    @ApiModelProperty(value = "名称:根据level区分,1-角色名,2-行为名,3-奖励名")
+    @TableField("name")
+    private String name;
+
+    @ApiModelProperty(value = "奖励数量:如1优惠券、2红包(仅第三级使用)")
+    @TableField("reward_amount")
+    private Integer rewardAmount;
 
     @ApiModelProperty(value = "状态:0-禁用,1-启用")
     @TableField("status")
     private Integer status;
 
-    @ApiModelProperty(value = "排序")
+    @ApiModelProperty(value = "排序:数值越大越靠前")
     @TableField("sort_order")
     private Integer sortOrder;
 

+ 173 - 89
alien-store/src/main/java/shop/alien/store/service/impl/UserActionRewardRuleServiceImpl.java

@@ -2,9 +2,7 @@ package shop.alien.store.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 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.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -15,10 +13,8 @@ import shop.alien.entity.store.vo.RewardRuleTreeNodeVo;
 import shop.alien.mapper.UserActionRewardRuleMapper;
 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;
 
 
-    // TODO 垃圾代码,运营活动
     @Override
     public List<RewardRuleTreeNodeVo> getRewardRuleList(int page, int size, String role, String action, String reward, Integer status) {
+        // 查询所有数据(不分页,因为需要构建完整树形结构)
         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.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;
     }
+    
+    /**
+     * 收集相关节点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
     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 {
             if (rewardRule.getId() == null) {
                 // 新增
+                if (rewardRule.getParentId() == null) {
+                    rewardRule.setParentId(0); // 根节点parent_id为0
+                }
                 if (rewardRule.getStatus() == null) {
                     rewardRule.setStatus(1); // 默认启用
                 }
@@ -186,12 +241,21 @@ public class UserActionRewardRuleServiceImpl extends ServiceImpl<UserActionRewar
         }
 
         try {
+            // 查找所有需要删除的节点ID(包括子节点)
+            Set<Integer> nodeIdsToDelete = new HashSet<>();
+            collectChildNodeIds(id, nodeIdsToDelete);
+            
+            if (nodeIdsToDelete.isEmpty()) {
+                return R.fail("删除失败,记录不存在或已删除");
+            }
+            
+            // 批量逻辑删除
             LambdaUpdateWrapper<UserActionRewardRule> updateWrapper = new LambdaUpdateWrapper<>();
-            updateWrapper.eq(UserActionRewardRule::getId, id)
+            updateWrapper.in(UserActionRewardRule::getId, nodeIdsToDelete)
                     .set(UserActionRewardRule::getDeleteFlag, 1);
             int result = userActionRewardRuleMapper.update(null, updateWrapper);
             if (result > 0) {
-                return R.data("删除成功");
+                return R.data("删除成功,共删除 " + result + " 条记录(含子节点)");
             } else {
                 return R.fail("删除失败,记录不存在或已删除");
             }
@@ -200,6 +264,26 @@ public class UserActionRewardRuleServiceImpl extends ServiceImpl<UserActionRewar
             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
     public R<String> updateRewardRuleStatus(Integer id, Integer status) {