实现管理段用户增删改查改密码

This commit is contained in:
2025-05-08 22:07:06 +08:00
parent 887c714e25
commit ff4c755fc8
6 changed files with 132 additions and 3 deletions

View File

@@ -4,12 +4,14 @@ import { AdminUserController } from './controller/admin-user.controller';
import { AdminUserService } from './service/admin-user.service'; import { AdminUserService } from './service/admin-user.service';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from 'src/user/entities/user.entity'; import { User } from 'src/user/entities/user.entity';
import { UserModule } from 'src/user/user.module';
@Module({ @Module({
imports: [ imports: [
TypeOrmModule.forFeature([ TypeOrmModule.forFeature([
User, User,
]) ]),
UserModule,
], ],
controllers: [ controllers: [
AdminController, AdminController,

View File

@@ -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 { AdminUserService } from "../service/admin-user.service";
import { ListDto } from "../dto/admin-user/list.dto"; 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') @Controller('admin/user')
export class AdminUserController { export class AdminUserController {
constructor( constructor(
private readonly adminUserService: AdminUserService, private readonly adminUserService: AdminUserService,
private readonly userService: UserService,
) { } ) { }
@Get() @Get()
@@ -15,4 +20,34 @@ export class AdminUserController {
) { ) {
return this.adminUserService.getUser(listDto.page, listDto.pageSize); 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);
}
} }

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -1,7 +1,9 @@
import { Injectable } from '@nestjs/common'; import { BadRequestException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { User } from './entities/user.entity'; import { User } from './entities/user.entity';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { createHash } from 'crypto';
import { v4 as uuid } from 'uuid';
type UserFindOptions = Partial<Pick<User, 'userId' | 'username' | 'phone' | 'email'>>; type UserFindOptions = Partial<Pick<User, 'userId' | 'username' | 'phone' | 'email'>>;
@@ -23,4 +25,40 @@ export class UserService {
const newUser = this.userRepository.create(user); const newUser = this.userRepository.create(user);
return this.userRepository.save(newUser); return this.userRepository.save(newUser);
} }
async update(userId: string, user: Partial<User>): Promise<User> {
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<void> {
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<User> {
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);
}
} }