lrf 2 gadi atpakaļ
vecāks
revīzija
92ce4e9fb7

+ 3 - 0
app/controller/trade/config/.afterSale.js

@@ -44,4 +44,7 @@ module.exports = {
     requestBody: ['order_detail', 'goods_id'],
     service: 'computedGoodsForRefund',
   },
+  orderCancel: {
+    requestBody: ['order_detail', 'desc'],
+  },
 };

+ 3 - 2
app/controller/user/config/.point.js

@@ -1,6 +1,6 @@
 module.exports = {
   create: {
-    requestBody: ['customer', 'point', 'time', 'status', 'source'],
+    requestBody: ['customer', 'point', 'time', 'status', 'source', 'source_id'],
   },
   destroy: {
     params: ['!id'],
@@ -8,7 +8,7 @@ module.exports = {
   },
   update: {
     params: ['!id'],
-    requestBody: ['customer', 'point', 'time', 'status', 'source'],
+    requestBody: ['customer', 'point', 'time', 'status', 'source', 'source_id'],
   },
   show: {
     parameters: {
@@ -23,6 +23,7 @@ module.exports = {
         'meta.createdAt@end': 'meta.createdAt@end',
         customer: 'customer',
         status: 'status',
+        source_id: 'source_id',
       },
       // options: {
       //   "meta.state": 0 // 默认条件

+ 2 - 0
app/model/user/point.js

@@ -9,12 +9,14 @@ const point = {
   time: { type: String, required: false, zh: '时间' }, //
   status: { type: String, required: false, default: '0', zh: '状态' }, // 字典:point_status
   source: { type: String, required: false, zh: '来源' }, // 字典:point_source
+  source_id: { type: String, required: false, zh: '来源id' }, //
 };
 const schema = new Schema(point, { toJSON: { getters: true, virtuals: true } });
 schema.index({ id: 1 });
 schema.index({ 'meta.createdAt': 1 });
 schema.index({ customer: 1 });
 schema.index({ status: 1 });
+schema.index({ source_id: 1 });
 
 schema.plugin(metaPlugin);
 

+ 35 - 3
app/service/trade/afterSale.js

@@ -29,6 +29,7 @@ class AfterSaleService extends CrudService {
     const { shop, customer } = orderDetail;
     const apply_time = moment().format('YYYY-MM-DD HH:mm:ss');
     const obj = { order_detail, customer, shop, goods, ...others, apply_time, status: '0' };
+    console.log(obj);
     await this.model.create(obj);
   }
 
@@ -86,6 +87,7 @@ class AfterSaleService extends CrudService {
     const reason = _.get(data, 'desc');
     const order_no = _.get(orderDetail, 'order.pay.pay_no');
     if (!order_no) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到支付订单号');
+
     // 查查优惠中,是否有这个商品:将这个商品的每一个优惠券的优惠部分都加一起,然后用原价-优惠价=实付价
     const discount_detail = _.get(orderDetail, 'total_detail.discount_detail');
     if (discount_detail) {
@@ -115,9 +117,11 @@ class AfterSaleService extends CrudService {
     const out_refund_no = `${order_no}-r${num}`;
     const obj = { reason, money: refundMoney, order_no, out_refund_no };
     // 退款请求
-    const res = await this.ctx.service.trade.pay.refund(obj);
-    if (res.errcode && res.errcode !== 0) throw new BusinessError(ErrorCode.SERVICE_FAULT, res.errmsg);
-    tran.update('AfterSale', afterSale_id, { status: '-1' });
+    if (refundMoney > 0) {
+      const res = await this.ctx.service.trade.pay.refund(obj);
+      if (res.errcode && res.errcode !== 0) throw new BusinessError(ErrorCode.SERVICE_FAULT, res.errmsg);
+    }
+    if (data.status === '1') tran.update('AfterSale', afterSale_id, { status: '-1' });
     await tran.run();
 
     // 检查优惠券是否都退了
@@ -200,6 +204,34 @@ class AfterSaleService extends CrudService {
     const obj = { payTotal, goodsTotal, freightTotal, discountTotal };
     return obj;
   }
+  /**
+   * 退单
+   * @param {Object} body 参数体
+   * @param body.order_detail 订单详情id
+   * @param body.desc 退单理由
+   */
+  async orderCancel({ order_detail, desc }) {
+    // 查询要退的订单
+    const orderDetail = await this.orderDetailModel.findById(order_detail);
+    if (!orderDetail) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到订单信息');
+    const { goods, customer } = orderDetail;
+    const basic = { order_detail, customer, type: '1', desc };
+    const discount_detail = _.get(orderDetail, 'total_detail.discount_detail', {});
+    // 组织数据
+    for (const g of goods) {
+      let money = this.ctx.multiply(g.buy_num, g.sell_money);
+      let dmt = 0;
+      for (const dd in discount_detail) {
+        const detail = _.get(discount_detail, dd, {});
+        const dm = _.get(detail, g._id);
+        dmt = this.ctx.plus(dmt, dm);
+      }
+      money = this.ctx.minus(money, dmt);
+      if (money <= 0) money = 0;
+      const obj = { ...basic, goods_id: g._id, money };
+      await this.create(obj);
+    }
+  }
 
   async fetch(filter) {
     assert(filter);

+ 9 - 1
app/service/trade/orderDetail.js

@@ -25,7 +25,6 @@ class OrderDetailService extends CrudService {
     return res;
   }
 
-
   /**
    * 创建:用户支付完成后的订单
    * @param {Object} body 请求参数体
@@ -64,6 +63,15 @@ 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;
+  }
+
   /**
    * 将商品规格列表中,优惠的部分提取出来,分单用
    * @param {Array} goodsList 某店的商品列表

+ 21 - 28
app/service/user/point.js

@@ -9,39 +9,32 @@ class PointService extends CrudService {
   constructor(ctx) {
     super(ctx, 'point');
     this.model = this.ctx.model.User.Point;
-    this.orderModel = this.ctx.model.Trade.Order;
+    this.orderDetailModel = this.ctx.model.Trade.OrderDetail;
     this.userModel = this.ctx.model.User.User;
   }
   /**
    * 添加积分;将处理添加至事务之中
-   * @param {Object} params 参数
-   * @param params.order_id 订单id
-   * @param params.openid 支付人的openid
-   * @param {Transaction} tran 数据库事务实例
-   * @return
+   * @param {String} orderDetail_id 订单详情id
    */
-  async afterPayOrder({ order_id, openid }, tran) {
-    if (!tran) throw new BusinessError(ErrorCode.DATA_INVALID, '支付成功添加积分:缺少事务参数');
-    const orderData = await this.orderModel.findById(order_id);
-    if (!orderData) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '支付成功添加积分:未找到支付订单信息');
-    // 10块钱给1积分,不到10块不给
-    const pay_money = _.get(orderData, 'pay.pay_money');
-    if (!_.isNumber(pay_money) || pay_money < 10) return;
-    const point = _.floor(pay_money / 10);
-    // 添加积分
-    const user = await this.userModel.findOne({ openid });
-    if (!user) {
-      console.error('未找到用户信息----添加积分');
-      return;
-    }
-    const customer = _.get(user, '_id');
-    const pointData = {
-      customer,
-      point,
-      time: moment().format('YYYY-MM-DD HH:mm:ss'),
-      source: '0',
-    };
-    tran.insert('Point', pointData);
+  async addPoints(orderDetail_id) {
+    const orderDetail = await this.orderDetailModel.findById(orderDetail_id);
+    assert(orderDetail, '缺少订单信息');
+    const realPay = this.ctx.service.util.orderDetail.computedRealPay(orderDetail);
+    // 支付金额/10 为积分; TODO需要改成可设置的
+    const point = this.ctx.divide(realPay, 10);
+    const { customer, _id: source_id } = orderDetail;
+    const obj = { customer, source_id, source: 'OrderDetail' };
+    const r = await this.checkHasAdd(obj);
+    if (r) return;
+    obj.point = point;
+    obj.time = moment().format('YYYY-MM-DD HH:mm:ss');
+    await this.model.create(obj);
+  }
+  // 检查是否已经添加过该来源的积分
+  async checkHasAdd(query) {
+    const { customer, source_id, source } = query;
+    const num = await this.model.count({ customer, source_id, source });
+    return num > 0;
   }
 }
 

+ 1 - 2
app/service/user/storeShop.js

@@ -25,8 +25,7 @@ class StoreShopService extends CrudService {
     return { msg: '收藏成功', result: true };
   }
 
-  // 用户查看收藏店铺
-  async userView() {}
+
   // 检查是否收藏店铺
   async check({ shop, customer }) {
     const num = await this.model.count({ shop, customer });

+ 39 - 0
app/service/util/orderDetail.js

@@ -0,0 +1,39 @@
+'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');
+
+//
+class OrderDetailService extends CrudService {
+  constructor(ctx) {
+    super(ctx, 'orderdetail');
+  }
+  /**
+   * 计算订单详情实际支付金额
+   * @param {Object} data 订单详情数据
+   * @return {Number} 实际支付金额
+   */
+  async computedRealPay(data) {
+    const { goods = [], total_detail = {} } = data;
+    let total = goods.reduce((p, n) => {
+      const price = this.ctx.plus(n.sell_money, n.freight);
+      const goodsTotal = this.ctx.multiply(price, n.buy_num);
+      return this.ctx.plus(p, goodsTotal);
+    }, 0);
+    let dmt = 0;
+    const discount_detail = _.get(total_detail, 'discount_detail', {});
+    for (const uc_id in discount_detail) {
+      const detail = _.get(discount_detail, uc_id, {});
+      const values = Object.values(detail);
+      const dm = values.reduce((p, n) => this.ctx.plus(p, n), 0);
+      dmt = this.ctx.plus(dmt, dm);
+
+    }
+    total = this.ctx.minus(total, dmt);
+    if (total <= 0) total = 0;
+    return total;
+  }
+}
+
+module.exports = OrderDetailService;

+ 1 - 1
app/service/view/goods.js

@@ -78,9 +78,9 @@ class GoodsService extends CrudService {
     if (sell_money) pipline.push({ $sort: { sell_money } });
     // 分页处理
     const qPipline = _.cloneDeep(pipline);
+    qPipline.push({ $sort: { createdAt: -1 } });
     if (parseInt(skip)) qPipline.push({ $skip: parseInt(skip) });
     if (parseInt(limit)) qPipline.push({ $limit: parseInt(limit) });
-    qPipline.push({ $sort: { createdAt: -1 } });
     const list = await this.goodsModel.aggregate(qPipline);
     const tPipline = _.cloneDeep(pipline);
     tPipline.push({ $count: 'total' });

+ 1 - 0
app/z_router/trade/afterSale.js

@@ -7,6 +7,7 @@ const rkey = 'afterSale';
 const ckey = 'trade.afterSale';
 const keyZh = '售后';
 const routes = [
+  { method: 'post', path: `${rkey}/orderCancel`, controller: `${ckey}.orderCancel`, name: `${ckey}orderCancel`, zh: '取消订单' },
   { method: 'post', path: `${rkey}/cgfr`, controller: `${ckey}.cgfr`, name: `${ckey}cgfr`, zh: '查询退货商品的金额设置' },
   { method: 'get', path: `${rkey}`, controller: `${ckey}.index`, name: `${ckey}Query`, zh: `${keyZh}列表查询` },
   { method: 'get', path: `${rkey}/:id`, controller: `${ckey}.show`, name: `${ckey}Show`, zh: `${keyZh}查询` },