完成admin-user-update

This commit is contained in:
2025-05-12 11:40:21 +08:00
parent 0d9ff2bfa6
commit d8fd52d73e
9 changed files with 155 additions and 57 deletions

View File

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

View File

@@ -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 '数据已存在,请检查输入';
}
}