首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >常见分销系统设计:架构、数据模型与分佣规则

常见分销系统设计:架构、数据模型与分佣规则

作者头像
编程小白狼
发布2025-11-07 08:03:21
发布2025-11-07 08:03:21
2220
举报
文章被收录于专栏:编程小白狼编程小白狼

1. 系统概述

分销系统是一种基于社交关系的电商营销模式,通过多级分销网络实现商品推广和销售。本文将详细介绍分销系统的技术架构、数据库设计和分佣规则实现。

2. 系统架构设计

2.1 整体架构
代码语言:javascript
复制
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   客户端层       │    │     API网关      │    │   业务服务层     │
│ - Web前端       │───▶│ - 路由转发       │───▶│ - 用户服务      │
│ - 移动APP       │    │ - 认证鉴权       │    │ - 商品服务      │
│ - 小程序        │    │ - 限流熔断       │    │ - 订单服务      │
└─────────────────┘    └──────────────────┘    └─────────────────┘
                                                          │
                                                          ▼
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   数据存储层     │◀──│    数据访问层     │◀──│   分销服务层     │
│ - MySQL         │    │ - MyBatis        │    │ - 关系管理      │
│ - Redis         │    │ - JPA            │    │ - 分佣计算      │
│ - Elasticsearch │    │ - Redis Template │    │ - 结算服务      │
└─────────────────┘    └──────────────────┘    └─────────────────┘
2.2 核心服务模块
代码语言:javascript
复制
// 分销系统核心服务类图
public class DistributionSystem {
    // 用户服务
    UserService userService;
    // 分销关系服务
    DistributionRelationService relationService;
    // 分佣服务
    CommissionService commissionService;
    // 结算服务
    SettlementService settlementService;
    // 规则引擎
    RuleEngine ruleEngine;
}

3. 数据库设计

