实现管理段用户增删改查改密码
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
23
tone-page-server/src/admin/dto/admin-user/create.dto.ts
Normal file
23
tone-page-server/src/admin/dto/admin-user/create.dto.ts
Normal 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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
23
tone-page-server/src/admin/dto/admin-user/update.dto.ts
Normal file
23
tone-page-server/src/admin/dto/admin-user/update.dto.ts
Normal 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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user