lrf 2 years ago
parent
commit
a19a5db716

+ 165 - 27
app/service/business/lesson.js

@@ -3,6 +3,8 @@ const { CrudService } = require('naf-framework-mongoose-free/lib/service');
 const { BusinessError, ErrorCode } = require('naf-core').Error;
 const _ = require('lodash');
 const assert = require('assert');
+const Transaction = require('mongoose-transactions');
+const moment = require('moment');
 
 //
 class LessonService extends CrudService {
@@ -12,6 +14,12 @@ class LessonService extends CrudService {
     this.lessonCoachModel = this.ctx.model.Business.LessonCoach;
     this.lessonStudentModel = this.ctx.model.Business.LessonStudent;
     this.coachInBillService = this.ctx.service.business.coachInBill;
+    this.lessonStudentModel = this.ctx.model.Business.LessonStudent;
+    this.tempLessonApplyModel = this.ctx.model.Apply.TempLessonApply;
+    this.rssModel = this.ctx.model.Relation.RelationStudentSchool;
+    this.payOrderModel = this.ctx.model.Business.PayOrder;
+    this.payService = this.ctx.service.wxpay;
+    this.tran = new Transaction();
   }
 
   /**
@@ -24,39 +32,169 @@ class LessonService extends CrudService {
   async afterUpdate(filter, body, data) {
     const { _id: lesson_id, type, status, school_id } = data;
     if (status !== '4') return data;
+    if (status === '-1') {
+      await this.refundThisLesson(data);
+      return data;
+    }
     const arr = [];
 
-    if (type === '0') {
-      // 公开课,每个教师都带着自己的金额. 按 人头数 * 单价 算钱
-      const lessonCoachList = await this.lessonCoachModel.find({ lesson_id });
-      // 这节课付了款的学生总数
-      const studentNum = await this.lessonStudentModel.count({ lesson_id, is_pay: '1' });
-      const obj = { lesson_id, type, school_id };
-      for (const c of lessonCoachList) {
-        const { coach_id, money } = c;
-        const total = money * studentNum;
-        arr.push({ ...obj, coach_id, money: total });
+    // if (type === '0') {
+    //   // 公开课,每个教师都带着自己的金额. 按 人头数 * 单价 算钱
+    //   const lessonCoachList = await this.lessonCoachModel.find({ lesson_id });
+    //   // 这节课付了款的学生总数
+    //   const studentNum = await this.lessonStudentModel.count({ lesson_id, is_pay: '1' });
+    //   const obj = { lesson_id, type, school_id };
+    //   for (const c of lessonCoachList) {
+    //     const { coach_id, money } = c;
+    //     const total = money * studentNum;
+    //     arr.push({ ...obj, coach_id, money: total });
+    //   }
+    // } else {
+    //   // 私教课, 按学生实际缴费
+    //   const lessonCoach = await this.lessonCoachModel.findOne({ lesson_id });
+    //   const studentList = await this.lessonStudentModel.find({ lesson_id });
+    //   const obj = { lesson_id, type, school_id };
+    //   obj.coach_id = lessonCoach.coach_id;
+    //   const total = studentList.reduce((p, n) => p + (n.money || 0), 0);
+    //   obj.money = total;
+    //   arr.push(obj);
+    // }
+    // // 创建,如果有该学校,这节课的这个教练已经有数据了,就不需要生成了
+    // for (const i of arr) {
+    //   try {
+    //     await this.coachInBillService.create(i);
+    //   } catch (error) {
+    //     // 不是数据有问题,就是有数据了,要不一般不会出错
+    //   }
+    // }
+
+    return data;
+  }
+  /**
+   * 退课,退款(能退到账户余额就退到账户余额,不能的就直接走退款接口)
+   * @param {Lesson} lesson 课程信息
+   */
+  async refundThisLesson(lesson) {
+    const lesson_id = _.get(lesson, '_id');
+    if (!lesson_id) return;
+    try {
+      // 取出学生id,支付单id,缴费金额
+      const studentList = await this.lessonStudentModel.find({ lesson_id, is_pay: '1', is_try: '0' }, 'student_id, pay_id, money, school_id');
+      for (const s of studentList) {
+        // 修改支付状态,返回金额
+        const r = await this.refundByRrs(s, this.tran);
+        // 没有关系,那就直接去用支付订单退款
+        if (!r) await this.refundByPayOrder(s, this.tran);
       }
-    } else {
-      // 私教课, 按学生实际缴费
-      const lessonCoach = await this.lessonCoachModel.findOne({ lesson_id });
-      const studentList = await this.lessonStudentModel.find({ lesson_id });
-      const obj = { lesson_id, type, school_id };
-      obj.coach_id = lessonCoach.coach_id;
-      const total = studentList.reduce((p, n) => p + (n.money || 0), 0);
-      obj.money = total;
-      arr.push(obj);
-    }
-    // 创建,如果有该学校,这节课的这个教练已经有数据了,就不需要生成了
-    for (const i of arr) {
-      try {
-        await this.coachInBillService.create(i);
-      } catch (error) {
-        // 不是数据有问题,就是有数据了,要不一般不会出错
+      const tempLessonList = await this.tempLessonApplyModel.find({ lesson_id, is_pay: '1' }, 'student_id, school_id, money,pay_id,');
+      for (const t of tempLessonList) {
+        // 如果有学生id,说明是有账号的,退余额
+        const r = await this.refundByTempLesson(t, this.tran);
+        // 没有学生id,需要原路返回
+        if (!r) await this.refundByPayOrder(t, this.tran);
       }
+      await this.tran.run();
+    } catch (error) {
+      await this.tran.rollback();
+      console.error(error);
+    } finally {
+      this.tran.clean();
     }
+  }
+  /**
+   * 退款至余额
+   * @param {Object} lessonStudent 学生上课报名信息
+   * @param {Transaction} tran 数据库事务
+   */
+  async refundByRrs(lessonStudent, tran) {
+    const { school_id, student_id, pay_id, money, _id } = lessonStudent;
+    const rss = await this.rssModel.find({ school_id, student_id });
+    if (!rss) return false;
+    const surplus = _.get(rss, 'money');
+    const newMoney = this.ctx.plus(surplus, money);
+    // 退款
+    tran.update('RelationStudentSchool', rss._id, { money: newMoney });
+    // 改状态
+    tran.update('LessonStudent', lessonStudent._id, { is_pay: '-3' });
+    tran.update('PayOrder', pay_id, { is_pay: '-3' });
+    // 生成账单数据
+    const billData = {
+      school_id,
+      payer_id: student_id,
+      payer_role: 'Student',
+      pay_for: 'LessonStudent',
+      from_id: _id,
+      type: '2',
+      pay_id,
+      is_pay: '1',
+      time: moment().format('YYYY-MM-DD HH:mm:ss'),
+      money,
+    };
+    tran.insert('Bill', billData);
+    return true;
+  }
+  /**
+   * 退临时上课申请至余额
+   * @param {Object} tempLessonApply 临时上课申请数据
+   * @param {Transaction} tran 数据库事务
+   */
+  async refundByTempLesson(tempLessonApply, tran) {
+    const { school_id, student_id, pay_id, money, _id } = tempLessonApply;
+    if (!student_id) return false;
+    const rss = await this.rssModel.find({ school_id, student_id });
+    if (!rss) return false;
+    const surplus = _.get(rss, 'money');
+    const newMoney = this.ctx.plus(surplus, money);
+    // 退款
+    tran.update('RelationStudentSchool', rss._id, { money: newMoney });
+    // 改状态
+    tran.update('TempLessonApply', _id, { is_pay: '-3' });
+    tran.update('PayOrder', pay_id, { is_pay: '-3' });
+    // 生成账单数据
+    const billData = {
+      school_id,
+      payer_id: student_id,
+      payer_role: 'Student',
+      pay_for: 'TempLessonApply',
+      from_id: _id,
+      type: '2',
+      pay_id,
+      is_pay: '1',
+      time: moment().format('YYYY-MM-DD HH:mm:ss'),
+      money,
+    };
+    tran.insert('Bill', billData);
+    return true;
+  }
 
-    return data;
+  /**
+   * 原路退款, 因为没有关系,才走原路退款的,所以别查关系了,没有滴
+   * @param {Object} data 学生上课报名信息
+   * @param {Transaction} tran 数据库事务
+   */
+  async refundByPayOrder(data, tran) {
+    const { pay_id, school_id } = data;
+    const payOrder = await this.payOrderModel.findById(pay_id);
+    if (!payOrder) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到支付单信息');
+    const order_no = _.get(data, 'order_no');
+    const pay_for = _.get(payOrder, 'pay_for');
+    const from_id = _.get(payOrder, 'from_id');
+    if (!order_no) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到支付单号');
+    await this.payService.refund(order_no, '课程取消');
+    // 修改状态
+    tran.update('PayOrder', pay_id, { is_pay: '-3' });
+    tran.update(pay_for, from_id, { is_pay: '-3' });
+    // 生成账单
+    const billData = {
+      school_id,
+      pay_for,
+      from_id,
+      type: '2',
+      pay_id,
+      is_pay: '1',
+      time: moment().format('YYYY-MM-DD HH:mm:ss'),
+    };
+    tran.insert('Bill', billData);
   }
 }
 

+ 0 - 1
app/service/business/lessonStudent.js

@@ -5,7 +5,6 @@ const _ = require('lodash');
 const assert = require('assert');
 const moment = require('moment');
 const Transaction = require('mongoose-transactions');
-const { find } = require('lodash');
 
 //
 class LessonStudentService extends CrudService {

+ 1 - 1
app/service/business/payOrder.js

@@ -145,7 +145,7 @@ class PayOrderService extends CrudService {
     // 数据修改
     try {
       // 修改支付单数据
-      this.tran.update('PayOrder', data._id, { ...payerInfo, ...obj });
+      this.tran.update('PayOrder', data._id, { ...payerInfo, ...obj, config: { result } });
       if (_.get(data, 'pay_for') === 'TempLessonApply') {
         // 临时上课的支付信息,需要修改 TempLessonApply 表的支付状态,生成账单
         // 修改临时上课表的数据