三级分销商城系统开发实例 (三级分销开发文档)

么是三级分销系统?

假设A推荐B,B推荐C,C再推荐D,D购买了C所分享的产品之后,C能获得分佣的同时,A和B也能获得,这个就是三级分销的分佣方式,自订单产生人开始往上推三层关系人获得分佣。

常见的电商三级分销系统产品设计场景:

1:小A想参加活动,需要先注册成为会员,然后获取一个分享的商品页码或活动页码。  2:小A再通过社交媒体(朋友圈、微博等)把页面分享出去。  3:小B通过A分享的页码,注册成功。小B成为小A的下线 。

电商三级分销系统的设计重点:

小A分享的活动页面的url ,需要包含分享者的标识

如:https://localhost//register?token=xxxx,xxxx 为分享者id。

小A分享注册页面可能为https://localhost//register?token=a_id.小B进入小A的分享页面,注册时提交注册表单需要将分享者ID(a_id)提交到后台。

这时后台可以确认小B的上级是某个id。

在三级分销的用户表设计时,数据库中用户信息表只要增加一栏记录上级ID即可。

再来看第二点:分配利润

首先可对每个商品设计一个佣金的比例。

在一个商品完成支付以后, 按照如下流程来做:

1:通过注册表格, 找出购买者的3个上家ID.

2:通过支付的价格,分别算出3个上家获得的利润。

3:打钱给3个上家。(有可能直接支付,有可能按月支付等等,看商家的规则)

系统设计

一、数据库设计:

基本功能需要依赖于:用户表 、商品表、订单表、钱包表 所以需要在

用户表:

// app/model/User.js  
'use strict';

module.exports = app => {
  const { STRING, INTEGER, DATE } = app.Sequelize;
  const User = app.model.define('users', {
    id: { type: INTEGER, primaryKey: true, autoIncrement: true },
    name: STRING(30), // 用户名
    pwd: STRING(30), // 密码
    pid: INTEGER, // 父级id
  });
  return User;
};

商品表:

// app/model/Goods.js 
'use strict';

module.exports = app => {
  const { STRING, INTEGER, DATE } = app.Sequelize;
  const Goods = app.model.define('goods', {
    id: { type: INTEGER, primaryKey: true, autoIncrement: true },
    name: STRING(30), // 商品名称
    img: STRING, // 商品图片
    describe: STRING, // 商品内容
    price: INTEGER, // 商品价格
    gain: INTEGER, // 佣金 按商品价格百分比
  });
  return Goods;
};

订单表:

// app/model/Order.js 
'use strict';

module.exports = app => {
  const { INTEGER, DATE, TINYINT, DECIMAL } = app.Sequelize;
  const Order = app.model.define('orders', {
    id: { type: INTEGER, primaryKey: true, autoIncrement: true },
    user_id: INTEGER, // 用户id
    goods_id: INTEGER, // 商品id
    status:TINYINT, // 订单状态
  });
  return Order;
};

钱包表:

// app/model/Bill.js 
'use strict';

module.exports = app => {
  const { DECIMAL, INTEGER, STRING, DATE } = app.Sequelize;
  const Bill = app.model.define('bills', {
    id: { type: INTEGER, primaryKey: true, autoIncrement: true },
    balance:DECIMAL(10, 2), // 账户余额
    price:STRING, // 变动的价格
    user_id: INTEGER, //用户id
    bz: STRING, // 备注信息
  });
  return Bill;
};

二、编写controller层:

// app/controller/users.js
const Controller = require('egg').Controller;

function toInt(str) {
  if (typeof str === 'number') return str;
  if (!str) return str;
  return parseInt(str, 10) || 0;
}

class UserController extends Controller {
  // 创建新用户
  async create() {
    const ctx = this.ctx;
    const { token } = ctx.query;
    const { name, age, pwd, id } = ctx.request.body;
    const obj = { name, age, pwd, id };
    
    // 判断是否有标识 此标识token是用户的上级id,填写在新用户的pid上
    if (token) {
      obj.pid = token;
    }
    const user = await ctx.model.User.create(obj);

    // 给用户分配余额
    await ctx.model.Bill.create({ user_id: user.id });

    ctx.status = 201;
    ctx.body = user;
  }

}

module.exports = UserController;

// app/controller/goods.js
const Controller = require('egg').Controller;

function toInt(str) {
  if (typeof str === 'number') return str;
  if (!str) return str;
  return parseInt(str, 10) || 0;
}

class GoodsController extends Controller {
  // 创建商品
  async create() {
    const ctx = this.ctx;
    const { name, describe, price, id, gain, img } = ctx.request.body;
    const obj = { name, describe, price, id, gain, img };
    const Goods = await ctx.model.Goods.create(obj);
    ctx.status = 201;
    ctx.body = Goods;
  }
}

module.exports = GoodsController;

// app/controller/order.js
const Controller = require('egg').Controller;

function toInt(str) {
  if (typeof str === 'number') return str;
  if (!str) return str;
  return parseInt(str, 10) || 0;
}

