lrf402788946 4 年之前
父節點
當前提交
ff684ef1eb

+ 0 - 3
app/controller/.card.js

@@ -63,9 +63,6 @@ module.exports = {
         "create_time@start": "create_time@start",
         "create_time@end": "create_time@end",
       },
-      options: {
-        "meta.status": 0, // 默认条件
-      },
     },
     service: "query",
     options: {

+ 0 - 3
app/controller/.cash.js

@@ -41,9 +41,6 @@ module.exports = {
         "create_time@start": "create_time@start",
         "create_time@end": "create_time@end",
       },
-      options: {
-        "meta.status": 0, // 默认条件
-      },
     },
     service: "query",
     options: {

+ 38 - 0
app/controller/.record.js

@@ -0,0 +1,38 @@
+module.exports = {
+  create: {
+    requestBody: ["mobile", "name", "points", "opera", "remark"],
+  },
+  destory: {
+    params: ["!id"],
+    service: "delete",
+  },
+  update: {
+    params: ["!id"],
+    requestBody: ["mobile", "name", "points", "opera", "remark"],
+  },
+  show: {
+    parameters: {
+      params: ["!id"],
+    },
+    service: "fetch",
+  },
+  index: {
+    parameters: {
+      query: {
+        mobile: "mobile",
+        name: "%name%",
+        points: "points",
+        opera: "%opera%",
+        "create_time@start": "create_time@start",
+        "create_time@end": "create_time@end",
+      },
+    },
+    service: "query",
+    options: {
+      query: ["skip", "limit"],
+      sort: ["meta.createdAt"],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 13 - 0
app/controller/record.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.record.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose/lib/controller');
+
+// 积分记录
+class RecordController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.record;
+  }
+}
+module.exports = CrudController(RecordController, meta);

+ 16 - 0
app/controller/util.js

@@ -0,0 +1,16 @@
+'use strict';
+
+const Controller = require('egg').Controller;
+
+class UtilController extends Controller {
+  async index() {
+    const { ctx } = this;
+    ctx.body = 'hi, egg';
+  }
+  async utilMethod() {
+    await this.ctx.service.util.utilMethod(this.ctx.query, this.ctx.request.body);
+    this.ctx.ok({});
+  }
+}
+
+module.exports = UtilController;

+ 1 - 1
app/model/card.js

@@ -20,7 +20,7 @@ const card = {
   pay_type: { type: String }, // 支付方式
   name: { type: String, required: true }, // 姓名
   id_card: { type: String, required: true, lowercase: true }, // 身份证
-  level: { type: String, required: true, default: '1' }, // 等级
+  level: { type: Number, required: true, default: 1 }, // 等级
   points: { type: Number, default: 600 }, // 积分
   recommend: { type: String }, // 推荐人
   r_mobile: { type: String }, // 推荐人电话

+ 21 - 0
app/model/record.js

@@ -0,0 +1,21 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
+// 分数记录表
+const record = {
+  mobile: { type: String, required: true }, // 电话
+  name: { type: String, required: true }, // 姓名
+  points: { type: Number, default: 600 }, // 积分
+  opera: { type: String, required: true }, // 操作行为:推荐办卡/提现/车奖
+  params: { type: Object },
+  remark: { type: String, maxLength: 200 },
+  create_time: { type: String, default: moment().format('YYYY-MM-DD HH:mm:ss') },
+};
+const schema = new Schema(record, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Record', schema, 'record');
+};

+ 2 - 0
app/router.js

@@ -8,6 +8,8 @@ module.exports = app => {
   const prefix = '/api/htyd';
   router.get('/', controller.home.index);
   router.post(`${prefix}/login`, controller.login.login);
+  router.post(`${prefix}/util`, controller.util.utilMethod);
   require('./router/card')(app); // 办卡
   require('./router/cash')(app); // 提现
+  require('./router/record')(app); // 记录
 };

+ 11 - 0
app/router/record.js

@@ -0,0 +1,11 @@
+'use strict';
+/**
+ * @param {Egg.Application} app - egg application
+ */
+module.exports = app => {
+  const prefix = '/api/htyd';
+  const index = 'record';
+  const { router, controller } = app;
+  router.resources(index, `${prefix}/${index}`, controller[index]); // index、create、show、destroy
+  router.post(index, `${prefix}/${index}/update/:id`, controller[index].update);
+};

+ 3 - 3
app/schedule/carshow.js

@@ -7,15 +7,15 @@ class CheckCheck extends Subscription {
   // 更改执行时间
   static get schedule() {
     return {
-      cron: '0 0 0 * * *',
-      // interval: '1d',
+      // cron: '0 0 0 * * *',
+      interval: '30s',
       type: 'worker', // 指定所有的 worker 都需要执行
     };
   }
 
   // subscribe 是真正定时任务执行时被运行的函数
   async subscribe() {
-    // await this.ctx.service.system.schedule.check();
+    await this.ctx.service.card.checkCarshow();
   }
 }
 module.exports = CheckCheck;

+ 68 - 44
app/service/card.js

@@ -16,18 +16,35 @@ class CardService extends CrudService {
   constructor(ctx) {
     super(ctx, 'card');
     this.model = this.ctx.model.Card;
+    this.record = this.ctx.model.Record;
     /**
-     * @constant Number 车奖的积分
+     * @constant Number 车奖的积分 default:131400
      */
     this.car_point = 131400;
     /**
-     * @constant Number 股东的积分
+     * @constant Number 股东的积分 default:10
      */
     this.stockholder_point = 10;
     /**
-     * @constant Number 股东的单数界限,前xxxx单不是股东
+     * @constant Number 股东的单数界限,前xxxx单不是股东 default: 9999
      */
-    this.stockholder_limit = 9999;
+    this.stockholder_limit = 20;
+    /**
+     * @constant Number 股东的等级界限,前x级不是股东 default:6
+     */
+    this.stockholder_limit_level = 6;
+    /**
+     * @constant Number 车奖的等级界限,前x级不是能获得车奖 default:4
+     */
+    this.car_show_limit_level = 4;
+    /**
+     * @constant Number 车奖的B梯队等级界限 default:4
+     */
+    this.car_show_b_limit_level = 4;
+    /**
+     * @constant Number 车奖的B梯队等级界限的人数 default:5
+     */
+    this.car_show_b_limit_person = 5;
   }
   /**
    * 修改密码
@@ -54,7 +71,9 @@ class CardService extends CrudService {
     try {
       data.password = { secret: password };
       user = await this.model.create(data);
+      user = _.omit(user, [ 'password' ]);
     } catch (e) {
+      this.ctx.logger.error(e);
       throw new BusinessError(
         ErrorCode.SERVICE_FAULT,
         '输入信息有误,用户创建失败!'
@@ -72,21 +91,22 @@ class CardService extends CrudService {
     }
     // 4,判断是129套餐,还是169套餐,如果是129套餐,那就不需要继续了
     if (set === '129') return user;
-    // 5,接下来,查看推荐人下已经有了多少人
-    const a_recer = await this.model.count(r_mobile);
     // 根据等级,找下推荐人应该加多少分
-    const { level, car_show, stockholder } = a_recer;
-    const rank = this.getRank().find(f => `${f.rank}` === `${level}`);
+    const { stockholder } = recommender;
+    // 重新计算推荐人用户等级
+    const nlevel = await this.reComputedLevel(recommender);
+    recommender.level = nlevel;
+    const rank = this.getRank().find(f => f.rank === nlevel);
     if (!rank) {
       // TODO 告知推荐人,等级信息有错误,中断,返回用户添加成功
       return user;
     }
     let { score } = rank;
-    // TODO,需要检查股东奖,是否需要+10
+    // 需要检查股东奖,是否需要+10
     if (stockholder) score = score + this.stockholder_point;
     else {
-      // TODO 去写检查是不是股东的问题
-      const result = await this.checkStockholder(a_recer);
+      // 去写检查是不是股东的问题
+      const result = await this.checkStockholder(recommender);
       if (result === undefined) {
         // TODO 告知推荐人,股东检测有错误,中断,返回用户添加成功
         return user;
@@ -94,31 +114,22 @@ class CardService extends CrudService {
       // 这次加上这个用户就是股东了
       if (result) {
         // 此情况主要讨论的是 9999 单时,是否加=>9999单时,不加
-        a_recer.stockholder = true;
+        recommender.stockholder = true;
         score = score + 10;
       }
     }
     // 加积分
-    a_recer.points = a_recer.points + score;
-    // 重新计算推荐人用户等级
-    const nlevel = await this.reComputedLevel(a_recer);
-    a_recer.level = nlevel;
-    await a_recer.save();
-    // TODO 添加分数记录,这次推荐人加了多少分
-    // // 检测车奖 这个应该做定时任务,1天/小时 检查1/2次,不应该放在这里,和股东的性质不一样,只要给了就行
-    // // 1,先看看车奖得没得,得了就可以返回了,都处理完了
-    // if (!car_show) {
-    //   const result = await this.checkCarshow(a_recer);
-    //   if (result === undefined) {
-    //     // TODO 告知推荐人,车奖检测有错误,中断,返回用户添加成功
-    //     return user;
-    //   }
-    //   // 这次满足车奖了
-    //   if (result) {
-    //     a_recer.car_show = true;
-    //     a_recer.points = a_recer.points + this.car_point;
-    //   }
-    // }
+    recommender.points = `${recommender.points + score}`;
+    await recommender.save();
+    const record = _.pick(recommender, [ 'mobile', 'name' ]);
+    record.points = score;
+    record.opera = '推荐办卡';
+    record.params = { name: user.name, mobile: user.mobile };
+    try {
+      await this.record.create(record);
+    } catch (error) {
+      this.logger.error(`积分记录添加失败${JSON.stringify(record)}`);
+    }
     return user;
   }
   /**
@@ -127,7 +138,7 @@ class CardService extends CrudService {
    * @property r_number A推出去的人数 B级总数
    * @property b_r_number B级推出去的人数 C级总数
    * @property group_number 团队完成单数: r_number + b_r_number
-   * @return {String} level 等级
+   * @return {Number} level 等级
    */
   async reComputedLevel(user) {
     const result = await this.getEchelon(user);
@@ -146,12 +157,12 @@ class CardService extends CrudService {
     const rank = ranks.find(f => {
       const { n_rank, n_r_person } = f;
       // 查找B梯队里,满足当前阶级要求的 B梯队职位 的人数
-      const list = b.filter(bl => `${bl.level}` === `${n_rank}`);
+      const list = b.filter(bl => bl.level === n_rank);
       // 如果人数也满足要求,推荐人就应该是这个阶级了,反之继续找
       return list >= n_r_person;
     });
-    if (rank) return `${rank.rank}`;
-    return `${user.level}`;
+    if (rank) return rank.rank;
+    return user.level;
   }
 
   /**
@@ -161,7 +172,7 @@ class CardService extends CrudService {
   async checkStockholder(user) {
     try {
       const level = _.get(user, 'level', 1) * 1;
-      if (level < 6) return false;
+      if (level < this.stockholder_limit_level) return false;
       const result = await this.getEchelon(user);
       if (!result) return;
       const { b = [], c = 0 } = result;
@@ -175,16 +186,29 @@ class CardService extends CrudService {
 
   /**
    * 检查该用户是否满足车奖
-   * @param {Object} user 用户
    */
-  async checkCarshow(user) {
+  async checkCarshow() {
+    const list = await this.model.find({ level: { $gte: this.car_show_limit_level }, car_show: false });
     try {
-      const level = _.get(user, 'level', 1) * 1;
-      if (level < 4) return false;
-      const b = await this.model.count({ r_mobile: user.mobile, level: 4 });
-      return b >= 5;
+      for (const user of list) {
+        const b = await this.model.count({ r_mobile: user.mobile, level: { $gte: this.car_show_b_limit_level } });
+        if (b >= this.car_show_b_limit_person) {
+          user.car_show = true;
+          user.points = user.points + this.car_point;
+          await user.save();
+          // TODO 添加积分记录
+          const record = _.pick(user, [ 'mobile', 'name' ]);
+          record.points = this.car_point;
+          record.opera = '车奖';
+          try {
+            await this.record.create(record);
+          } catch (error) {
+            this.logger.error(`积分记录添加失败${JSON.stringify(record)}`);
+          }
+        }
+      }
     } catch (error) {
-      this.ctx.logger.error(`${moment().format('YYYY-MM-DD HH:mm:ss')}-${user.name}-${user.mobile}:车奖检查出错`);
+      this.ctx.logger.error(`${moment().format('YYYY-MM-DD HH:mm:ss')}-车奖检查出错`);
       return undefined;
     }
 

+ 30 - 0
app/service/cash.js

@@ -1,11 +1,41 @@
 'use strict';
 const { CrudService } = require('naf-framework-mongoose/lib/service');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const _ = require('lodash');
 
 // 提现
 class CashService extends CrudService {
   constructor(ctx) {
     super(ctx, 'cash');
     this.model = this.ctx.model.Cash;
+    this.record = this.ctx.model.Record;
+    this.card = this.ctx.model.Card;
+    this.charge = 0.06; // 6%
+  }
+
+  async create(data) {
+    const { b_point, i_point, e_point, mobile } = data;
+    const user = await this.card.findOne({ mobile });
+    if (!user) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '为找到提现的用户信息');
+    if (!b_point) data.b_point = user.points; // 手动赋值
+    if (e_point || e_point === 0) {
+      // 说明存在剩余积分,直接用
+      user.points = e_point;
+    } else {
+      user.points = user.points - (i_point + _.ceil(i_point * 0.06));
+      data.e_point = user.points;
+    }
+    await this.model.create(data);
+    await user.save();
+    const record = _.pick(user, [ 'mobile', 'name' ]);
+    record.points = -i_point;
+    record.opera = '提现';
+    record.params = { charge: -_.ceil(i_point * 0.06) };
+    try {
+      await this.record.create(record);
+    } catch (error) {
+      this.logger.error(`积分记录添加失败${JSON.stringify(record)}`);
+    }
   }
 }
 

+ 12 - 0
app/service/record.js

@@ -0,0 +1,12 @@
+'use strict';
+const { CrudService } = require('naf-framework-mongoose/lib/service');
+
+// 积分记录
+class RecordService extends CrudService {
+  constructor(ctx) {
+    super(ctx, 'record');
+    this.model = this.ctx.model.Record;
+  }
+}
+
+module.exports = RecordService;

+ 60 - 0
app/service/util.js

@@ -0,0 +1,60 @@
+'use strict';
+const { CrudService } = require('naf-framework-mongoose/lib/service');
+const moment = require('moment');
+
+// 工具
+class UtilService extends CrudService {
+  constructor(ctx) {
+    super(ctx);
+    this.model = this.ctx.model.Card;
+  }
+  async utilMethod(query, body) {
+    this.seed();
+  }
+
+  async seed() {
+    // b梯队
+    const b = [];
+    for (let i = 1; i <= 5; i++) {
+      const mobile = i < 10 ? `2222222220${i}` : `222222222${i}`;
+      const data = {
+        mobile,
+        password: '111111',
+        province: '220000',
+        city: '220100',
+        set: '168',
+        name: `B梯队${i}`,
+        id_card: '22010319950601161x',
+        recommend: '刘睿峰',
+        r_mobile: '13089419810',
+      };
+      b.push(data);
+      await this.ctx.service.card.create(data);
+    }
+    // c梯队
+    const c = [];
+    let num = 1;
+    for (const binfo of b) {
+      const { name, mobile } = binfo;
+      for (let i = num; i < num + 5; i++) {
+        const m = i < 10 ? `3333333330${i}` : `333333333${i}`;
+        const data = {
+          mobile: m,
+          password: '111111',
+          province: '220000',
+          city: '220100',
+          set: '168',
+          id_card: '22010319950601161x',
+          name: `C梯队${i}`,
+          recommend: name,
+          r_mobile: mobile,
+        };
+        c.push(data);
+        await this.ctx.service.card.create(data);
+      }
+      num = num + 5;
+    }
+  }
+}
+
+module.exports = UtilService;