import { Service, Inject } from 'typedi'; import winston from 'winston'; import { User, UserModel, UserRole, UserStatus } from '../data/user'; import { Op } from 'sequelize'; @Service() export default class UserManagementService { constructor(@Inject('logger') private logger: winston.Logger) {} public async list(searchText?: string): Promise { let query: any = {}; if (searchText) { query = { username: { [Op.like]: `%${searchText}%` }, }; } const docs = await UserModel.findAll({ where: query }); return docs.map((x) => x.get({ plain: true })); } public async get(id: number): Promise { const doc = await UserModel.findByPk(id); if (!doc) { throw new Error('用户不存在'); } return doc.get({ plain: true }); } public async getByUsername(username: string): Promise { const doc = await UserModel.findOne({ where: { username } }); if (!doc) { return null; } return doc.get({ plain: true }); } public async create(payload: User): Promise { const existingUser = await this.getByUsername(payload.username); if (existingUser) { throw new Error('用户名已存在'); } if (payload.password === 'admin') { throw new Error('密码不能设置为admin'); } const doc = await UserModel.create(payload); return doc.get({ plain: true }); } public async update(payload: User): Promise { if (!payload.id) { throw new Error('缺少用户ID'); } const existingUser = await this.get(payload.id); if (!existingUser) { throw new Error('用户不存在'); } if (payload.password === 'admin') { throw new Error('密码不能设置为admin'); } // Check if username is being changed and if new username already exists if (payload.username !== existingUser.username) { const userWithSameUsername = await this.getByUsername(payload.username); if (userWithSameUsername && userWithSameUsername.id !== payload.id) { throw new Error('用户名已存在'); } } const [, [updated]] = await UserModel.update(payload, { where: { id: payload.id }, returning: true, }); return updated.get({ plain: true }); } public async delete(ids: number[]): Promise { const count = await UserModel.destroy({ where: { id: ids } }); return count; } public async authenticate( username: string, password: string, ): Promise { const user = await this.getByUsername(username); if (!user) { return null; } if (user.password !== password) { return null; } if (user.status === UserStatus.disabled) { throw new Error('用户已被禁用'); } return user; } }