Explorar o código

feat: add Distribution system module (entities+mappers+service+controller)

Add distribution system and distribution relation entities with CRUD admin controller.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
liaoxg hai 2 meses
pai
achega
00d1fcc0e9

+ 78 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminDistributionController.java

@@ -0,0 +1,78 @@
+package com.etotem.cfc.controller.admin;
+
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.entity.DistributionRelation;
+import com.etotem.cfc.entity.DistributionSystem;
+import com.etotem.cfc.service.DistributionService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+@Tag(name = "管理端-分销管理")
+@RestController
+@RequestMapping("/api/admin/distribution")
+public class AdminDistributionController {
+
+    @Resource
+    private DistributionService distributionService;
+
+    @Operation(summary = "创建分销体系")
+    @PostMapping("/system/create")
+    public Result<String> createSystem(@RequestBody DistributionSystem system) {
+        return distributionService.createSystem(system);
+    }
+
+    @Operation(summary = "更新分销体系")
+    @PostMapping("/system/update")
+    public Result<String> updateSystem(@RequestBody DistributionSystem system) {
+        return distributionService.updateSystem(system);
+    }
+
+    @Operation(summary = "分销体系列表")
+    @PostMapping("/system/list")
+    public Result<List<DistributionSystem>> listSystems() {
+        return distributionService.listSystems();
+    }
+
+    @Operation(summary = "启用/禁用分销体系")
+    @PostMapping("/system/toggle")
+    public Result<String> toggleSystem(@RequestBody Map<String, Object> params) {
+        Long id = params.get("id") != null ? Long.valueOf(params.get("id").toString()) : null;
+        if (id == null) return Result.error("id不能为空");
+        return distributionService.toggleSystem(id);
+    }
+
+    @Operation(summary = "分销关系列表")
+    @PostMapping("/relation/list")
+    public Result<List<DistributionRelation>> listRelations(@RequestBody Map<String, Object> params) {
+        Long systemId = params.get("systemId") != null ? Long.valueOf(params.get("systemId").toString()) : null;
+        Long userId = params.get("userId") != null ? Long.valueOf(params.get("userId").toString()) : null;
+        return distributionService.listRelations(systemId, userId);
+    }
+
+    @Operation(summary = "添加分销关系")
+    @PostMapping("/relation/add")
+    public Result<Void> addRelation(@RequestBody Map<String, Object> params) {
+        Long systemId = params.get("systemId") != null ? Long.valueOf(params.get("systemId").toString()) : null;
+        Long userId = params.get("userId") != null ? Long.valueOf(params.get("userId").toString()) : null;
+        Long parentId = params.get("parentId") != null ? Long.valueOf(params.get("parentId").toString()) : null;
+        if (systemId == null) return Result.error("systemId不能为空");
+        if (userId == null) return Result.error("userId不能为空");
+        return distributionService.addRelation(systemId, userId, parentId);
+    }
+
+    @Operation(summary = "移除分销关系")
+    @PostMapping("/relation/remove")
+    public Result<String> removeRelation(@RequestBody Map<String, Object> params) {
+        Long id = params.get("id") != null ? Long.valueOf(params.get("id").toString()) : null;
+        if (id == null) return Result.error("id不能为空");
+        return distributionService.removeRelation(id);
+    }
+}

+ 20 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/DistributionRelation.java

@@ -0,0 +1,20 @@
+package com.etotem.cfc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("distribution_relations")
+public class DistributionRelation implements Serializable {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private Long systemId;
+    private Long userId;
+    private Long parentId;
+    private Integer depth;
+    private Date createdAt;
+}

+ 22 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/DistributionSystem.java

@@ -0,0 +1,22 @@
+package com.etotem.cfc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("distribution_systems")
+public class DistributionSystem implements Serializable {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private String name;
+    private String description;
+    private Long ownerId;
+    private Integer profitRate;
+    private Boolean enabled;
+    private Date createdAt;
+    private Date updatedAt;
+}

+ 9 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/DistributionRelationMapper.java

