- 新增 Dockerfile 和 .dockerignore 文件 - 添加 Gitea 持续集成工作流,用于构建和推送 Docker 镜像 - 新增 .gitignore 文件,忽略构建和配置文件 - 添加项目结构和规范文档,包括 TypeScript、模块化、API、数据库等规范 - 新增前端和后端的基础代码结构
138 lines
4.0 KiB
TypeScript
138 lines
4.0 KiB
TypeScript
import { HTTPException } from 'hono/http-exception'
|
|
import { DataSource } from 'typeorm';
|
|
import { UserEntity as User } from './user.entity';
|
|
import * as bcrypt from 'bcrypt';
|
|
import { Repository } from 'typeorm';
|
|
import { Role } from './role.entity';
|
|
|
|
const SALT_ROUNDS = 10;
|
|
|
|
export class UserService {
|
|
private userRepository: Repository<User>;
|
|
private roleRepository: Repository<Role>;
|
|
private readonly dataSource: DataSource;
|
|
|
|
constructor(dataSource: DataSource) {
|
|
this.dataSource = dataSource;
|
|
this.userRepository = this.dataSource.getRepository(User);
|
|
this.roleRepository = this.dataSource.getRepository(Role);
|
|
}
|
|
|
|
async createUser(userData: Partial<User>): Promise<User> {
|
|
try {
|
|
if (userData.password) {
|
|
userData.password = await bcrypt.hash(userData.password, SALT_ROUNDS);
|
|
}
|
|
const user = this.userRepository.create(userData);
|
|
return await this.userRepository.save(user);
|
|
} catch (error) {
|
|
console.error('Error creating user:', error);
|
|
throw new HTTPException(400,{ message: 'Failed to create user', cause: error})
|
|
}
|
|
}
|
|
|
|
async getUserById(id: number): Promise<User | null> {
|
|
try {
|
|
return await this.userRepository.findOne({
|
|
where: { id },
|
|
relations: ['roles']
|
|
});
|
|
} catch (error) {
|
|
console.error('Error getting user:', error);
|
|
throw new Error('Failed to get user');
|
|
}
|
|
}
|
|
|
|
async getUserByUsername(username: string): Promise<User | null> {
|
|
try {
|
|
return await this.userRepository.findOne({
|
|
where: { username },
|
|
relations: ['roles']
|
|
});
|
|
} catch (error) {
|
|
console.error('Error getting user:', error);
|
|
throw new Error('Failed to get user');
|
|
}
|
|
}
|
|
|
|
async getUserByPhone(phone: string): Promise<User | null> {
|
|
try {
|
|
return await this.userRepository.findOne({
|
|
where: { mobile: phone },
|
|
relations: ['roles']
|
|
});
|
|
} catch (error) {
|
|
console.error('Error getting user by phone:', error);
|
|
throw new Error('Failed to get user by phone');
|
|
}
|
|
}
|
|
|
|
async updateUser(id: number, updateData: Partial<User>): Promise<User | null> {
|
|
try {
|
|
if (updateData.password) {
|
|
updateData.password = await bcrypt.hash(updateData.password, SALT_ROUNDS);
|
|
}
|
|
await this.userRepository.update(id, updateData);
|
|
return this.getUserById(id);
|
|
} catch (error) {
|
|
console.error('Error updating user:', error);
|
|
throw new Error('Failed to update user');
|
|
}
|
|
}
|
|
|
|
async deleteUser(id: number): Promise<void> {
|
|
try {
|
|
await this.userRepository.delete(id);
|
|
} catch (error) {
|
|
console.error('Error deleting user:', error);
|
|
throw new Error('Failed to delete user');
|
|
}
|
|
}
|
|
|
|
async verifyPassword(user: User, password: string): Promise<boolean> {
|
|
return bcrypt.compare(password, user.password);
|
|
}
|
|
|
|
async assignRoles(userId: number, roleIds: number[]): Promise<User | null> {
|
|
try {
|
|
const user = await this.getUserById(userId);
|
|
if (!user) return null;
|
|
|
|
const roles = await this.roleRepository.findByIds(roleIds);
|
|
user.roles = roles;
|
|
return await this.userRepository.save(user);
|
|
} catch (error) {
|
|
console.error('Error assigning roles:', error);
|
|
throw new Error('Failed to assign roles');
|
|
}
|
|
}
|
|
|
|
async getUsers(): Promise<User[]> {
|
|
try {
|
|
const users = await this.userRepository.find({
|
|
relations: ['roles']
|
|
});
|
|
return users;
|
|
} catch (error) {
|
|
console.error('Error getting users:', error);
|
|
throw new HTTPException(500, { message: 'Failed to get users', cause: error })
|
|
}
|
|
}
|
|
|
|
|
|
getUserRepository(): Repository<User> {
|
|
return this.userRepository;
|
|
}
|
|
|
|
async getUserByAccount(account: string): Promise<User | null> {
|
|
try {
|
|
return await this.userRepository.findOne({
|
|
where: [{ username: account }, { email: account }],
|
|
relations: ['roles']
|
|
});
|
|
} catch (error) {
|
|
console.error('Error getting user by account:', error);
|
|
throw new Error('Failed to get user by account');
|
|
}
|
|
}
|
|
} |