class OrderController extends Controller {
  // 创建订单
  async create() {
    const ctx = this.ctx;
    const { user_id, goods_id, total } = ctx.request.body;
    const obj = { user_id, goods_id, total };
		// 创建好订单后 
    const Order = await ctx.model.Order.create(obj);


    // 1.商品完成购买后,系统通过注册表找出购买者的3个上级ID
    const User = await ctx.model.User.findByPk(toInt(user_id));
    if (!User.pid) return;
    const UserList = await ctx.helper.seekPid(User.pid, 3);//该方法在工具类app/extend/helper.js
    console.log(UserList);

    // 2.通过支付的价格,分别算出3个上家获得的利润。
    const Goods = await ctx.model.Goods.findByPk(toInt(goods_id));
    const { gain, price } = Goods;
    // 通过支付商品的价格来获取商品的总佣金 100 * 10 / 100 = 10
    const commission = (price * gain / 100);

    // 3 分别算出3个上家获得的利润。分配利润判断有几级分销人 按照分销人来分配佣金
    if (UserList.length === 1) {
      console.log('如果上级只有一个人则按佣金按照 100% 分');
      const Bill = await ctx.model.Bill.findOne({ where: { user_id: UserList[0] } });
      await ctx.model.Bill.update({
        balance: Number(Bill.balance) + commission,
        price: '+' + commission,
      }, { where: { user_id: Bill.user_id } });

    } else if (UserList.length === 2) {
      console.log('如果上级有两个人则按佣金按照 30% 70% 分');
      const Bill1 = await ctx.model.Bill.findOne({ where: { user_id: UserList[0] } });
      await ctx.model.Bill.update({
        balance: Number(Bill1.balance) + commission * 70 / 100,
        price: '+' + commission * 70 / 100,
      }, { where: { user_id: Bill1.user_id } });

      const Bill2 = await ctx.model.Bill.findOne({ where: { user_id: UserList[1] } });
      await ctx.model.Bill.update({
        balance: Number(Bill2.balance) + commission * 30 / 100,
        price: '+' + commission * 30 / 100,
      }, { where: { user_id: Bill2.user_id } });

    } else {
      console.log('如果上级有三个人则按佣金按照 20% 30% 50% 分');
      const Bill1 = await ctx.model.Bill.findOne({ where: { user_id: UserList[0] } });
      await ctx.model.Bill.update({
        balance: Number(Bill1.balance) + commission * 50 / 100,
        price: '+' + commission * 50 / 100,
      }, { where: { user_id: Bill1.user_id } });

      const Bill2 = await ctx.model.Bill.findOne({ where: { user_id: UserList[1] } });
      await ctx.model.Bill.update({
        balance: Number(Bill2.balance) + commission * 30 / 100,
        price: '+' + commission * 30 / 100,
      }, { where: { user_id: Bill2.user_id } });

      const Bill3 = await ctx.model.Bill.findOne({ where: { user_id: UserList[2] } });
      await ctx.model.Bill.update({
        balance: Number(Bill3.balance) + commission * 20 / 100,
        price: '+' + commission * 20 / 100,
      }, { where: { user_id: Bill3.user_id } });
    }
    ctx.status = 201;
    ctx.body = Order;

  }
}

module.exports = OrderController;

三、编写工具类:

因为 app/controller/order.js 中的 create 使用该方法

// app/extend/helper.js
'use strict';

module.exports = {

  /**
   *查找用户的pid
   * @param {number} pid 用户父id
   * @param {number} num 查找几个人
   * @return [] 查找到的人数
   */
  async seekPid(pid, num) {
    const { ctx } = this;
    const userList = [];
    await seek(pid, num);
    return userList;

    async function seek(pid, num) {
      if (userList.length >= num) return userList;
      const User = await ctx.model.User.findByPk(pid);
      if (!User.pid) return userList.push(User.id);
      userList.push(User.id);
      await seek(User.pid, num);
    }
  },
};

四、编写路由:

// app/router.js
'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
  router.post('/users', controller.users.create); // 创建用户
  router.post('/goods', controller.goods.create); // 创建商品
  router.post('/order', controller.goods.order); // 创建订单
};

五、接口说明:

新增用户接口:

请求类型:POST 请求路径:/users 类型:x-www-form-urlencoded

query 请求参数 :

参数名

类型

必填

示例值

说明

token

number

10086

用户的pid上级id 推广者的标识

body 请求参数 :

参数名

类型

必填

示例值

说明

name

string

zhangsan

用户名

pwd

string

123456

密码

新增商品接口:

请求类型:POST 请求路径:/goods 类型:x-www-form-urlencoded

body 请求参数 :

参数名

类型

必填

示例值

说明

name

string

小米手机

商品名称

img

string

img.png

图片

describe

string

小米手机

商品描述

price

number

100

商品价格

gain

number

10

商品佣金 按总价的百分比设置

创建订单接口:

请求类型:POST 请求路径:/order 类型:x-www-form-urlencoded

body 请求参数 :

参数名

类型

必填

示例值

说明

user_id

number

10086

用户id

goods_id

number

241

商品ID

Gitee仓库地址:fenxiao: 使用Egg.js搭建的三级分销系统