3.1 核心表结构
用户表 (users)
代码语言:javascript
复制
CREATE TABLE users (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(100) NOT NULL UNIQUE,
    email VARCHAR(255),
    phone VARCHAR(20),
    user_type TINYINT NOT NULL COMMENT '1-普通用户 2-分销员',
    invite_code VARCHAR(20) NOT NULL UNIQUE COMMENT '邀请码',
    parent_id BIGINT COMMENT '上级用户ID',
    distribution_level INT DEFAULT 0 COMMENT '分销层级',
    status TINYINT DEFAULT 1 COMMENT '状态',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    
    INDEX idx_parent_id (parent_id),
    INDEX idx_invite_code (invite_code)
);
分销关系表 (distribution_relations)
代码语言:javascript
复制
CREATE TABLE distribution_relations (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT NOT NULL,
    ancestor_id BIGINT NOT NULL COMMENT '祖先节点ID',
    level INT NOT NULL COMMENT '关系层级',
    commission_rate DECIMAL(5,4) COMMENT '该层级分佣比例',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    UNIQUE KEY uk_user_ancestor (user_id, ancestor_id),
    INDEX idx_user_id (user_id),
    INDEX idx_ancestor_id (ancestor_id)
);
订单表 (orders)
代码语言:javascript
复制
CREATE TABLE orders (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    order_no VARCHAR(50) NOT NULL UNIQUE,
    user_id BIGINT NOT NULL,
    total_amount DECIMAL(10,2) NOT NULL COMMENT '订单总金额',
    actual_amount DECIMAL(10,2) NOT NULL COMMENT '实际支付金额',
    commission_base DECIMAL(10,2) NOT NULL COMMENT '分佣基数',
    status TINYINT NOT NULL COMMENT '订单状态',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    INDEX idx_user_id (user_id),
    INDEX idx_created_at (created_at)
);
分佣记录表 (commission_records)
代码语言:javascript
复制
CREATE TABLE commission_records (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    order_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL COMMENT '获得佣金的用户',
    from_user_id BIGINT NOT NULL COMMENT '来源用户',
    commission_level INT NOT NULL COMMENT '分佣层级',
    commission_rate DECIMAL(5,4) NOT NULL COMMENT '分佣比例',
    commission_amount DECIMAL(10,2) NOT NULL COMMENT '分佣金额',
    commission_base DECIMAL(10,2) NOT NULL COMMENT '分佣基数',
    status TINYINT NOT NULL COMMENT '1-待结算 2-已结算 3-已取消',
    settled_at TIMESTAMP NULL COMMENT '结算时间',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    INDEX idx_user_id (user_id),
    INDEX idx_order_id (order_id),
    INDEX idx_status (status)
);
分佣规则表 (commission_rules)
代码语言:javascript
复制
CREATE TABLE commission_rules (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    rule_name VARCHAR(100) NOT NULL,
    rule_type TINYINT NOT NULL COMMENT '1-固定比例 2-阶梯比例 3-固定金额',
    level_config JSON NOT NULL COMMENT '层级配置',
    product_categories JSON COMMENT '适用商品分类',
    status TINYINT DEFAULT 1,
    start_time TIMESTAMP NULL,
    end_time TIMESTAMP NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

4. 核心代码实现

4.1 分销关系管理
代码语言:javascript
复制
@Service
@Slf4j
public class DistributionRelationService {
    
    @Autowired
    private DistributionRelationMapper relationMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    /**
     * 建立分销关系
     */
    @Transactional
    public void buildDistributionRelation(Long userId, String inviteCode) {
        // 1. 验证邀请码
        User parentUser = userMapper.selectByInviteCode(inviteCode);
        if (parentUser == null) {
            throw new BusinessException("无效的邀请码");
        }
        
        // 2. 防止循环引用
        if (userId.equals(parentUser.getId())) {
            throw new BusinessException("不能邀请自己");
        }
        
        // 3. 更新用户的直接上级
        User currentUser = userMapper.selectById(userId);
        currentUser.setParentId(parentUser.getId());
        userMapper.updateById(currentUser);
        
        // 4. 建立多级关系链
        buildRelationChain(userId, parentUser.getId());
    }
    
    /**
     * 构建完整的关系链
     */
    private void buildRelationChain(Long userId, Long parentId) {
        // 获取上级的所有祖先关系
        List<DistributionRelation> parentRelations = 
            relationMapper.selectByUserId(parentId);
        
        List<DistributionRelation> newRelations = new ArrayList<>();
        
        // 添加直接上级关系
        DistributionRelation directRelation = new DistributionRelation();
        directRelation.setUserId(userId);
        directRelation.setAncestorId(parentId);
        directRelation.setLevel(1);
        newRelations.add(directRelation);
        
        // 添加上级的祖先关系
        for (DistributionRelation parentRelation : parentRelations) {
            DistributionRelation relation = new DistributionRelation();
            relation.setUserId(userId);
            relation.setAncestorId(parentRelation.getAncestorId());
            relation.setLevel(parentRelation.getLevel() + 1);
            newRelations.add(relation);
        }
        
        // 批量插入关系
        relationMapper.batchInsert(newRelations);
        
        // 更新用户层级
        User user = userMapper.selectById(userId);
        user.setDistributionLevel(getMaxLevel(newRelations));
        userMapper.updateById(user);
    }
    
    /**
     * 获取用户的所有下级
     */
    public List<Long> getSubordinateUsers(Long userId, Integer maxLevel) {
        return relationMapper.selectSubordinateUserIds(userId, maxLevel);
    }
}
4.2 分佣规则引擎
代码语言:javascript
复制
@Service
public class CommissionRuleEngine {
    
    @Autowired
    private CommissionRuleMapper ruleMapper;
    
    /**
     * 计算分佣
     */
    public List<CommissionDetail> calculateCommission(Order order, Long distributorId) {
        // 1. 获取适用的分佣规则
        CommissionRule rule = getApplicableRule(order);
        
        // 2. 获取分销关系链
        List<DistributionRelation> relations = 
            relationMapper.selectByUserId(distributorId);
        
        // 3. 根据规则类型计算分佣
        List<CommissionDetail> commissionDetails = new ArrayList<>();
        
        switch (rule.getRuleType()) {
            case FIXED_RATE:
                commissionDetails = calculateFixedRateCommission(order, relations, rule);
                break;
            case LADDER_RATE:
                commissionDetails = calculateLadderRateCommission(order, relations, rule);
                break;
            case FIXED_AMOUNT:
                commissionDetails = calculateFixedAmountCommission(order, relations, rule);
                break;
        }
        
        return commissionDetails;
    }
    
    /**
     * 固定比例分佣计算
     */
    private List<CommissionDetail> calculateFixedRateCommission(
            Order order, 
            List<DistributionRelation> relations, 
            CommissionRule rule) {
        
        List<CommissionDetail> details = new ArrayList<>();
        JSONObject levelConfig = JSON.parseObject(rule.getLevelConfig());
        
        for (DistributionRelation relation : relations) {
            String levelKey = "level_" + relation.getLevel();
            if (levelConfig.containsKey(levelKey)) {
                BigDecimal rate = levelConfig.getBigDecimal(levelKey);
                BigDecimal amount = order.getCommissionBase().multiply(rate);
                
                if (amount.compareTo(BigDecimal.ZERO) > 0) {
                    CommissionDetail detail = new CommissionDetail();
                    detail.setUserId(relation.getAncestorId());
                    detail.setFromUserId(order.getUserId());
                    detail.setCommissionLevel(relation.getLevel());
                    detail.setCommissionRate(rate);
                    detail.setCommissionAmount(amount);
                    detail.setCommissionBase(order.getCommissionBase());
                    details.add(detail);
                }
            }
        }
        
        return details;
    }
    
    /**
     * 阶梯比例分佣计算
     */
    private List<CommissionDetail> calculateLadderRateCommission(
            Order order, 
            List<DistributionRelation> relations, 
            CommissionRule rule) {
        
        List<CommissionDetail> details = new ArrayList<>();
        JSONArray ladderConfig = JSON.parseArray(rule.getLevelConfig());
        
        // 按订单金额匹配阶梯
        BigDecimal orderAmount = order.getActualAmount();
        JSONObject matchedLadder = findMatchedLadder(ladderConfig, orderAmount);
        
        if (matchedLadder != null) {
            JSONObject rates = matchedLadder.getJSONObject("rates");
            
            for (DistributionRelation relation : relations) {
                String levelKey = "level_" + relation.getLevel();
                if (rates.containsKey(levelKey)) {
                    BigDecimal rate = rates.getBigDecimal(levelKey);
                    BigDecimal amount = order.getCommissionBase().multiply(rate);
                    
                    if (amount.compareTo(BigDecimal.ZERO) > 0) {
                        CommissionDetail detail = buildCommissionDetail(
                            order, relation, rate, amount);
                        details.add(detail);
                    }
                }
            }
        }
        
        return details;
    }
    
    private JSONObject findMatchedLadder(JSONArray ladderConfig, BigDecimal orderAmount) {
        for (int i = 0; i < ladderConfig.size(); i++) {
            JSONObject ladder = ladderConfig.getJSONObject(i);
            BigDecimal minAmount = ladder.getBigDecimal("minAmount");
            BigDecimal maxAmount = ladder.getBigDecimal("maxAmount");
            
            if (orderAmount.compareTo(minAmount) >= 0 && 
                (maxAmount == null || orderAmount.compareTo(maxAmount) < 0)) {
                return ladder;
            }
        }
        return null;
    }
}
4.3 分佣执行服务
代码语言:javascript
复制
@Service
@Slf4j
public class CommissionService {
    
    @Autowired
    private CommissionRecordMapper commissionRecordMapper;
    
    @Autowired
    private DistributionRelationService relationService;
    
    @Autowired
    private CommissionRuleEngine ruleEngine;
    
    /**
     * 处理订单分佣
     */
    @Transactional
    public void processOrderCommission(Order order) {
        // 1. 检查订单是否满足分佣条件
        if (!shouldProcessCommission(order)) {
            return;
        }
        
        // 2. 获取分销用户(订单用户)
        Long distributorId = order.getUserId();
        
        // 3. 计算分佣详情
        List<CommissionDetail> commissionDetails = 
            ruleEngine.calculateCommission(order, distributorId);
        
        // 4. 保存分佣记录
        List<CommissionRecord> records = new ArrayList<>();
        for (CommissionDetail detail : commissionDetails) {
            CommissionRecord record = buildCommissionRecord(order, detail);
            records.add(record);
        }
        
        commissionRecordMapper.batchInsert(records);
        
        log.info("订单分佣处理完成,订单ID: {}, 分佣记录数: {}", 
                 order.getId(), records.size());
    }
    
    /**
     * 判断是否应该处理分佣
     */
    private boolean shouldProcessCommission(Order order) {
        // 只对已支付的订单进行分佣
        if (!OrderStatus.PAID.equals(order.getStatus())) {
            return false;
        }
        
        // 检查分佣基数是否大于0
        if (order.getCommissionBase().compareTo(BigDecimal.ZERO) <= 0) {
            return false;
        }
        
        // 检查用户是否是分销员
        User user = userMapper.selectById(order.getUserId());
        return user != null && UserType.DISTRIBUTOR.equals(user.getUserType());
    }
    
    /**
     * 构建分佣记录
     */
    private CommissionRecord buildCommissionRecord(Order order, CommissionDetail detail) {
        CommissionRecord record = new CommissionRecord();
        record.setOrderId(order.getId());
        record.setUserId(detail.getUserId());
        record.setFromUserId(detail.getFromUserId());
        record.setCommissionLevel(detail.getCommissionLevel());
        record.setCommissionRate(detail.getCommissionRate());
        record.setCommissionAmount(detail.getCommissionAmount());
        record.setCommissionBase(detail.getCommissionBase());
        record.setStatus(CommissionStatus.PENDING);
        return record;
    }
    
    /**
     * 结算分佣
     */
    @Transactional
    public void settleCommissions(List<Long> recordIds) {
        List<CommissionRecord> records = commissionRecordMapper.selectByIds(recordIds);
        
        for (CommissionRecord record : records) {
            if (CommissionStatus.PENDING.equals(record.getStatus())) {
                // 更新记录状态
                record.setStatus(CommissionStatus.SETTLED);
                record.setSettledAt(new Date());
                commissionRecordMapper.updateById(record);
                
                // 实际资金操作(调用支付服务)
                transferCommission(record);
            }
        }
    }
    
    /**
     * 资金转账(简化实现)
     */
    private void transferCommission(CommissionRecord record) {
        // 调用支付系统API或更新用户余额
        log.info("分佣转账: 用户 {} 获得佣金 {}", 
                 record.getUserId(), record.getCommissionAmount());
    }
}

5. 分佣规则设计

5.1 常见分佣模式
5.1.1 固定比例模式
代码语言:javascript
复制
{
  "rule_type": "FIXED_RATE",
  "level_config": {
    "level_1": 0.10,
    "level_2": 0.05,
    "level_3": 0.03
  }
}
5.1.2 阶梯比例模式
代码语言:javascript
复制
{
  "rule_type": "LADDER_RATE",
  "level_config": [
    {
      "minAmount": 0,
      "maxAmount": 100,
      "rates": {
        "level_1": 0.08,
        "level_2": 0.04
      }
    },
    {
      "minAmount": 100,
      "maxAmount": 500,
      "rates": {
        "level_1": 0.12,
        "level_2": 0.06,
        "level_3": 0.03
      }
    }
  ]
}
5.1.3 团队业绩模式
代码语言:javascript
复制
// 基于团队总业绩的分佣
public class TeamPerformanceRule {
    private Map<String, BigDecimal> performanceRates;
    private Map<String, BigDecimal> teamRates;
    
    public List<CommissionDetail> calculateTeamCommission(
            Order order, 
            User distributor,
            TeamPerformance performance) {
        
        // 计算个人业绩分佣
        BigDecimal personalRate = getPersonalRate(performance.getPersonalSales());
        BigDecimal personalCommission = order.getCommissionBase().multiply(personalRate);
        
        // 计算团队管理分佣
        BigDecimal teamRate = getTeamRate(performance.getTeamSales());
        BigDecimal teamCommission = order.getCommissionBase().multiply(teamRate);
        
        // 返回组合分佣
        List<CommissionDetail> details = new ArrayList<>();
        // ... 构建分佣详情
        return details;
    }
}
5.2 防作弊机制
代码语言:javascript
复制
@Service
public class AntiCheatService {
    
    /**
     * 分佣风控检查
     */
    public CommissionRiskCheckResult riskCheck(Order order, List<CommissionDetail> details) {
        CommissionRiskCheckResult result = new CommissionRiskCheckResult();
        
        // 1. 自买自卖检测
        if (isSelfTrading(order, details)) {
            result.setHighRisk(true);
            result.addRiskItem("自买自卖风险");
        }
        
        // 2. 异常关系链检测
        if (hasAbnormalRelationChain(order.getUserId())) {
            result.setHighRisk(true);
            result.addRiskItem("异常关系链");
        }
        
        // 3. 高频交易检测
        if (isHighFrequencyTrading(order.getUserId())) {
            result.setMediumRisk(true);
            result.addRiskItem("高频交易");
        }
        
        return result;
    }
    
    /**
     * 自买自卖检测
     */
    private boolean isSelfTrading(Order order, List<CommissionDetail> details) {
        for (CommissionDetail detail : details) {
            if (detail.getUserId().equals(order.getUserId())) {
                return true;
            }
        }
        return false;
    }
}

6. 性能优化方案

6.1 数据库优化
代码语言:javascript
复制
-- 添加合适的索引
CREATE INDEX idx_commission_user_status ON commission_records(user_id, status);
CREATE INDEX idx_relations_user_ancestor ON distribution_relations(user_id, ancestor_id);
CREATE INDEX idx_orders_user_created ON orders(user_id, created_at);

-- 分区表(按时间分区)
ALTER TABLE commission_records PARTITION BY RANGE (YEAR(created_at)) (
    PARTITION p2023 VALUES LESS THAN (2024),
    PARTITION p2024 VALUES LESS THAN (2025)
);
6.2 缓存策略
代码语言:javascript
复制
@Service
public class DistributionCacheService {
    
    @Autowired
    private RedisTemplate redisTemplate;
    
    private static final String RELATION_CACHE_KEY = "dist:relation:%s";
    private static final long RELATION_CACHE_TTL = 3600; // 1小时
    
    /**
     * 缓存用户关系链
     */
    public void cacheUserRelations(Long userId, List<DistributionRelation> relations) {
        String key = String.format(RELATION_CACHE_KEY, userId);
        redisTemplate.opsForValue().set(key, relations, RELATION_CACHE_TTL, TimeUnit.SECONDS);
    }
    
    /**
     * 从缓存获取关系链
     */
    public List<DistributionRelation> getCachedUserRelations(Long userId) {
        String key = String.format(RELATION_CACHE_KEY, userId);
        return (List<DistributionRelation>) redisTemplate.opsForValue().get(key);
    }
}

7. 总结

本文详细介绍了分销系统的整体架构设计、数据库模型、核心代码实现以及分佣规则设计。关键要点包括:

  1. 架构清晰:采用分层架构,模块化设计
  2. 关系管理:使用闭包表模式存储多级分销关系
  3. 规则灵活:支持多种分佣模式,可配置化
  4. 风控完善:内置防作弊机制,保障系统安全
  5. 性能优化:通过缓存、索引等手段提升系统性能

实际项目中还需要考虑分布式事务、数据一致性、系统监控等更多细节,但以上设计已经提供了一个坚实的分销系统基础框架。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-11-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 系统概述
  • 2. 系统架构设计
    • 2.1 整体架构
    • 2.2 核心服务模块
  • 3. 数据库设计
    • 3.1 核心表结构
      • 用户表 (users)
      • 分销关系表 (distribution_relations)
      • 订单表 (orders)
      • 分佣记录表 (commission_records)
      • 分佣规则表 (commission_rules)
  • 4. 核心代码实现
    • 4.1 分销关系管理
    • 4.2 分佣规则引擎
    • 4.3 分佣执行服务
  • 5. 分佣规则设计
    • 5.1 常见分佣模式
      • 5.1.1 固定比例模式
      • 5.1.2 阶梯比例模式
      • 5.1.3 团队业绩模式
    • 5.2 防作弊机制
  • 6. 性能优化方案
    • 6.1 数据库优化
    • 6.2 缓存策略
  • 7. 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档