lrf 2 yıl önce
ebeveyn
işleme
c22b709c97

+ 2 - 2
app/controller/shop/config/.goods.js

@@ -1,6 +1,6 @@
 module.exports = {
   create: {
-    requestBody: ['sort', 'source', 'url', 'act_tags', 'shop', 'name', 'shot_brief', 'send_time', 'brief', 'file', 'tags', 'status'],
+    requestBody: ['is_cashBack', 'cb_config', 'sort', 'source', 'url', 'act_tags', 'shop', 'name', 'shot_brief', 'send_time', 'brief', 'file', 'tags', 'status'],
   },
   destroy: {
     params: ['!id'],
@@ -8,7 +8,7 @@ module.exports = {
   },
   update: {
     params: ['!id'],
-    requestBody: ['sort', 'source', 'url', 'act_tags', 'shop', 'name', 'shot_brief', 'send_time', 'brief', 'file', 'tags', 'status'],
+    requestBody: ['is_cashBack', 'cb_config', 'sort', 'source', 'url', 'act_tags', 'shop', 'name', 'shot_brief', 'send_time', 'brief', 'file', 'tags', 'status'],
   },
   show: {
     parameters: {

+ 1 - 1
app/controller/trade/config/.order.js

@@ -1,6 +1,6 @@
 module.exports = {
   create: {
-    requestBody: ['type', 'group', 'customer', 'address', 'goods', 'total_detail', 'buy_time', 'pay', 'no', 'status', 'coupon'],
+    requestBody: ['inviter', 'type', 'group', 'customer', 'address', 'goods', 'total_detail', 'buy_time', 'pay', 'no', 'status', 'coupon'],
   },
   destroy: {
     params: ['!id'],

+ 13 - 0
app/controller/user/cashBack.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./config/.cashBack.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 
+class CashBackController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.user.cashBack;
+  }
+}
+module.exports = CrudController(CashBackController, meta);

+ 41 - 0
app/controller/user/config/.cashBack.js

@@ -0,0 +1,41 @@
+module.exports = {
+  create: {
+    requestBody: ['money', 'inviter', 'order', 'order_detail', 'time', 'status'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['money', 'inviter', 'order', 'order_detail', 'time', 'status'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+        inviter: 'inviter',
+        order: 'order',
+        order_detail: 'order_detail',
+        status: 'status',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 7 - 1
app/model/shop/goods.js

@@ -1,7 +1,10 @@
 'use strict';
 const Schema = require('mongoose').Schema;
 const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
-
+const cb_config = {
+  back_type: { type: String, zh: '返现金额类型' }, // 固定金额/百分比
+  money: { type: Number, zh: '具体返现金额设置' }, // 固定金额就是固定金额/ 百分比,需要与售价相乘转换为金额
+};
 // 商品信息
 const goods = {
   shop: { type: String, required: false, zh: '店铺', ref: 'Shop.Shop' }, //
@@ -18,6 +21,8 @@ const goods = {
   sort: { type: Number, required: false, default: 0, zh: '排序' }, //
   source: { type: String, required: false, zh: '来源' }, //
   url: { type: String, required: false, zh: '网址' }, //
+  is_cashBack: { type: String, required: false, zh: '是否返现' }, // 字典:use
+  cb_config: { type: Object, required: false, zh: '返现设置' }, // 返现设置
 };
 const schema = new Schema(goods, { toJSON: { getters: true, virtuals: true } });
 schema.index({ id: 1 });
@@ -28,6 +33,7 @@ schema.index({ status: 1 });
 schema.index({ view_num: 1 });
 schema.index({ act_tags: 1 });
 schema.index({ sort: 1 });
+schema.index({ is_cashBack: 1 });
 
 schema.plugin(metaPlugin);
 

+ 2 - 0
app/model/trade/order.js

@@ -18,6 +18,7 @@ const order = {
   pay: { type: Object, required: false, zh: '支付数据' }, // 有关支付时间,支付方式,支付订单号内容全都写在这里面
   type: { type: String, required: false, default: '0', zh: '订单类型' }, // 字典:order_type
   group: { type: String, required: false, zh: '所属团', ref: 'Group.Group' }, //
+  inviter: { type: String, required: false, zh: '推荐商品人', ref: 'User.User' }, // 返现部分
 };
 const schema = new Schema(order, { toJSON: { getters: true, virtuals: true } });
 schema.index({ id: 1 });
@@ -27,6 +28,7 @@ schema.index({ buy_time: 1 });
 schema.index({ no: 1 });
 schema.index({ type: 1 });
 schema.index({ group: 1 });
+schema.index({ inviter: 1 });
 
 schema.plugin(metaPlugin);
 

+ 2 - 0
app/model/trade/orderDetail.js

@@ -29,6 +29,7 @@ const orderDetail = {
   type: { type: String, required: false, default: '0', zh: '订单类型' }, // 字典:order_type
   group: { type: String, required: false, zh: '所属团', ref: 'Group.Group' }, //
   out_bill: { type: String, required: false, default: '1', zh: '是否出账' }, // 字典:tf
+  inviter: { type: String, required: false, zh: '推荐商品人', ref: 'User.User' }, // 返现部分
 };
 const schema = new Schema(orderDetail, { toJSON: { getters: true, virtuals: true } });
 schema.index({ id: 1 });
@@ -44,6 +45,7 @@ schema.index({ status: 1 });
 schema.index({ type: 1 });
 schema.index({ group: 1 });
 schema.index({ out_bill: 1 });
+schema.index({ inviter: 1 });
 
 schema.plugin(metaPlugin);
 

+ 27 - 0
app/model/user/cashBack.js

@@ -0,0 +1,27 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+
+const MoneyPlugin = require('naf-framework-mongoose-free/lib/model/type-money-plugin');
+
+// 返现记录表
+const cashBack = {
+  inviter: { type: String, required: false, zh: '推荐人', ref: 'User.User' }, //
+  order_detail: { type: String, required: false, zh: '订单', ref: 'Trade.OrderDetail' }, //
+  time: { type: String, required: false, zh: '返现时间' }, //
+  status: { type: String, required: false, default: '0', zh: '状态' }, // 字典:cashBack_status
+};
+const schema = new Schema(cashBack, { toJSON: { getters: true, virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.index({ inviter: 1 });
+schema.index({ order_detail: 1 });
+schema.index({ status: 1 });
+
+schema.plugin(metaPlugin);
+schema.plugin(MoneyPlugin({ zh: '返现金额', required: false, key: 'money' }));
+
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('CashBack', schema, 'cashBack');
+};

+ 6 - 2
app/service/trade/order.js

@@ -32,7 +32,7 @@ class OrderService extends CrudService {
       const user = this.ctx.user;
       const customer = _.get(user, '_id');
       if (!customer) throw new BusinessError(ErrorCode.NOT_LOGIN, '未找到用户信息');
-      const { address, goods, total_detail, coupon = [], type = '0', group } = body;
+      const { address, goods, total_detail, coupon = [], type = '0', group, inviter } = body;
       if (coupon.length > 1) throw new BusinessError(ErrorCode.DATA_INVALID, '目前只允许使用1张优惠券');
       // 检测商品是否可以下单
       for (const i of goods) {
@@ -95,6 +95,8 @@ class OrderService extends CrudService {
         orderData.group = group;
       }
       // #endregion
+      // 5.返现部分:邀请人
+      orderData.inviter = inviter;
 
       // 生成数据
       const order_id = this.tran.insert('Order', orderData);
@@ -227,9 +229,11 @@ class OrderService extends CrudService {
     pageData.goodsData = specsData;
     pageData.orderTotal = shopTotalDetail;
     // 优惠券列表
+    // 查询优惠券列表
     const couponList = await this.ctx.service.user.userCoupon.toMakeOrder_getList(specsData);
     pageData.couponList = couponList;
-    // 查询优惠券列表
+    // 返现部分:添加推荐人信息
+    pageData.inviter = _.get(data, 'inviter');
     return pageData;
   }
 

+ 26 - 10
app/service/trade/orderDetail.js

@@ -37,9 +37,10 @@ class OrderDetailService extends CrudService {
     assert(order_id, '缺少支付订单信息');
     const order = await this.orderModel.findById(order_id);
     if (!order) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到支付订单的数据');
-    const { customer, address, goods: shopGoods, no, status, buy_time, pay, total_detail: otd } = order;
+    // 返现部分
+    const { customer, address, goods: shopGoods, no, status, buy_time, pay, total_detail: otd, inviter } = order;
     if (status === '0') throw new BusinessError(ErrorCode.DATA_INVALID, '订单未支付');
-    const orderDetailData = { customer, address, order: order_id, buy_time, pay_time: _.get(pay, 'pay_time'), status };
+    const orderDetailData = { customer, address, order: order_id, buy_time, pay_time: _.get(pay, 'pay_time'), status, inviter };
     const shopMoneyDetail = this.ctx.service.util.order.shopMoneyDetail(order);
     // 分订单计数器
     let noTimes = 1;
@@ -81,14 +82,6 @@ class OrderDetailService extends CrudService {
     // await this.model.insertMany(arr);
   }
 
-  async afterUpdate(filter, body, data) {
-    const status = _.get(data, 'status');
-    if (status === '3') {
-      // 处理积分,签收再加
-      await this.ctx.service.user.point.addPoints(data._id);
-    }
-    return data;
-  }
 
   /**
    * 将商品规格列表中,优惠的部分提取出来,分单用
@@ -248,6 +241,29 @@ class OrderDetailService extends CrudService {
     return { data: list, total };
   }
 
+  async update(filter, update, { projection } = {}) {
+    assert(filter);
+    assert(update);
+    const { _id, id } = filter;
+    if (_id || id) filter = { _id: ObjectId(_id || id) };
+    const entity = await this.model.findOne(filter).exec();
+    if (!entity) throw new BusinessError(ErrorCode.DATA_NOT_EXIST);
+    try {
+      this.tran.update('OrderDetail', filter._id, update);
+      // 积分部分
+      await this.ctx.service.user.point.addPoints(filter._id, this.tran);
+      // 返现部分
+      await this.ctx.service.user.cashBack.create(filter._id, this.tran);
+      await this.tran.run();
+      const e = await this.model.findOne(filter, projection).exec();
+      return e;
+    } catch (error) {
+      await this.tran.rollback();
+
+    } finally {
+      this.tran.clean();
+    }
+  }
 }
 
 module.exports = OrderDetailService;

+ 31 - 0
app/service/user/cashBack.js

@@ -0,0 +1,31 @@
+'use strict';
+const { CrudService } = require('naf-framework-mongoose-free/lib/service');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const _ = require('lodash');
+const assert = require('assert');
+const moment = require('moment');
+//
+class CashBackService extends CrudService {
+  constructor(ctx) {
+    super(ctx, 'cashback');
+    this.model = this.ctx.model.User.CashBack;
+    this.orderDetailModel = this.ctx.model.Trade.OrderDetail;
+  }
+  /**
+   * 添加检查返现
+   * @param {String} orderDetail_id 订单详情id
+   * @param {Transaction} tran 数据库事务
+   */
+  async create(orderDetail_id, tran) {
+    const { populate } = this.ctx.service.trade.orderDetail.getRefMods();
+    const orderDetail = await this.orderDetailModel.findById(orderDetail_id).populate(populate);
+    if (!orderDetail) return;
+    const money = this.ctx.service.util.orderDetail.computedRealPay(orderDetail);
+    const { inviter, _id: order_detail } = orderDetail;
+    if (!inviter) return;
+    const obj = { inviter, order_detail, money, time: moment().format('YYYY-MM-DD HH:mm:ss') };
+    tran.insert('CashBack', obj);
+  }
+}
+
+module.exports = CashBackService;

+ 4 - 2
app/service/user/point.js

@@ -27,8 +27,9 @@ class PointService extends CrudService {
   /**
    * 添加积分;将处理添加至事务之中
    * @param {String} orderDetail_id 订单详情id
+   * @param {Transaction} tran 数据库事务
    */
-  async addPoints(orderDetail_id) {
+  async addPoints(orderDetail_id, tran) {
     const orderDetail = await this.orderDetailModel.findById(orderDetail_id);
     assert(orderDetail, '缺少订单信息');
     const realPay = this.ctx.service.util.orderDetail.computedRealPay(orderDetail);
@@ -42,7 +43,8 @@ class PointService extends CrudService {
     if (r) return;
     obj.point = point;
     obj.time = moment().format('YYYY-MM-DD HH:mm:ss');
-    await this.model.create(obj);
+    // await this.model.create(obj);
+    tran.insert('Point', obj);
   }
   // 检查是否已经添加过该来源的积分
   async checkHasAdd(query) {

+ 3 - 2
app/service/util/trade.js

@@ -50,9 +50,10 @@ class TradeService extends CrudService {
    * @param param.num 购买数量
    * @param param.type 订单类型: 0:常规单 1:团购单,需要按团购价计算
    * @param param.group 团id
+   * @param param.inviter 邀请用户id 返现部分
    * @param makeCache 生成缓存
    */
-  async checkCanBuy({ shop, goods, goodsSpec, num, type = '0', group }, makeCache = true) {
+  async checkCanBuy({ shop, goods, goodsSpec, num, type = '0', group, inviter }, makeCache = true) {
     assert(shop, '缺少店铺信息');
     assert(goods, '缺少商品信息');
     assert(goodsSpec, '缺少商品规格信息');
@@ -80,7 +81,7 @@ class TradeService extends CrudService {
     }
     // #endregion
     if (makeCache) {
-      const key = await this.makeOrderKey({ shop, goods, goodsSpec, num, type, group });
+      const key = await this.makeOrderKey({ shop, goods, goodsSpec, num, type, group, inviter });
       result.key = key;
     }
 

+ 1 - 1
config/config.default.js

@@ -35,7 +35,7 @@ module.exports = appInfo => {
   // 数据库设置
   config.dbName = 'point_shopping';
   config.mongoose = {
-    url: `mongodb://120.48.146.1:27017/${config.dbName}`, // 120.48.146.1 127.0.0.1
+    url: `mongodb://127.0.0.1:27017/${config.dbName}`, // 120.48.146.1 127.0.0.1
     options: {
       user: 'admin',
       pass: 'admin',