@@ -0,0 +1,9 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.DistributionRelation;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface DistributionRelationMapper extends BaseMapper<DistributionRelation> {
+}

+ 9 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/DistributionSystemMapper.java

@@ -0,0 +1,9 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.DistributionSystem;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface DistributionSystemMapper extends BaseMapper<DistributionSystem> {
+}

+ 175 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/DistributionService.java

@@ -0,0 +1,175 @@
+package com.etotem.cfc.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.etotem.cfc.common.Result;
+import com.etotem.cfc.entity.DistributionRelation;
+import com.etotem.cfc.entity.DistributionSystem;
+import com.etotem.cfc.mapper.DistributionRelationMapper;
+import com.etotem.cfc.mapper.DistributionSystemMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+@Service
+public class DistributionService {
+
+    @Resource
+    private DistributionSystemMapper distributionSystemMapper;
+
+    @Resource
+    private DistributionRelationMapper distributionRelationMapper;
+
+    public Result<String> createSystem(DistributionSystem system) {
+        system.setEnabled(true);
+        system.setCreatedAt(new Date());
+        system.setUpdatedAt(new Date());
+        distributionSystemMapper.insert(system);
+        return Result.success("创建成功");
+    }
+
+    public Result<String> updateSystem(DistributionSystem system) {
+        DistributionSystem existing = distributionSystemMapper.selectById(system.getId());
+        if (existing == null) return Result.error("分销体系不存在");
+
+        if (system.getName() != null) existing.setName(system.getName());
+        if (system.getDescription() != null) existing.setDescription(system.getDescription());
+        if (system.getProfitRate() != null) existing.setProfitRate(system.getProfitRate());
+        existing.setUpdatedAt(new Date());
+        distributionSystemMapper.updateById(existing);
+        return Result.success("更新成功");
+    }
+
+    public Result<List<DistributionSystem>> listSystems() {
+        List<DistributionSystem> list = distributionSystemMapper.selectList(
+            new LambdaQueryWrapper<DistributionSystem>().orderByDesc(DistributionSystem::getCreatedAt)
+        );
+        return Result.success(list);
+    }
+
+    public Result<String> toggleSystem(Long id) {
+        DistributionSystem system = distributionSystemMapper.selectById(id);
+        if (system == null) return Result.error("分销体系不存在");
+
+        system.setEnabled(!Boolean.TRUE.equals(system.getEnabled()));
+        system.setUpdatedAt(new Date());
+        distributionSystemMapper.updateById(system);
+        return Result.success(system.getEnabled() ? "已启用" : "已禁用");
+    }
+
+    public Result<Void> addRelation(Long systemId, Long userId, Long parentId) {
+        DistributionRelation existing = distributionRelationMapper.selectOne(
+            new LambdaQueryWrapper<DistributionRelation>()
+                .eq(DistributionRelation::getSystemId, systemId)
+                .eq(DistributionRelation::getUserId, userId)
+        );
+        if (existing != null) return Result.error("用户已在该分销体系中");
+
+        DistributionRelation relation = new DistributionRelation();
+        relation.setSystemId(systemId);
+        relation.setUserId(userId);
+        relation.setParentId(parentId);
+        relation.setCreatedAt(new Date());
+
+        if (parentId == null) {
+            relation.setDepth(0);
+        } else {
+            DistributionRelation parent = distributionRelationMapper.selectOne(
+                new LambdaQueryWrapper<DistributionRelation>()
+                    .eq(DistributionRelation::getSystemId, systemId)
+                    .eq(DistributionRelation::getUserId, parentId)
+            );
+            if (parent == null) return Result.error("上级节点不存在");
+            relation.setDepth(parent.getDepth() + 1);
+        }
+
+        distributionRelationMapper.insert(relation);
+        return Result.success();
+    }
+
+    public Result<String> removeRelation(Long id) {
+        DistributionRelation relation = distributionRelationMapper.selectById(id);
+        if (relation == null) return Result.error("关系不存在");
+
+        List<DistributionRelation> children = distributionRelationMapper.selectList(
+            new LambdaQueryWrapper<DistributionRelation>()
+                .eq(DistributionRelation::getParentId, relation.getUserId())
+                .eq(DistributionRelation::getSystemId, relation.getSystemId())
+        );
+        if (!children.isEmpty()) return Result.error("该节点存在下级节点,无法删除");
+
+        distributionRelationMapper.deleteById(id);
+        return Result.success("移除成功");
+    }
+
+    public Result<List<DistributionRelation>> listRelations(Long systemId, Long userId) {
+        LambdaQueryWrapper<DistributionRelation> wrapper = new LambdaQueryWrapper<>();
+        if (systemId != null) wrapper.eq(DistributionRelation::getSystemId, systemId);
+        if (userId != null) wrapper.eq(DistributionRelation::getUserId, userId);
+        wrapper.orderByAsc(DistributionRelation::getDepth).orderByDesc(DistributionRelation::getCreatedAt);
+        return Result.success(distributionRelationMapper.selectList(wrapper));
+    }
+
+    public Result<List<DistributionRelation>> getParentChain(Long systemId, Long userId) {
+        List<DistributionRelation> chain = new ArrayList<>();
+        Long currentUserId = userId;
+        for (int i = 0; i < 10; i++) {
+            DistributionRelation relation = distributionRelationMapper.selectOne(
+                new LambdaQueryWrapper<DistributionRelation>()
+                    .eq(DistributionRelation::getSystemId, systemId)
+                    .eq(DistributionRelation::getUserId, currentUserId)
+            );
+            if (relation == null || relation.getParentId() == null) break;
+            DistributionRelation parent = distributionRelationMapper.selectOne(
+                new LambdaQueryWrapper<DistributionRelation>()
+                    .eq(DistributionRelation::getSystemId, systemId)
+                    .eq(DistributionRelation::getUserId, relation.getParentId())
+            );
+            if (parent == null) break;
+            chain.add(parent);
+            currentUserId = relation.getParentId();
+        }
+        return Result.success(chain);
+    }
+
+    public Result<Map<String, Object>> calculateCommission(Long systemId, Long buyerId, Integer orderAmount) {
+        DistributionSystem system = distributionSystemMapper.selectById(systemId);
+        if (system == null || !Boolean.TRUE.equals(system.getEnabled())) {
+            return Result.error("分销体系不可用");
+        }
+
+        int totalCommission = orderAmount * system.getProfitRate() / 1000;
+
+        List<DistributionRelation> chain = new ArrayList<>();
+        Long currentUserId = buyerId;
+        for (int i = 0; i < 2; i++) {
+            DistributionRelation relation = distributionRelationMapper.selectOne(
+                new LambdaQueryWrapper<DistributionRelation>()
+                    .eq(DistributionRelation::getSystemId, systemId)
+                    .eq(DistributionRelation::getUserId, currentUserId)
+            );
+            if (relation == null || relation.getParentId() == null) break;
+            DistributionRelation parent = distributionRelationMapper.selectOne(
+                new LambdaQueryWrapper<DistributionRelation>()
+                    .eq(DistributionRelation::getSystemId, systemId)
+                    .eq(DistributionRelation::getUserId, relation.getParentId())
+            );
+            if (parent == null) break;
+            chain.add(parent);
+            currentUserId = relation.getParentId();
+        }
+
+        int level1Amount = totalCommission * 70 / 100;
+        int level2Amount = totalCommission * 30 / 100;
+
+        Map<String, Object> result = new LinkedHashMap<>();
+        result.put("totalCommission", totalCommission);
+        result.put("level1Amount", chain.size() >= 1 ? level1Amount : 0);
+        result.put("level1User", chain.size() >= 1 ? chain.get(0).getUserId() : null);
+        result.put("level2Amount", chain.size() >= 2 ? level2Amount : 0);
+        result.put("level2User", chain.size() >= 2 ? chain.get(1).getUserId() : null);
+        result.put("platformAmount", totalCommission - (chain.size() >= 1 ? level1Amount : 0)
+            - (chain.size() >= 2 ? level2Amount : 0));
+        return Result.success(result);
+    }
+}