完成admin-user-update
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
import { IsOptional, IsString } from "class-validator";
|
||||
import { IsString, Length, ValidateIf } from "class-validator";
|
||||
|
||||
export class CreateDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
username?: string;
|
||||
@ValidateIf(o => o.username !== null)
|
||||
@IsString({ message: '用户名不得为空' })
|
||||
@Length(6, 32, { message: '用户名长度只能为6~32' })
|
||||
username: string | null;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
nickname?: string;
|
||||
@ValidateIf(o => o.username !== null)
|
||||
@IsString({ message: '昵称不得为空' })
|
||||
@Length(6, 30, { message: '昵称长度只能为6~30' })
|
||||
nickname: string | null;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
email?: string;
|
||||
@ValidateIf(o => o.username !== null)
|
||||
@IsString({ message: '邮箱不得为空' })
|
||||
@Length(6, 254, { message: '邮箱长度只能为6~254' })
|
||||
email: string | null;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
phone?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
avatar?: string;
|
||||
@ValidateIf(o => o.username !== null)
|
||||
@IsString({ message: '手机号不得为空' })
|
||||
@Length(11, 11, { message: '手机号长度只能为11' })
|
||||
phone: string | null;
|
||||
}
|
||||
@@ -1,23 +1,29 @@
|
||||
import { IsOptional, IsString } from "class-validator";
|
||||
import { IsEmail, IsOptional, IsString, Length, Matches, ValidateIf } from "class-validator";
|
||||
|
||||
export class UpdateDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
username?: string;
|
||||
@IsString({ message: '用户名不得为空' })
|
||||
@Length(6, 32, { message: '用户名长度只能为6~32' })
|
||||
username: string;
|
||||
|
||||
@IsString({ message: '昵称不得为空' })
|
||||
@Length(6, 30, { message: '昵称长度只能为6~30' })
|
||||
nickname: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
nickname?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@IsEmail({}, { message: '请输入有效的邮箱地址', always: false })
|
||||
@Length(6, 254, {
|
||||
message: '邮箱长度只能为6~254',
|
||||
// 仅在值不为 null 或 undefined 时验证
|
||||
always: false
|
||||
})
|
||||
email?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@IsOptional() // 标记字段为可选
|
||||
@IsString({ message: '手机号不得为空', always: false })
|
||||
@Matches(/^1[3456789]\d{9}$/, {
|
||||
message: '请输入有效的手机号码',
|
||||
// 仅在值不为 null 或 undefined 时验证
|
||||
always: false
|
||||
})
|
||||
phone?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
avatar?: string;
|
||||
}
|
||||
@@ -2,16 +2,18 @@ import { BeforeInsert, Column, CreateDateColumn, DeleteDateColumn, Entity, Index
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
@Entity()
|
||||
@Index("IDX_user_userid", ["userId"], { unique: true })
|
||||
@Index("IDX_user_username", ["username"], { unique: true })
|
||||
@Index("IDX_user_email", ["email"], { unique: true, where: "email IS NOT NULL" })
|
||||
@Index("IDX_user_phone", ["phone"], { unique: true, where: "phone IS NOT NULL" })
|
||||
export class User {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column('uuid', { unique: true, default: () => 'gen_random_uuid()' })
|
||||
@Index({ unique: true })
|
||||
@Column('uuid', { default: () => 'gen_random_uuid()' })
|
||||
userId: string;
|
||||
|
||||
@Column({ length: 32 })
|
||||
@Index({ unique: true })
|
||||
username: string;
|
||||
|
||||
@Column({ length: 30 })
|
||||
@@ -33,15 +35,33 @@ export class User {
|
||||
@Column({ nullable: true, type: 'char', length: 64 })
|
||||
password_hash: string;
|
||||
|
||||
@Column({ nullable: true, length: 254 })// RFC 5321
|
||||
@Index({ unique: true })
|
||||
email: string;
|
||||
@Column({
|
||||
nullable: true,
|
||||
length: 254,
|
||||
transformer: {
|
||||
to: (value: string | null) => value?.trim() || null,
|
||||
from: (value: string | null) => value,
|
||||
}
|
||||
})// RFC 5321
|
||||
email: string | null;
|
||||
|
||||
@Column({ nullable: true, length: 20 })// China Mainland
|
||||
@Index({ unique: true })
|
||||
phone: string;
|
||||
@Column({
|
||||
nullable: true,
|
||||
length: 20,
|
||||
transformer: {
|
||||
to: (value: string | null) => value?.trim() || null,
|
||||
from: (value: string | null) => value,
|
||||
}
|
||||
})// China Mainland
|
||||
phone: string | null;
|
||||
|
||||
@Column({ nullable: true })
|
||||
@Column({
|
||||
nullable: true,
|
||||
transformer: {
|
||||
to: (value: string | null) => value?.trim() || null,
|
||||
from: (value: string | null) => value,
|
||||
}
|
||||
})
|
||||
avatar: string;
|
||||
|
||||
@CreateDateColumn({ precision: 3 })
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
import { BadRequestException, ConflictException, Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { User } from './entities/user.entity';
|
||||
import { Repository } from 'typeorm';
|
||||
import { createHash } from 'crypto';
|
||||
import { QueryFailedError, Repository } from 'typeorm';
|
||||
import { createHash, ECDH } from 'crypto';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
type UserFindOptions = Partial<Pick<User, 'userId' | 'username' | 'phone' | 'email'>>;
|
||||
@@ -31,8 +31,14 @@ export class UserService {
|
||||
if (!existingUser) {
|
||||
throw new BadRequestException('User not found');
|
||||
}
|
||||
Object.assign(existingUser, user);
|
||||
return this.userRepository.save(existingUser);
|
||||
try {
|
||||
Object.assign(existingUser, user);
|
||||
return await this.userRepository.save(existingUser);
|
||||
} catch (error) {
|
||||
if (error instanceof QueryFailedError) {
|
||||
throw new ConflictException(this.getDuplicateErrorMessage(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async delete(userId: string): Promise<void> {
|
||||
@@ -61,4 +67,18 @@ export class UserService {
|
||||
user.salt = salt;
|
||||
return this.userRepository.save(user);
|
||||
}
|
||||
|
||||
private getDuplicateErrorMessage(error: QueryFailedError): string {
|
||||
// 根据具体的错误信息返回友好的提示
|
||||
if (error.message.includes('IDX_user_username')) {
|
||||
return '用户名已被使用';
|
||||
}
|
||||
if (error.message.includes('IDX_user_email')) {
|
||||
return '邮箱已被使用';
|
||||
}
|
||||
if (error.message.includes('IDX_user_phone')) {
|
||||
return '手机号已被使用';
|
||||
}
|
||||
return '数据已存在,请检查输入';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user