xiongzhu 2 лет назад
Родитель
Сommit
917878935a

+ 5 - 2
src/app.module.ts

@@ -16,6 +16,7 @@ import { MembershipModule } from './membership/membership.module'
 import { WeixinModule } from './weixin/weixin.module'
 import { NotifyModule } from './notify/notify.module';
 import { CommissionModule } from './commission/commission.module';
+import { UserBalanceModule } from './user-balance/user-balance.module';
 
 @Module({
     imports: [
@@ -58,7 +59,8 @@ import { CommissionModule } from './commission/commission.module';
                 cli: {
                     migrationsDir: config.get<string>('TYPEORM_MIGRATIONS_DIR'),
                     subscribersDir: config.get<string>('TYPEORM_SUBSCRIBERS_DIR')
-                }
+                },
+                logging: true
             })
         }),
         AliyunModule,
@@ -70,7 +72,8 @@ import { CommissionModule } from './commission/commission.module';
         MembershipModule,
         WeixinModule,
         NotifyModule,
-        CommissionModule
+        CommissionModule,
+        UserBalanceModule
     ],
     controllers: [AppController],
     providers: [AppService]

+ 8 - 3
src/chat/chat.controller.ts

@@ -8,18 +8,18 @@ import { Public } from '../auth/public.decorator'
 @Controller('chat')
 @ApiBearerAuth()
 export class ChatController {
-    constructor(private readonly openaiService: ChatService) {}
+    constructor(private readonly chatService: ChatService) {}
 
     @Post('chat-process')
     @Sse()
     public chat(@Req() req, @Res() res): Observable<any> {
-        return this.openaiService.chat(req, res)
+        return this.chatService.chat(req, res)
     }
 
     @Post('chat-process1')
     @Sse()
     public async chat1(@Req() req, @Res() res) {
-        await this.openaiService.chat1(req, res)
+        await this.chatService.chat1(req, res)
     }
 
     @Public()
@@ -32,4 +32,9 @@ export class ChatController {
     public verify() {
         return { status: 'Success', message: 'Verify successfully', data: null }
     }
+
+    @Get('/usage')
+    public async getTokenUsage(@Req() req) {
+        return this.chatService.getUsage(req.user.id)
+    }
 }

+ 9 - 1
src/chat/chat.service.ts

@@ -3,7 +3,7 @@ import { Observable } from 'rxjs'
 import { ChatGPTAPI, ChatMessage } from '../chatapi'
 import type { RequestProps } from './types'
 import { chatReplyProcess } from './chatgpt'
-import { Repository } from 'typeorm'
+import { Repository, MoreThanOrEqual, LessThanOrEqual, And } from 'typeorm'
 import { ChatHistory } from './entities/chat.entity'
 import { InjectRepository } from '@nestjs/typeorm'
 import { TokenUsage } from './entities/token-usage.entity'
@@ -134,4 +134,12 @@ export class ChatService {
 
         this.membershipService.saveUsage(userId, usage)
     }
+
+    public async getUsage(userId: number, start?: string, end?: string): Promise<TokenUsage[]> {
+        const date = format(new Date(), 'yyyy-MM-dd')
+        return await this.tokenUsageRepository.findBy({
+            userId,
+            date: And(MoreThanOrEqual(start || '2023-04-01'), LessThanOrEqual(end || date))
+        })
+    }
 }

+ 14 - 3
src/commission/commission.controller.ts

@@ -1,4 +1,15 @@
-import { Controller } from '@nestjs/common';
+import { Controller, Get, Req } from '@nestjs/common'
+import { CommissionService } from './commission.service'
+import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'
 
-@Controller('commission')
-export class CommissionController {}
+@ApiTags('commission')
+@ApiBearerAuth()
+@Controller('/commission')
+export class CommissionController {
+    constructor(private readonly commissionService: CommissionService) {}
+
+    @Get('/records/get')
+    async getCommission(@Req() req) {
+        return await this.commissionService.getRecords(req.user.id)
+    }
+}

+ 2 - 1
src/commission/commission.module.ts

@@ -5,9 +5,10 @@ import { TypeOrmModule } from '@nestjs/typeorm'
 import { CommissionConfig } from './entities/commission-config.entity'
 import { CommissionRecord } from './entities/commission-record.entity'
 import { Users } from 'src/users/entities/users.entity'
