|
@@ -3,12 +3,101 @@ const { CrudService } = require('naf-framework-mongoose-free/lib/service');
|
|
|
const { BusinessError, ErrorCode } = require('naf-core').Error;
|
|
|
const _ = require('lodash');
|
|
|
const assert = require('assert');
|
|
|
+const { ObjectId } = require('mongoose').Types;
|
|
|
+const moment = require('moment');
|
|
|
+const Transaction = require('mongoose-transactions');
|
|
|
|
|
|
-//
|
|
|
+//
|
|
|
class AfterSaleService extends CrudService {
|
|
|
constructor(ctx) {
|
|
|
super(ctx, 'aftersale');
|
|
|
this.model = this.ctx.model.Trade.AfterSale;
|
|
|
+ this.orderDetailModel = this.ctx.model.Trade.OrderDetail;
|
|
|
+ this.tran = new Transaction();
|
|
|
+ }
|
|
|
+ async create({ order_id, goods_id, ...others }) {
|
|
|
+ const orderDetail = await this.orderDetailModel.findById(order_id);
|
|
|
+ if (!orderDetail) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到订单信息');
|
|
|
+ // 查询该商品是不是申请退款,如果是申请退款,查看是否有记录,如果有记录,是否已经退款
|
|
|
+ const type = _.get(others, 'type');
|
|
|
+ if (type === '0') {
|
|
|
+ const record = await this.model.find({ order_detail: order_id, 'goods._id': goods_id, type: '0' });
|
|
|
+ if (record) {
|
|
|
+ const rs = _.get(record, 'status');
|
|
|
+ if (rs === '0' || rs === '1') throw new BusinessError(ErrorCode.DATA_EXISTED, '已申请退款,正在等待处理');
|
|
|
+ else if (rs === '-1') throw new BusinessError(ErrorCode.DATA_EXISTED, '该商品已退款');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const { goods: goodsList } = orderDetail;
|
|
|
+ const goods = goodsList.find(f => ObjectId(f._id).equals(goods_id));
|
|
|
+ if (!goods) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未在当前订单中搜索到要售后的商品');
|
|
|
+ const { shop, customer } = orderDetail;
|
|
|
+ const apply_time = moment().format('YYYY-MM-DD HH:mm:ss');
|
|
|
+ const obj = { order_detail: order_id, customer, shop, goods, ...others, apply_time, status: '0' };
|
|
|
+ await this.model.create(obj);
|
|
|
+ }
|
|
|
+
|
|
|
+ async update(filter, update, { projection } = {}) {
|
|
|
+ assert(filter);
|
|
|
+ assert(update);
|
|
|
+ const beforeUpdateResult = await this.beforeUpdate(filter, update);
|
|
|
+ filter = beforeUpdateResult.filter;
|
|
|
+ update = beforeUpdateResult.update;
|
|
|
+ const { _id, id } = filter;
|
|
|
+ if (_id || id) filter = { _id: ObjectId(_id || id) };
|
|
|
+ // TODO:检查数据是否存在
|
|
|
+ const entity = await this.model.findOne(filter).exec();
|
|
|
+ if (!entity) throw new BusinessError(ErrorCode.DATA_NOT_EXIST);
|
|
|
+
|
|
|
+ // TODO: 修改数据
|
|
|
+ try {
|
|
|
+ this.tran.update('AfterSale', entity._id, update);
|
|
|
+ await this.tran.run();
|
|
|
+ const type = _.get(update, 'type');
|
|
|
+ const status = _.get(update, 'status');
|
|
|
+ // 同意退款,则直接进行退款,然后再将状态修改为已退款
|
|
|
+ if (type === '0' && status === '1') {
|
|
|
+ await this.toRefund({ afterSale_id: entity._id, goods_id: _.get(entity, 'goods._id') }, this.tran);
|
|
|
+ this.tran.update('AfterSale', entity._id, { status: '-1' });
|
|
|
+ }
|
|
|
+ await this.tran.run();
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ await this.tran.rollback();
|
|
|
+ throw new BusinessError(ErrorCode.SERVICE_FAULT, '售后:修改失败');
|
|
|
+ }
|
|
|
+ const reSearchData = await this.model.findOne(filter, projection).exec();
|
|
|
+ return reSearchData;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 退款
|
|
|
+ * @param {Object} param 参数
|
|
|
+ * @param param.afterSale_id 售后申请id
|
|
|
+ * @param param.goods_id 商品规格id
|
|
|
+ * @param {Transaction} tran 事务的实例
|
|
|
+ */
|
|
|
+ async toRefund({ afterSale_id, goods_id }, tran) {
|
|
|
+ const data = await this.model.findById(afterSale_id);
|
|
|
+ if (!data) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到售后信息');
|
|
|
+ const { populate } = this.ctx.service.trade.orderDetail.getRefMods();
|
|
|
+ const orderDetail = await this.orderDetailModel.findById(data.order_detail).populate(populate);
|
|
|
+ if (!orderDetail) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到售后信息的订单');
|
|
|
+ const money = _.get(data, 'goods.sell_money');
|
|
|
+ const reason = _.get(data, 'desc');
|
|
|
+ const order_no = _.get(orderDetail, 'order.pay.pay_no');
|
|
|
+ if (!order_no) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到支付订单号');
|
|
|
+ // 找下当前这个订单有多少次售后记录
|
|
|
+ let num = await this.model.count({ order_detail: data.order_detail });
|
|
|
+ num += 1;
|
|
|
+ // 组成退款单号
|
|
|
+ const out_refund_no = `${order_no}-r${num}`;
|
|
|
+ const obj = { reason, money, order_no, out_refund_no };
|
|
|
+ // TODO优惠部分
|
|
|
+
|
|
|
+ // 退款请求
|
|
|
+ const refundRes = await this.ctx.service.trade.pay.refund(obj);
|
|
|
+ console.log(refundRes);
|
|
|
}
|
|
|
}
|
|
|
|