| | |
| | | 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'; |
| | | |
| | | /** |
| | | * 支付 |
| | |
| | | export class OrderPayService extends BaseService { |
| | | @InjectEntityModel(OrderInfoEntity) |
| | | orderInfoEntity: Repository<OrderInfoEntity>; |
| | | |
| | | @InjectEntityModel(UserInfoEntity) |
| | | userInfoEntity: Repository<UserInfoEntity>; |
| | | |
| | | @InjectEntityModel(RecycleTransactionEntity) |
| | | recycleTransactionEntity: Repository<RecycleTransactionEntity>; |
| | | |
| | | @Inject() |
| | | pluginService: PluginService; |
| | |
| | | /** |
| | | * 支付成功 |
| | | * @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); |
| | |
| | | await this.orderInfoEntity.update(order.id, { |
| | | payType, |
| | | status: 1, |
| | | payTime: order.payTime, |
| | | payTime: new Date(), |
| | | }); |
| | | // 发送自动确认收货队列 |
| | | const orderConfirm = await this.baseSysParamService.dataByKey( |
| | |
| | | * @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); |
| | | } |
| | |
| | | * @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); |
| | | } |
| | |
| | | * @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); |
| | |
| | | * @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('订单不存在或不是可以支付的状态'); |
| | |
| | | * @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); |
| | | |
| | |
| | | } |
| | | 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; |
| | | } |
| | | } |