commission.service.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { join } from 'path'
  2. import { Inject, Injectable, forwardRef } from '@nestjs/common'
  3. import { InjectRepository } from '@nestjs/typeorm'
  4. import { CommissionConfig } from './entities/commission-config.entity'
  5. import { Repository } from 'typeorm'
  6. import { CommissionRecord } from './entities/commission-record.entity'
  7. import { Users } from '../users/entities/users.entity'
  8. import { UserBalanceService } from '../user-balance/user-balance.service'
  9. import { BalanceType as BalanceType } from 'src/user-balance/entities/balance-record.entity'
  10. import { BigNumber } from 'bignumber.js'
  11. import { CommissionRecordDto } from './dto/commission-record.dto'
  12. import { hideSensitiveData } from 'src/utils/common'
  13. import { MembershipService } from 'src/membership/membership.service'
  14. @Injectable()
  15. export class CommissionService {
  16. constructor(
  17. @InjectRepository(CommissionConfig)
  18. private readonly commissionConfigRepository: Repository<CommissionConfig>,
  19. @InjectRepository(CommissionRecord)
  20. private readonly commissionRecordRepository: Repository<CommissionRecord>,
  21. @InjectRepository(Users)
  22. private readonly usersRepository: Repository<Users>,
  23. private readonly userBalanceService: UserBalanceService,
  24. @Inject(forwardRef(() => MembershipService))
  25. private readonly membershipService: MembershipService
  26. ) {}
  27. async saveConfig(config: Partial<CommissionConfig>) {
  28. return await this.commissionConfigRepository.save(config)
  29. }
  30. async doCommission(userId: number, amount: BigNumber) {
  31. amount = new BigNumber(amount)
  32. const user = await this.usersRepository.findOneBy({
  33. id: userId
  34. })
  35. if (!user || !user.invitor) return
  36. const plans = await this.membershipService.getPlans()
  37. const configs = await this.commissionConfigRepository.find()
  38. const maxLevel = configs.map((config) => config.level).sort((a, b) => b - a)[0] || 0
  39. let invitorId = user.invitor
  40. for (let i = 0; i < maxLevel; i++) {
  41. const invitor = await this.usersRepository.findOneBy({
  42. id: invitorId
  43. })
  44. if (!invitor) return
  45. const membership = await this.membershipService.getMembership(invitorId)
  46. const plan = plans.find((plan) => plan.id === membership.planId)
  47. if (plan?.commissionable) {
  48. const config = configs.find((config) => config.level === i + 1)
  49. if (config) {
  50. const commission = amount.times(config.ratio)
  51. await this.userBalanceService.modifyBalance(invitorId, commission, BalanceType.COMMISSION)
  52. await this.commissionRecordRepository.save(
  53. new CommissionRecord({
  54. userId: invitorId,
  55. fromUserId: userId,
  56. amount: commission,
  57. level: configs[i].level,
  58. ratio: configs[i].ratio
  59. })
  60. )
  61. }
  62. }
  63. if (!invitor.invitor) return
  64. invitorId = invitor.invitor
  65. }
  66. }
  67. async getRecords(userId: number) {
  68. return (
  69. await this.commissionRecordRepository
  70. .createQueryBuilder()
  71. .leftJoinAndMapOne(
  72. 'CommissionRecord.fromUser',
  73. Users,
  74. 'fromUser',
  75. 'CommissionRecord.fromUserId = fromUser.id'
  76. )
  77. .where('CommissionRecord.userId = :userId', { userId })
  78. .orderBy('CommissionRecord.createdAt', 'DESC')
  79. .getMany()
  80. ).map((record) => {
  81. return new CommissionRecordDto({
  82. id: record.id,
  83. userId: record.userId,
  84. fromUserId: record.fromUserId,
  85. name: hideSensitiveData(record.fromUser?.name),
  86. level: record.level,
  87. ratio: record.ratio,
  88. amount: record.amount
  89. })
  90. })
  91. // return await this.commissionRecordRepository.find({
  92. // relations: {
  93. // fromUser: true
  94. // },
  95. // where: {
  96. // userId
  97. // },
  98. // order: {
  99. // createdAt: 'DESC'
  100. // }
  101. // })
  102. }
  103. }