xiongzhu 2 лет назад
Родитель
Сommit
12f79931bd

Разница между файлами не показана из-за своего большого размера
+ 339 - 180
package-lock.json


+ 3 - 0
package.json

@@ -58,11 +58,14 @@
     "mongodb": "^5.2.0",
     "mongoose": "^7.0.4",
     "mysql2": "^3.1.2",
+    "nestjs-typeorm-paginate": "^4.0.3",
     "nodemailer": "^6.9.1",
     "p-timeout": "^6.1.1",
     "passport": "^0.6.0",
     "passport-http-bearer": "^1.0.1",
     "passport-jwt": "^4.0.1",
+    "patch-package": "^6.5.1",
+    "postinstall-postinstall": "^2.1.0",
     "quick-lru": "^5.0.0",
     "randomstring": "^1.2.3",
     "reflect-metadata": "^0.1.13",

+ 3 - 1
src/app.module.ts

@@ -17,6 +17,7 @@ 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'
+import { WithdrawModule } from './withdraw/withdraw.module';
 
 @Module({
     imports: [
@@ -72,7 +73,8 @@ import { UserBalanceModule } from './user-balance/user-balance.module'
         WeixinModule,
         NotifyModule,
         CommissionModule,
-        UserBalanceModule
+        UserBalanceModule,
+        WithdrawModule
     ],
     controllers: [AppController],
     providers: [AppService]

+ 2 - 1
src/user-balance/entities/balance-record.entity.ts

@@ -4,7 +4,8 @@ import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, ValueTransfor
 
 export enum BalanceType {
     COMMISSION = 'COMMISSION',
-    WITHDRAW = 'WITHDRAW'
+    WITHDRAW = 'WITHDRAW',
+    RETURN = 'RETURN'
 }
 
 @Entity()

+ 13 - 0
src/user-balance/user-balance.admin.controller.ts

@@ -0,0 +1,13 @@
+import { Controller } from '@nestjs/common'
+import { UserBalanceService } from './user-balance.service'
+import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'
+import { HasRoles } from 'src/auth/roles.decorator'
+import { Role } from 'src/model/role.enum'
+
+@ApiTags('userBalance.admin')
+@ApiBearerAuth()
+@HasRoles(Role.Admin)
+@Controller('/admin/userBalance')
+export class UserBalanceAdminController {
+    constructor(private readonly userBalanceService: UserBalanceService) {}
+}

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

@@ -1,7 +1,6 @@
 import { Body, Controller, Get, Post, Req } from '@nestjs/common'
 import { UserBalanceService } from './user-balance.service'
 import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'
-import { WithdrawApplyDto } from './dto/withdraw-apply.dto'
 
 @ApiTags('userBalance')
 @ApiBearerAuth()
@@ -18,9 +17,4 @@ export class UserBalanceController {
     async getRecords(@Req() req) {
         return await this.userBalanceService.getRecords(req.user.id)
     }
-
-    @Post('/withdraw')
-    async withdraw(@Req() req, @Body() body: WithdrawApplyDto) {
-        return await this.userBalanceService.applyWithdraw(req.user.id, body.amount, body.remark, body.extra)
-    }
 }

+ 2 - 1
src/user-balance/user-balance.module.ts

@@ -4,11 +4,12 @@ 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'
+import { UserBalanceAdminController } from './user-balance.admin.controller'
 
 @Module({
     imports: [TypeOrmModule.forFeature([UserBalance, BalanceRecord])],
     providers: [UserBalanceService],
-    controllers: [UserBalanceController],
+    controllers: [UserBalanceController, UserBalanceAdminController],
     exports: [UserBalanceService]
 })
 export class UserBalanceModule {}

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

@@ -60,8 +60,4 @@ export class UserBalanceService {
             }
         })
     }
-
-    async applyWithdraw(userId: number, amount: string, remark?: string, extra?: string) {
-        return await this.modifyBalance(userId, new BigNumber(amount).negated(), BalanceType.WITHDRAW, remark, extra)
-    }
 }

+ 3 - 2
src/users/users.admin.controller.ts

@@ -18,6 +18,7 @@ import { IUsers } from './interfaces/users.interface'
 import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'
 import { HasRoles } from '../auth/roles.decorator'
 import { Role } from '../model/role.enum'
