123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- '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 Transaction = require('mongoose-transactions');
- const moment = require('moment');
- //
- class LessonService extends CrudService {
- constructor(ctx) {
- super(ctx, 'lesson');
- this.model = this.ctx.model.Business.Lesson;
- 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();
- }
- /**
- * 处理下课的课程进行结算
- * @param {Object} filter 修改条件
- * @param {Object} body 修改内容
- * @param {Object} data 修改后的结果
- * @return {Object} 返回整理后的内容
- */
- 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 });
- // }
- // } 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);
- }
- 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;
- }
- /**
- * 原路退款, 因为没有关系,才走原路退款的,所以别查关系了,没有滴
- * @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);
- }
- }
- module.exports = LessonService;
|