From d2287bc3637381ae397fac0b7f8f9915fe328ebd Mon Sep 17 00:00:00 2001 From: tone <3341154833@qq.com> Date: Thu, 8 May 2025 22:07:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=AE=A1=E7=90=86=E6=AE=B5?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=A2=9E=E5=88=A0=E6=94=B9=E6=9F=A5=E6=94=B9?= =?UTF-8?q?=E5=AF=86=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tone-page-server/src/admin/admin.module.ts | 4 +- .../admin/controller/admin-user.controller.ts | 37 ++++++++++++++++- .../src/admin/dto/admin-user/create.dto.ts | 23 +++++++++++ .../dto/admin-user/update-password.dto.ts | 8 ++++ .../src/admin/dto/admin-user/update.dto.ts | 23 +++++++++++ tone-page-server/src/user/user.service.ts | 40 ++++++++++++++++++- 6 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 tone-page-server/src/admin/dto/admin-user/create.dto.ts create mode 100644 tone-page-server/src/admin/dto/admin-user/update-password.dto.ts create mode 100644 tone-page-server/src/admin/dto/admin-user/update.dto.ts diff --git a/tone-page-server/src/admin/admin.module.ts b/tone-page-server/src/admin/admin.module.ts index b25f99a..0fce98f 100644 --- a/tone-page-server/src/admin/admin.module.ts +++ b/tone-page-server/src/admin/admin.module.ts @@ -4,12 +4,14 @@ import { AdminUserController } from './controller/admin-user.controller'; import { AdminUserService } from './service/admin-user.service'; import { TypeOrmModule } from '@nestjs/typeorm'; import { User } from 'src/user/entities/user.entity'; +import { UserModule } from 'src/user/user.module'; @Module({ imports: [ TypeOrmModule.forFeature([ User, - ]) + ]), + UserModule, ], controllers: [ AdminController, diff --git a/tone-page-server/src/admin/controller/admin-user.controller.ts b/tone-page-server/src/admin/controller/admin-user.controller.ts index bea4368..4883258 100644 --- a/tone-page-server/src/admin/controller/admin-user.controller.ts +++ b/tone-page-server/src/admin/controller/admin-user.controller.ts @@ -1,12 +1,17 @@ -import { Controller, Get, Query } from "@nestjs/common"; +import { Body, Controller, Delete, Get, Param, ParseUUIDPipe, Post, Put, Query } from "@nestjs/common"; import { AdminUserService } from "../service/admin-user.service"; import { ListDto } from "../dto/admin-user/list.dto"; +import { CreateDto } from "../dto/admin-user/create.dto"; +import { UserService } from "src/user/user.service"; +import { UpdateDto } from "../dto/admin-user/update.dto"; +import { UpdatePasswordDto } from "../dto/admin-user/update-password.dto"; @Controller('admin/user') export class AdminUserController { constructor( private readonly adminUserService: AdminUserService, + private readonly userService: UserService, ) { } @Get() @@ -15,4 +20,34 @@ export class AdminUserController { ) { return this.adminUserService.getUser(listDto.page, listDto.pageSize); } + + @Post() + async create( + @Body() createDto: CreateDto + ) { + return this.userService.create(createDto); + } + + @Put(':userId') + async update( + @Param('userId', new ParseUUIDPipe({ version: '4' })) userId: string, + @Body() updateDto: UpdateDto, + ) { + return this.userService.update(userId, updateDto); + } + + @Delete(':userId') + async delete( + @Param('userId', new ParseUUIDPipe({ version: '4' })) userId: string, + ) { + return this.userService.delete(userId); + } + + @Post(':userId/password') + async setPassword( + @Param('userId', new ParseUUIDPipe({ version: '4' })) userId: string, + @Body() updatePasswordDto: UpdatePasswordDto, + ) { + return this.userService.setPassword(userId, updatePasswordDto.password); + } } \ No newline at end of file diff --git a/tone-page-server/src/admin/dto/admin-user/create.dto.ts b/tone-page-server/src/admin/dto/admin-user/create.dto.ts new file mode 100644 index 0000000..94a0b10 --- /dev/null +++ b/tone-page-server/src/admin/dto/admin-user/create.dto.ts @@ -0,0 +1,23 @@ +import { IsOptional, IsString } from "class-validator"; + +export class CreateDto { + @IsOptional() + @IsString() + username?: string; + + @IsOptional() + @IsString() + nickname?: string; + + @IsOptional() + @IsString() + email?: string; + + @IsOptional() + @IsString() + phone?: string; + + @IsOptional() + @IsString() + avatar?: string; +} \ No newline at end of file diff --git a/tone-page-server/src/admin/dto/admin-user/update-password.dto.ts b/tone-page-server/src/admin/dto/admin-user/update-password.dto.ts new file mode 100644 index 0000000..2fac29c --- /dev/null +++ b/tone-page-server/src/admin/dto/admin-user/update-password.dto.ts @@ -0,0 +1,8 @@ +import { IsString, Length, Matches } from "class-validator"; + +export class UpdatePasswordDto { + @IsString() + @Length(6, 32) + @Matches(/^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d!@#$%^&*()_+\-=\[\]{};:'",.<>/?]{6,32}$/) + password: string; +} \ No newline at end of file diff --git a/tone-page-server/src/admin/dto/admin-user/update.dto.ts b/tone-page-server/src/admin/dto/admin-user/update.dto.ts new file mode 100644 index 0000000..849ceaa --- /dev/null +++ b/tone-page-server/src/admin/dto/admin-user/update.dto.ts @@ -0,0 +1,23 @@ +import { IsOptional, IsString } from "class-validator"; + +export class UpdateDto { + @IsOptional() + @IsString() + username?: string; + + @IsOptional() + @IsString() + nickname?: string; + + @IsOptional() + @IsString() + email?: string; + + @IsOptional() + @IsString() + phone?: string; + + @IsOptional() + @IsString() + avatar?: string; +} \ No newline at end of file diff --git a/tone-page-server/src/user/user.service.ts b/tone-page-server/src/user/user.service.ts index adbda50..0bf6358 100644 --- a/tone-page-server/src/user/user.service.ts +++ b/tone-page-server/src/user/user.service.ts @@ -1,7 +1,9 @@ -import { Injectable } from '@nestjs/common'; +import { BadRequestException, Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { User } from './entities/user.entity'; import { Repository } from 'typeorm'; +import { createHash } from 'crypto'; +import { v4 as uuid } from 'uuid'; type UserFindOptions = Partial>; @@ -23,4 +25,40 @@ export class UserService { const newUser = this.userRepository.create(user); return this.userRepository.save(newUser); } + + async update(userId: string, user: Partial): Promise { + const existingUser = await this.userRepository.findOne({ where: { userId } }); + if (!existingUser) { + throw new BadRequestException('User not found'); + } + Object.assign(existingUser, user); + return this.userRepository.save(existingUser); + } + + async delete(userId: string): Promise { + const existingUser = await this.userRepository.findOne({ where: { userId } }); + if (!existingUser) { + throw new BadRequestException('User not found'); + } + await this.userRepository.softDelete(existingUser.id); + } + + hashPassword(password: string, salt: string): string { + return createHash('sha256').update(`${password}${salt}`).digest('hex'); + } + + generateSalt(): string { + return uuid().replace(/-/g, ''); + } + + async setPassword(userId: string, password: string): Promise { + const user = await this.userRepository.findOne({ where: { userId } }); + if (!user) { + throw new BadRequestException('User not found'); + } + const salt = this.generateSalt(); + user.password_hash = this.hashPassword(password, salt); + user.salt = salt; + return this.userRepository.save(user); + } }