+import { IPaginationOptions } from 'nestjs-typeorm-paginate'
 
 @ApiTags('users.admin')
 @Controller('/admin/users')
@@ -27,8 +28,8 @@ export class UsersAdminController {
     constructor(private readonly usersService: UsersService) {}
 
     @Get()
-    public async findAllUser(): Promise<IUsers[]> {
-        return this.usersService.findAll()
+    public async findAllUser(@Body() options: IPaginationOptions) {
+        return await this.usersService.findAll(options)
     }
 
     @Put('/:userId')

+ 3 - 2
src/users/users.service.ts

@@ -17,6 +17,7 @@ import { HashingService } from '../shared/hashing/hashing.service'
 import { SmsService } from '../sms/sms.service'
 import * as randomstring from 'randomstring'
 import { MembershipService } from '../membership/membership.service'
+import { paginate, Pagination, IPaginationOptions } from 'nestjs-typeorm-paginate'
 
 @Injectable()
 export class UsersService {
@@ -28,8 +29,8 @@ export class UsersService {
         private readonly membershipService: MembershipService
     ) {}
 
-    public async findAll(): Promise<Users[]> {
-        return await this.userRepository.find()
+    async findAll(options: IPaginationOptions): Promise<Pagination<Users>> {
+        return await paginate<Users>(this.userRepository, options)
     }
 
     public async findByEmail(email: string): Promise<Users> {

+ 6 - 0
src/user-balance/dto/withdraw-apply.dto.ts → src/withdraw/dto/withdraw-apply.dto.ts

@@ -5,6 +5,12 @@ export class WithdrawApplyDto {
     @IsString()
     amount: string
 
+    @IsString()
+    name: string
+
+    @IsString()
+    account: string
+
     remark?: string
 
     extra?: string

+ 18 - 3
src/user-balance/entities/withdraw.entity.ts → src/withdraw/entities/withdraw.entity.ts

@@ -1,12 +1,18 @@
-import { Column, CreateDateColumn, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'
+import BigNumber from 'bignumber.js'
+import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'
 
 export enum WithdrawStatus {
     PENDING = 'PENDING',
     SUCCESS = 'SUCCESS',
-    FAILED = 'FAILED'
+    REJECTED = 'REJECTED'
 }
 
+@Entity()
 export class Withdraw {
+    constructor(data: Partial<Withdraw>) {
+        Object.assign(this, data)
+    }
+
     @PrimaryGeneratedColumn()
     id: number
 
@@ -14,11 +20,20 @@ export class Withdraw {
     userId: number
 
     @Column({ type: 'decimal', precision: 19, scale: 2 })
-    amount: number
+    amount: BigNumber
+
+    @Column()
+    name: string
+
+    @Column()
+    account: string
 
     @Column({ type: 'enum', enum: WithdrawStatus })
     status: WithdrawStatus
 
+    @Column({ nullable: true })
+    remark?: string
+
     @CreateDateColumn()
     createdAt: Date
 

+ 30 - 0
src/withdraw/withdraw.admin.controller.ts

@@ -0,0 +1,30 @@
+import { IPaginationOptions } from 'nestjs-typeorm-paginate';
+import { Body, Controller, Post, Req } from '@nestjs/common'
+import { WithdrawApplyDto } from './dto/withdraw-apply.dto'
+import { WithdrawService } from './withdraw.service'
+import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'
+import { HasRoles } from 'src/auth/roles.decorator'
+import { Role } from 'src/model/role.enum'
+
+@ApiTags('withdraw.admin')
+@ApiBearerAuth()
+@HasRoles(Role.Admin)
+@Controller('/admin/withdraw')
+export class WithdrawAdminController {
+    constructor(private readonly withdrawService: WithdrawService) {}
+
+    @Post()
+    async list(@Body() page:IPaginationOptions) {
+        
+    }
+
+    @Post('/finish')
+    async apply(@Body() { id }) {
+        return await this.withdrawService.finishWithdraw(id)
+    }
+
+    @Post('/reject')
+    async reject(@Body() { id }) {
+        return await this.withdrawService.rejectWithdraw(id)
+    }
+}

+ 16 - 0
src/withdraw/withdraw.controller.ts

@@ -0,0 +1,16 @@
+import { Body, Controller, Post, Req } from '@nestjs/common'
+import { WithdrawApplyDto } from './dto/withdraw-apply.dto'
+import { WithdrawService } from './withdraw.service'
+import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'
+
+@ApiTags('withdraw')
+@ApiBearerAuth()
+@Controller('/withdraw')
+export class WithdrawController {
+    constructor(private readonly withdrawService: WithdrawService) {}
+
+    @Post('/apply')
+    async apply(@Req() req, @Body() body: WithdrawApplyDto) {
+        return await this.withdrawService.applyWithdraw(req.user.id, body.amount, body.name, body.account, body.remark)
+    }
+}

+ 14 - 0
src/withdraw/withdraw.module.ts

@@ -0,0 +1,14 @@
+import { Module } from '@nestjs/common'
+import { WithdrawService } from './withdraw.service'
+import { WithdrawController } from './withdraw.controller'
+import { TypeOrmModule } from '@nestjs/typeorm'
+import { Withdraw } from './entities/withdraw.entity'
+import { WithdrawAdminController } from './withdraw.admin.controller'
+import { UserBalanceModule } from 'src/user-balance/user-balance.module'
+
+@Module({
+    imports: [TypeOrmModule.forFeature([Withdraw]), UserBalanceModule],
+    providers: [WithdrawService],
+    controllers: [WithdrawController, WithdrawAdminController]
+})
+export class WithdrawModule {}

+ 65 - 0
src/withdraw/withdraw.service.ts

@@ -0,0 +1,65 @@
+import { BadRequestException, Injectable } from '@nestjs/common'
+import { InjectRepository } from '@nestjs/typeorm'
+import { UserBalanceService } from '../user-balance/user-balance.service'
+import { Withdraw, WithdrawStatus } from './entities/withdraw.entity'
+import { Repository } from 'typeorm'
+import BigNumber from 'bignumber.js'
+import { BalanceType } from '../user-balance/entities/balance-record.entity'
+import { IPaginationOptions, Pagination, paginate } from 'nestjs-typeorm-paginate'
+
+@Injectable()
+export class WithdrawService {
+    constructor(
+        private readonly userBalanceService: UserBalanceService,
+        @InjectRepository(Withdraw)
+        private readonly withdrawRepository: Repository<Withdraw>
+    ) {}
+
+    async findAll(options: IPaginationOptions): Promise<Pagination<Withdraw>> {
+        return await paginate<Withdraw>(this.withdrawRepository, options)
+    }
+
+    async applyWithdraw(userId: number, amount: string, name: string, account: string, remark?: string) {
+        await this.userBalanceService.modifyBalance(
+            userId,
+            new BigNumber(amount).negated(),
+            BalanceType.WITHDRAW,
+            remark
+        )
+        return await this.withdrawRepository.save(
+            new Withdraw({
+                userId,
+                amount: new BigNumber(amount),
+                name,
+                account,
+                status: WithdrawStatus.PENDING,
+                remark
+            })
+        )
+    }
+
+    async rejectWithdraw(id: number) {
+        const withdraw = await this.withdrawRepository.findOneBy({ id })
+        if (!withdraw) {
+            throw new BadRequestException('提现记录不存在')
+        }
+        if (withdraw.status !== WithdrawStatus.PENDING) {
+            throw new BadRequestException('提现记录不可取消')
+        }
+        await this.userBalanceService.modifyBalance(withdraw.userId, withdraw.amount, BalanceType.RETURN)
+        withdraw.status = WithdrawStatus.REJECTED
+        return await this.withdrawRepository.save(withdraw)
+    }
+
+    async finishWithdraw(id: number) {
+        const withdraw = await this.withdrawRepository.findOneBy({ id })
+        if (!withdraw) {
+            throw new BadRequestException('提现记录不存在')
+        }
+        if (withdraw.status !== WithdrawStatus.PENDING) {
+            throw new BadRequestException('提现记录不可完成')
+        }
+        withdraw.status = WithdrawStatus.SUCCESS
+        return await this.withdrawRepository.save(withdraw)
+    }
+}

Разница между файлами не показана из-за своего большого размера
+ 633 - 847
yarn.lock


Некоторые файлы не были показаны из-за большого количества измененных файлов