|
@@ -4,12 +4,16 @@ const { BusinessError, ErrorCode } = require('naf-core').Error;
|
|
const _ = require('lodash');
|
|
const _ = require('lodash');
|
|
const assert = require('assert');
|
|
const assert = require('assert');
|
|
const { ObjectId } = require('mongoose').Types;
|
|
const { ObjectId } = require('mongoose').Types;
|
|
|
|
+const Transaction = require('mongoose-transactions');
|
|
//
|
|
//
|
|
class OrderDetailService extends CrudService {
|
|
class OrderDetailService extends CrudService {
|
|
constructor(ctx) {
|
|
constructor(ctx) {
|
|
super(ctx, 'orderdetail');
|
|
super(ctx, 'orderdetail');
|
|
this.model = this.ctx.model.Trade.OrderDetail;
|
|
this.model = this.ctx.model.Trade.OrderDetail;
|
|
this.orderModel = this.ctx.model.Trade.Order;
|
|
this.orderModel = this.ctx.model.Trade.Order;
|
|
|
|
+ this.goodsSpecModel = this.ctx.model.Shop.GoodsSpec;
|
|
|
|
+ this.userCouponModel = this.ctx.model.User.UserCoupon;
|
|
|
|
+ this.tran = new Transaction();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -79,6 +83,67 @@ class OrderDetailService extends CrudService {
|
|
const freight_total = goodsList.reduce((p, n) => this.ctx.plus(p, this.ctx.multiply(n.freight, n.buy_num)), 0);
|
|
const freight_total = goodsList.reduce((p, n) => this.ctx.plus(p, this.ctx.multiply(n.freight, n.buy_num)), 0);
|
|
return { goods_total, freight_total };
|
|
return { goods_total, freight_total };
|
|
}
|
|
}
|
|
|
|
+ /**
|
|
|
|
+ * 退拆分的订单
|
|
|
|
+ * @param {Object} param 地址参数
|
|
|
|
+ * @param param.id 数据id
|
|
|
|
+ */
|
|
|
|
+ async cancel({ id }) {
|
|
|
|
+ const orderDetail = await this.model.findById(id);
|
|
|
|
+ // 退库存,退券,退钱
|
|
|
|
+ const goods = _.get(orderDetail, 'goods', []);
|
|
|
|
+ // 计算退款金额
|
|
|
|
+ let total = goods.reduce((p, n) => {
|
|
|
|
+ const price = this.ctx.plus(n.sell_money, n.freight);
|
|
|
|
+ const total = this.ctx.multiply(n.buy_num, price);
|
|
|
|
+ return this.ctx.plus(p, total);
|
|
|
|
+ }, 0);
|
|
|
|
+ const dd = _.get(orderDetail, 'total_detail.discount_detail', {});
|
|
|
|
+ let discount = 0;
|
|
|
|
+ // 用户使用的优惠券id
|
|
|
|
+ const uc_ids = [];
|
|
|
|
+ for (const d in dd) {
|
|
|
|
+ uc_ids.push(d);
|
|
|
|
+ const detail = _.get(dd, d, {});
|
|
|
|
+ const dm = Object.values(detail).reduce((p, n) => this.ctx.plus(p, n), 0);
|
|
|
|
+ discount = this.ctx.plus(discount, dm);
|
|
|
|
+ }
|
|
|
|
+ total = this.ctx.minus(total, discount);
|
|
|
|
+ // 找到支付单号,
|
|
|
|
+ const order = await this.orderModel.findById(orderDetail.order);
|
|
|
|
+ if (!order) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到订单信息');
|
|
|
|
+ const pay_no = _.get(order, 'pay.pay_no');
|
|
|
|
+ if (!pay_no) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到支付单号');
|
|
|
|
+ try {
|
|
|
|
+ // 组成退款单号
|
|
|
|
+ const out_refund_no = `${pay_no}-r-all`;
|
|
|
|
+ const obj = { reason: '退单', money: total, order_no: pay_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);
|
|
|
|
+
|
|
|
|
+ // 退库存
|
|
|
|
+ for (const g of goods) {
|
|
|
|
+ const { _id, buy_num } = g;
|
|
|
|
+ const goodsSpec = await this.goodsSpecModel.findById(_id, { buy_num: 1 });
|
|
|
|
+ const newNum = this.ctx.plus(goodsSpec.num, buy_num);
|
|
|
|
+ this.tran.update('GoodsSpec', _id, newNum);
|
|
|
|
+ }
|
|
|
|
+ // 退优惠券
|
|
|
|
+ for (const uc_id of uc_ids) {
|
|
|
|
+ this.tran.update('UserCoupon', uc_id, { status: '0' });
|
|
|
|
+ }
|
|
|
|
+ // 修改订单信息
|
|
|
|
+ this.tran.update('OrderDetail', id, { status: '-1' });
|
|
|
|
+ await this.tran.run();
|
|
|
|
+ } catch (error) {
|
|
|
|
+ await this.tran.rollback();
|
|
|
|
+ console.error(error);
|
|
|
|
+ throw new BusinessError(ErrorCode.SERVICE_FAULT, '退单失败');
|
|
|
|
+ } finally {
|
|
|
|
+ this.tran.clean();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
async fetch(filter) {
|
|
async fetch(filter) {
|
|
assert(filter);
|
|
assert(filter);
|