+import { UserBalanceModule } from 'src/user-balance/user-balance.module'
 
 @Module({
-    imports: [TypeOrmModule.forFeature([CommissionRecord, CommissionConfig, Users])],
+    imports: [TypeOrmModule.forFeature([CommissionRecord, CommissionConfig, Users]), UserBalanceModule],
     providers: [CommissionService],
     controllers: [CommissionController],
     exports: [CommissionService]

+ 19 - 3
src/commission/commission.service.ts

@@ -3,7 +3,9 @@ import { InjectRepository } from '@nestjs/typeorm'
 import { CommissionConfig } from './entities/commission-config.entity'
 import { Repository } from 'typeorm'
 import { CommissionRecord } from './entities/commission-record.entity'
-import { Users } from 'src/users/entities/users.entity'
+import { Users } from '../users/entities/users.entity'
+import { UserBalanceService } from '../user-balance/user-balance.service'
+import { Type as BalanceType } from 'src/user-balance/entities/balance-record.entity'
 
 @Injectable()
 export class CommissionService {
@@ -13,7 +15,8 @@ export class CommissionService {
         @InjectRepository(CommissionRecord)
         private readonly commissionRecordRepository: Repository<CommissionRecord>,
         @InjectRepository(Users)
-        private readonly usersRepository: Repository<Users>
+        private readonly usersRepository: Repository<Users>,
+        private readonly userBalanceService: UserBalanceService
     ) {}
 
     async saveConfig(config: Partial<CommissionConfig>) {
@@ -38,15 +41,28 @@ export class CommissionService {
             const config = configs.find((config) => config.level === i + 1)
             if (config) {
                 const commission = Number((amount * config.ratio).toFixed(2))
+                await this.userBalanceService.modifyBalance(invitorId, commission, BalanceType.COMMISSION)
                 await this.commissionRecordRepository.save({
                     userId: invitorId,
                     amount,
                     commission,
-                    level: configs[i].level
+                    level: configs[i].level,
+                    ratio: configs[i].ratio
                 })
             }
             if (!invitor.invitor) return
             invitorId = invitor.invitor
         }
     }
+
+    async getRecords(userId: number){
+        return await this.commissionRecordRepository.find({
+            where: {
+                userId
+            },
+            order: {
+                createdAt: 'DESC'
+            }
+        })
+    }
 }

+ 0 - 9
src/commission/entities/balance-record.entity.ts

@@ -1,9 +0,0 @@
-import { Column,ValueTransformer } from "typeorm"
-import { Big } from 'big.js'
-
-export class BalanceRecord {
-    userId: number
-
-    @Column({ type: 'decimal', precision: 19, scale: 2 })
-    amount: number
-}

+ 3 - 2
src/commission/entities/commission-record.entity.ts

@@ -1,5 +1,6 @@
-import { Column, PrimaryGeneratedColumn } from 'typeorm'
+import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'
 
+@Entity()
 export class CommissionRecord {
     @PrimaryGeneratedColumn()
     id: number
@@ -16,7 +17,7 @@ export class CommissionRecord {
     @Column()
     ratio: number
 
-    @Column()
+    @Column({ type: 'decimal', precision: 19, scale: 2 })
     amount: number
 
     @Column()

+ 0 - 1
src/commission/entities/user-balance.entity.ts

@@ -1 +0,0 @@
-export class UserBalance {}

+ 2 - 0
src/notify/notify.controller.ts

@@ -1,7 +1,9 @@
 import { Body, Controller, Headers, HttpCode, Post } from '@nestjs/common'
 import { NotifyService } from './notify.service'
 import { Public } from 'src/auth/public.decorator'
+import { ApiTags } from '@nestjs/swagger'
 
+@ApiTags('notify')
 @Controller('/notify')
 export class NotifyController {
     constructor(private readonly notifyService: NotifyService) {}

+ 41 - 0
src/user-balance/entities/balance-record.entity.ts

@@ -0,0 +1,41 @@
+import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, ValueTransformer } from 'typeorm'
+import { Big } from 'big.js'
+
+export enum Type {
+    COMMISSION = 'COMMISSION',
+    WITHDRAW = 'WITHDRAW'
+}
+
+@Entity()
+export class BalanceRecord {
+    @PrimaryGeneratedColumn()
+    id: number
+
+    @Column()
+    userId: number
+
+    @Column({ type: 'decimal', precision: 19, scale: 2 })
+    amount: number
+
+    @Column({ type: 'decimal', precision: 19, scale: 2 })
+    balance: number
+
+    @Column({ type: 'decimal', precision: 19, scale: 2 })
+    lastBalance: number
+
+    @Column({ type: 'enum', enum: Type })
+    type: Type
+
+    @Column({ nullable: true })
+    remark: string
+
+    @Column({ nullable: true })
+    extra: string
+
+    @CreateDateColumn()
+    createdAt: Date
+
+    constructor(record: Partial<BalanceRecord>) {
+        Object.assign(this, record)
+    }
+}

+ 26 - 0
src/user-balance/entities/user-balance.entity.ts

@@ -0,0 +1,26 @@
+import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'
+
+@Entity()
+export class UserBalance {
+    @PrimaryGeneratedColumn()
+    id: number
+
+    @Column({ unique: true })
+    userId: number
+
+    @Column({ type: 'decimal', precision: 19, scale: 2 })
+    balance: number
+
+    @Column()
+    lastBalance: number
+
+    @CreateDateColumn()
+    createdAt: Date
+
+    @UpdateDateColumn()
+    updatedAt: Date
+
+    constructor(userBalance: Partial<UserBalance>) {
+        Object.assign(this, userBalance)
+    }
+}

+ 20 - 0
src/user-balance/user-balance.controller.ts

@@ -0,0 +1,20 @@
+import { Controller, Get, Post, Req } from '@nestjs/common'
+import { UserBalanceService } from './user-balance.service'
+import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'
+
+@ApiTags('userBalance')
+@ApiBearerAuth()
+@Controller('/userBalance')
+export class UserBalanceController {
+    constructor(private readonly userBalanceService: UserBalanceService) {}
+
+    @Get('/get')
+    async getBalance(@Req() req) {
+        return await this.userBalanceService.getBalance(req.user.id)
+    }
+ 
+    @Get('/records/get')
+    async getRecords(@Req() req) {
+        return await this.userBalanceService.getRecords(req.user.id)
+    }
+}

+ 14 - 0
src/user-balance/user-balance.module.ts

@@ -0,0 +1,14 @@
+import { Module } from '@nestjs/common'
+import { UserBalanceService } from './user-balance.service'
+import { UserBalanceController } from './user-balance.controller'
+import { TypeOrmModule } from '@nestjs/typeorm'
+import { UserBalance } from './entities/user-balance.entity'
+import { BalanceRecord } from './entities/balance-record.entity'
+
+@Module({
+    imports: [TypeOrmModule.forFeature([UserBalance, BalanceRecord])],
+    providers: [UserBalanceService],
+    controllers: [UserBalanceController],
+    exports: [UserBalanceService]
+})
+export class UserBalanceModule {}

+ 57 - 0
src/user-balance/user-balance.service.ts

@@ -0,0 +1,57 @@
+import { Injectable } from '@nestjs/common'
+import { InjectRepository } from '@nestjs/typeorm'
+import { UserBalance } from './entities/user-balance.entity'
+import { Repository } from 'typeorm'
+import { BalanceRecord, Type } from './entities/balance-record.entity'
+
+@Injectable()
+export class UserBalanceService {
+    constructor(
+        @InjectRepository(UserBalance)
+        private readonly userBalanceRepository: Repository<UserBalance>,
+        @InjectRepository(BalanceRecord)
+        private readonly balanceRecordRepository: Repository<BalanceRecord>
+    ) {}
+
+    async getBalance(userId: number): Promise<UserBalance> {
+        let userBalance = await this.userBalanceRepository.findOneBy({ userId })
+        if (!userBalance) {
+            userBalance = new UserBalance({
+                userId,
+                balance: 0,
+                lastBalance: 0
+            })
+            await this.userBalanceRepository.save(userBalance)
+        }
+        return userBalance
+    }
+
+    async modifyBalance(userId: number, amount: number, type: Type, remark?: string, extra?: string) {
+        const userBalance = await this.getBalance(userId)
+        await this.balanceRecordRepository.save(
+            new BalanceRecord({
+                userId,
+                amount,
+                balance: userBalance.balance + amount,
+                lastBalance: userBalance.balance,
+                type,
+                remark,
+                extra
+            })
+        )
+        userBalance.lastBalance = userBalance.balance
+        userBalance.balance += amount
+        await this.userBalanceRepository.save(userBalance)
+    }
+
+    async getRecords(userId: number, ) {
+        return await this.balanceRecordRepository.find({
+            where: {
+                userId
+            },
+            order: {
+                createdAt: 'DESC'
+            }
+        })
+    }
+}