wangzhibo
5 天以前 50e5cdbaceee71f000341a434620d10a87b582f5
src/modules/order/service/pay.ts
@@ -1,14 +1,16 @@
import { Init, Inject, Provide } from '@midwayjs/core';
import { BaseService, CoolCommException } from '@cool-midway/core';
import { BaseService, CoolCommException, CoolTransaction } from '@cool-midway/core';
import { PluginService } from '../../plugin/service/info';
import { OrderInfoService } from './info';
import { UserWxService } from '../../user/service/wx';
import BigNumber from 'bignumber.js';
import { OrderInfoEntity } from '../entity/info';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { QueryRunner, Repository } from 'typeorm';
import { Action, OrderQueue } from '../queue/order';
import { BaseSysParamService } from '../../base/service/sys/param';
import { UserInfoEntity } from '../../user/entity/info';
import { RecycleTransactionEntity } from '../../shop/entity/transaction';
/**
 * 支付
@@ -17,6 +19,12 @@
export class OrderPayService extends BaseService {
  @InjectEntityModel(OrderInfoEntity)
  orderInfoEntity: Repository<OrderInfoEntity>;
  @InjectEntityModel(UserInfoEntity)
  userInfoEntity: Repository<UserInfoEntity>;
  @InjectEntityModel(RecycleTransactionEntity)
  recycleTransactionEntity: Repository<RecycleTransactionEntity>;
  @Inject()
  pluginService: PluginService;
@@ -41,7 +49,7 @@
  /**
   * 支付成功
   * @param orderNum 订单号
   * @param payType 支付方式 0-待支付 1-微信 2-支付宝
   * @param payType 支付方式 0-待支付 1-微信 2-支付宝 3-碳积分
   */
  async paySuccess(orderNum: string, payType: number) {
    const order = await this.orderInfoService.getByOrderNum(orderNum);
@@ -49,7 +57,7 @@
      await this.orderInfoEntity.update(order.id, {
        payType,
        status: 1,
        payTime: order.payTime,
        payTime: new Date(),
      });
      // 发送自动确认收货队列
      const orderConfirm = await this.baseSysParamService.dataByKey(
@@ -71,7 +79,7 @@
   * @param userId
   * @param orderId
   */
  async wxMiniPay(orderId: number, userId: number) {
  async wxMiniPay(orderId: number, userId: string) {
    await this.orderInfoEntity.update(orderId, { wxType: 0 });
    return await this.wxJSAPI(orderId, userId, 0);
  }
@@ -81,7 +89,7 @@
   * @param userId
   * @param orderId
   */
  async wxMpPay(orderId: number, userId: number) {
  async wxMpPay(orderId: number, userId: string) {
    await this.orderInfoEntity.update(orderId, { wxType: 1 });
    return await this.wxJSAPI(orderId, userId, 1);
  }
@@ -134,7 +142,7 @@
   * @param userId
   * @returns
   */
  async wxAppPay(orderId: number, userId: number) {
  async wxAppPay(orderId: number, userId: string) {
    const appid = await this.getAppidByType(2);
    const { config, instance } = await this.wxPayInstance(appid);
@@ -162,7 +170,7 @@
   * @param userId
   * @returns
   */
  async getOrder(orderId: number, userId: number) {
  async getOrder(orderId: number, userId: string) {
    const order: OrderInfoEntity = await this.orderInfoService.info(orderId);
    if (!order || order.status != 0 || order.userId != userId) {
      throw new CoolCommException('订单不存在或不是可以支付的状态');
@@ -177,7 +185,7 @@
   * @param type 0-小程序 1-公众号 2-App
   * @returns
   */
  async wxJSAPI(orderId: number, userId: number, type = 0) {
  async wxJSAPI(orderId: number, userId: string, type = 0) {
    const order = await this.getOrder(orderId, userId);
    const openid = await this.userWxService.getOpenid(userId, type);
@@ -235,4 +243,91 @@
    }
    throw new CoolCommException(result.message);
  }
  /**
   * 读取碳积分兑换比例,默认 100
   */
  async getCarbonRatio() {
    try {
      const value = await this.baseSysParamService.dataByKey('carbonratio');
      const ratio = Number(value);
      if (ratio > 0) {
        return ratio;
      }
    } catch (e) {}
    return 100;
  }
  /**
   * 碳积分支付:不调用外部渠道
   * 扣减积分 = 订单实付金额 * carbonratio
   */
  @CoolTransaction()
  async carbonPay(orderId: number, userId: string, queryRunner?: QueryRunner) {
    if (!queryRunner) {
      throw new CoolCommException('事务启动失败');
    }
    const manager = queryRunner.manager;
    const order = await manager.findOne(OrderInfoEntity, {
      where: { id: orderId },
    });
    if (!order || order.status != 0 || order.userId != userId) {
      throw new CoolCommException('订单不存在或不是可以支付的状态');
    }
    const user = await manager.findOne(UserInfoEntity, {
      where: { unionid: userId },
    });
    if (!user) {
      throw new CoolCommException('用户不存在');
    }
    const ratio = await this.getCarbonRatio();
    const payAmount = new BigNumber(order.price).minus(order.discountPrice || 0);
    const carbonCost = payAmount.multipliedBy(ratio).toNumber();
    if (Number(user.carbonBalance || 0) < carbonCost) {
      throw new CoolCommException('碳积分不足');
    }
    const dec = await manager
      .createQueryBuilder()
      .update(UserInfoEntity)
      .set({ carbonBalance: () => `carbonBalance - ${carbonCost}` })
      .where('id = :id AND carbonBalance >= :cost', {
        id: userId,
        cost: carbonCost,
      })
      .execute();
    if (!dec.affected) {
      throw new CoolCommException('碳积分不足');
    }
    await manager.update(OrderInfoEntity, order.id, {
      payType: 3,
      status: 1,
      payTime: new Date(),
    });
    await manager.save(RecycleTransactionEntity, {
      userId: user.unionid || String(userId),
      departmentId: user.departmentId,
      type: '支出',
      amount: carbonCost,
      sourceType: '商城',
      remark: `商城订单 ${order.orderNum} 碳积分支付`,
      orderId: order.orderNum,
    });
    const orderConfirm = await this.baseSysParamService.dataByKey('orderConfirm');
    this.orderQueue.add(
      { orderId: order.id, action: Action.CONFIRM },
      {
        delay: orderConfirm * 60 * 60 * 1000,
      }
    );
    return true;
  }
}