一个高效率的多级分销系统后端设计

后台开发过程中经常遇到多级分销的问题,要求邀请的下线消费进行返佣,本文介绍一下我用nosql实现的方案,欢迎大家提出宝贵意见

首先,我们来探讨一下分销系统常见的需求

常见的功能如下:

  • 等级
    所有参与者都可以成为代理商,即系统满足无限级分销;
    分销商只能获取三级分销所得的佣金,超过三级的部分不能获得佣金。
  • 权限
    上级代理可以查看下级代理,以及下级代理的所有下级代理的订单;
    下级代理不能查看上级代理的订单;
    同级不能查看对方以及他的下线订单
  • 返佣
    A->B->C->D->E->F->客户小明
    如上分销体系中,客户小明从分销商F那里购买了商品,那么F获得一级佣金,E获得二级佣金,D获得三级佣金,D前面的分销商C,B,A就与此没有关系,也无法获得佣金。
    一级佣金比例是5%,二级是3%,三级的是2%

题外话

分销一般分为三级,分销商超过三级是犯法的。

2010年5月7日,《最高人民检察院、公安部关于公安机关管辖的刑事案件立案追诉标准的规定(二)》发布,其在第七十八条中规定 “涉嫌组织、领导的传销活动人员在三十人以上且层级在三级以上的,对组织者、领导者,应予立案追诉”。

数据库存储设计

使用nosql数据库;以redis为例,实际开发过程中,可以同样使用支持hash表结构和k-v结构存储的nosql数据引擎,如ssdb,mongodb等。

  • 下级的存储,使用hash表存储第一级经销商;
h_down_agency_${代理商ID} {
    下线1_ID: 成为下线时间,
    下线2_ID: 成为下线时间,
    ......
}
  • 上级代理商的存储,使用k-v保存所有上级代理商;
k_up_agency 代理商ID 上级代理商ID

功能实现

加入分销

  • B输入A的邀请码,B成为A的下级
  • 同时A成为B的上级

代码实现:

async function joinAgency(clientId, agencyId){
    await redis.HSETAsync('h_down_agency_'+agencyId, clientId, Date.now())
    await redis.SETAsync('k_up_agency', clientId, agencyId)
}

获取下级

使用遍历的方式获取多级下层代理商

代码实现:

agency.getThreeFloorDownAgency = async function (id) {
    async function getOneFloorDownAgency(ids) {
        let result = []
        if (typeof ids === 'string') {
            ids = [ids]
        }
        if (ids.length == 0) {
            return result
        } else if (ids.length == 1) {
            let results = await redisClient.HGETALLAsync('h_down_agency_' + ids[0])
            for (let id in results) {
                result.push(id)
            }
            return result
        } else {
            for (let id of ids) {
                let results = await redisClient.HGETALLAsync('h_down_agency_' + id)
                for (let id in results) {
                    result.push(id)
                }
            }
            return result
        }
    }

    let oneFloorAgencies = await getOneFloorDownAgency(id)
    let twoFloorAgencies = await getOneFloorDownAgency(oneFloorAgencies)
    let threeFloorAgencies = await getOneFloorDownAgency(twoFloorAgencies)
    return [oneFloorAgencies, twoFloorAgencies, threeFloorAgencies]
}

获取上级

遍历获取多级上层代理商

代码实现:

agency.getThreeFloorUpAgency = async function (id) {
    async function getOneFloorUpAgency(id) {
        return await redisClient.GETAsync('k_up_agency_' + id)
    }

    let result = []
    while (result.length < 3) {
        let item = await getOneFloorUpAgency(id)
        if (!item) {
            break
        }
        result.push(item)
        id = item
    }
    return result
}

具体实现参见代码地址

你可能感兴趣的:(一个高效率的多级分销系统后端设计)