|
@@ -17,12 +17,75 @@ class PayOrderService extends CrudService {
|
|
|
this.userModel = this.ctx.model.User.User;
|
|
|
this.studentModel = this.ctx.model.User.Student;
|
|
|
this.coachModel = this.ctx.model.User.Coach;
|
|
|
+ this.rcsModel = this.ctx.model.Relation.RelationCoachSchool;
|
|
|
+ this.rssModel = this.ctx.model.Relation.RelationStudentSchool;
|
|
|
+ this.costDetailModel = this.ctx.model.Business.CostDetail;
|
|
|
}
|
|
|
|
|
|
async beforeCreate(data) {
|
|
|
if (!_.get(data, 'order_no')) data.order_no = this.getOrderNo();
|
|
|
+ const { data: nd, next } = await this.checkSurplus(data);
|
|
|
+ if (!next) throw new BusinessError(0, '扣除余额成功');
|
|
|
+ data = nd;
|
|
|
return data;
|
|
|
}
|
|
|
+ // 检查是否扣除余额
|
|
|
+ async checkSurplus(data) {
|
|
|
+ const pay_for = _.get(data, 'pay_for');
|
|
|
+ // 充值不检查余额
|
|
|
+ if (pay_for && pay_for === 'charge') return { data, next: true };
|
|
|
+ const payer_id = _.get(data, 'payer_id');
|
|
|
+ const payer_role = _.get(data, 'payer_role');
|
|
|
+ let costDetailData;
|
|
|
+ let relation;
|
|
|
+ // 没有要支付的人及其角色,那就找不到余额,返回下单
|
|
|
+ if (!(payer_id && payer_role)) return { data, next: true };
|
|
|
+ // 有支付的人,可以查查这个人的余额
|
|
|
+ if (payer_role === 'Student') relation = await this.rssModel.findOne({ student_id: payer_id });
|
|
|
+ else if (payer_role === 'Coach') relation = await this.rcsModel.findOne({ coach_id: payer_id });
|
|
|
+ // 没找到关系,那就直接返回正常下单缴费
|
|
|
+ if (!relation) return { data, next: true };
|
|
|
+ // 有关系,找余额
|
|
|
+ const { money: surplus } = relation;
|
|
|
+ const { money } = data;
|
|
|
+ // 没有余额,或者余额没钱,返回正常下单缴费
|
|
|
+ if (surplus && surplus <= 0) return { data, next: true };
|
|
|
+ // 有余额,看余额够不够
|
|
|
+ if (surplus >= money) {
|
|
|
+ try {
|
|
|
+ // 余额够, 无需生成订单,直接去使用余额缴费
|
|
|
+ const costDetail = _.pick(data, [ 'school_id', 'payer_id', 'payer_role', 'pay_for', 'from_id' ]);
|
|
|
+ // 本次扣除余额的金额就是本次需要支付的金额
|
|
|
+ costDetail.money = money;
|
|
|
+ costDetail.type = '1';
|
|
|
+ costDetailData = await this.costDetailModel.create(costDetail);
|
|
|
+ // 余额需要扣除本次支付的费用
|
|
|
+ relation.money = surplus - money;
|
|
|
+ await relation.save();
|
|
|
+ return false;
|
|
|
+ } catch (error) {
|
|
|
+ // 抓取数据库创建和修改的异常,
|
|
|
+ // 如果 costDetailData没有值,说明是创建消费记录时发生的错误,不需要做回滚处理;如果有值,那就删除
|
|
|
+ if (costDetailData) {
|
|
|
+ await this.costDetailModel.deleteOne({ _id: costDetailData._id });
|
|
|
+ }
|
|
|
+ // 如果是余额修改错误,上面的回滚删除就足够了.因为保存新余额发生错误,余额不会保存,只要把消费记录删了,就回到原样了
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 余额不够,在config里记录部分使用了余额,再进行下单,下单完后,生成余额的扣款
|
|
|
+ const needPay = surplus - money;
|
|
|
+ const costDetail = _.pick(data, [ 'school_id', 'payer_id', 'payer_role', 'pay_for', 'from_id' ]);
|
|
|
+ costDetail.money = surplus;
|
|
|
+ costDetail.type = '1';
|
|
|
+ if (!data.config) data.config = {};
|
|
|
+ // 添加余额的设置, 等支付成功后,再生成余额的消费记录
|
|
|
+ data.config.useSurplus = true;
|
|
|
+ data.config.costDetail = costDetail;
|
|
|
+ data.money = needPay;
|
|
|
+ }
|
|
|
+
|
|
|
+ return { data, next: true };
|
|
|
+ }
|
|
|
|
|
|
async afterCreate(body, data) {
|
|
|
await this.syncData(data);
|
|
@@ -40,10 +103,8 @@ class PayOrderService extends CrudService {
|
|
|
*/
|
|
|
async syncData(data) {
|
|
|
const pay_for = _.get(data, 'pay_for');
|
|
|
- if (!pay_for) {
|
|
|
- // 不知道该去同步哪个表的支付状态,不处理
|
|
|
- return;
|
|
|
- }
|
|
|
+ // 不知道该去同步哪个表的支付状态,不处理
|
|
|
+ if (!pay_for) return;
|
|
|
const { from_id: _id, status: is_pay, money, _id: pay_id, config } = data;
|
|
|
if (pay_for === 'lessonStudent') {
|
|
|
// 因为上课产生的支付,去找lessonStudent,修改指定学生的支付状态
|
|
@@ -59,8 +120,16 @@ class PayOrderService extends CrudService {
|
|
|
const obj = { lesson_id, student_id, school_id, is_pay, pay_id, config, money };
|
|
|
await this.lessonStudentService.create(obj);
|
|
|
} else if (pay_for === 'charge') {
|
|
|
- // 充值
|
|
|
- await this.chargeModel.updateOne({ _id }, { is_pay });
|
|
|
+ // 充值记录,找到充值记录,没有就生成
|
|
|
+ const chargeData = await this.chargeModel.findOne({ pay_id });
|
|
|
+ if (chargeData) {
|
|
|
+ // 有就修改
|
|
|
+ chargeData.is_pay = is_pay;
|
|
|
+ await chargeData.save();
|
|
|
+ } else {
|
|
|
+ const obj = _.pick(data, [ 'school_id', 'payer_id', 'payer_role', 'pay_id' ]);
|
|
|
+ await this.chargeModel.create({ ...obj, is_pay, time: moment().format('YYYY-MM-DD HH:mm:ss') });
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|