| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- import { FastifyRequest, FastifyReply, FastifyInstance } from 'fastify'
- import { UserService } from '../services/user.service'
- import { MemberTokenManagerService } from '../services/member-token-manager.service'
- import {
- ListUserQuery,
- LoginBody,
- RegisterBody,
- ResetPasswordBody,
- CreateUserBody,
- UpdateUserBody
- } from '../dto/user.dto'
- import { UserRole } from '../entities/user.entity'
- export class UserController {
- private userService: UserService
- private tokenManagerService: MemberTokenManagerService
- constructor(app: FastifyInstance) {
- this.userService = new UserService(app)
- this.tokenManagerService = new MemberTokenManagerService(app)
- }
- async register(request: FastifyRequest<{ Body: RegisterBody }>, reply: FastifyReply) {
- try {
- const { password, name } = request.body
- const existingUser = await this.userService.findByName(name)
- if (existingUser) {
- return reply.code(400).send({ message: '用户名已存在' })
- }
- const user = await this.userService.create(password, name)
- const token = await reply.jwtSign({ id: user.id, name: user.name, role: user.role })
- return reply.code(201).send({
- user: {
- id: user.id,
- name: user.name
- },
- token
- })
- } catch (error) {
- return reply.code(500).send({ message: '注册失败' })
- }
- }
- async login(request: FastifyRequest<{ Body: LoginBody }>, reply: FastifyReply) {
- try {
- const { name, password } = request.body
- if (!name || !password) {
- return reply.code(400).send({ message: '请输入用户名和密码' })
- }
- const user = await this.userService.findByName(name)
- if (!user) {
- return reply.code(401).send({ message: '用户名或密码错误' })
- }
- if (!user.password) {
- return reply.code(401).send({ message: '该用户未设置密码,请联系管理员' })
- }
- const isValidPassword = await this.userService.validatePassword(user, password)
- if (!isValidPassword) {
- return reply.code(401).send({ message: '用户名或密码错误' })
- }
- // 单点登录:使该用户的所有其他token失效
- await this.tokenManagerService.invalidateUserTokens(user.id)
- const token = await reply.jwtSign({ id: user.id, name: user.name, role: user.role })
- return reply.send({
- user: {
- id: user.id,
- name: user.name
- },
- token,
- message: '登录成功,其他设备已自动下线'
- })
- } catch (error) {
- return reply.code(500).send({ message: '登录失败' })
- }
- }
- async profile(request: FastifyRequest, reply: FastifyReply) {
- try {
- const user = await this.userService.findById(request.user.id)
- return reply.send({
- id: user.id,
- name: user.name,
- role: user.role
- })
- } catch (error) {
- return reply.code(500).send({ message: '获取用户信息失败' })
- }
- }
- async resetPassword(request: FastifyRequest<{ Body: ResetPasswordBody }>, reply: FastifyReply) {
- try {
- const { password } = request.body
- if (password.length < 8 || !/(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/.test(password)) {
- return reply.code(400).send({ message: '密码长度必须至少8位,包含大小写字母和数字' })
- }
- await this.userService.resetPassword(request.user.id, password)
- return reply.send({ message: '密码重置成功' })
- } catch (error) {
- return reply.code(500).send({ message: '重置密码失败' })
- }
- }
- async list(request: FastifyRequest<{ Querystring: ListUserQuery }>, reply: FastifyReply) {
- try {
- const { user, query } = request
- if (!user) {
- return reply.code(403).send({
- error: 'Forbidden',
- message: 'Unauthorized access'
- })
- }
- const parentId = user.id
- const { page, size } = query
- const result = await this.userService.findAllChildUsers(parentId, page, size)
- return reply.send(result)
- } catch (error) {
- request.log.error({ error }, '获取用户列表失败')
- const errorMessage = error instanceof Error ? error.message : '获取用户列表失败'
- return reply.code(500).send({
- message: '获取用户列表失败',
- error: errorMessage
- })
- }
- }
- async getAllUsers(request: FastifyRequest, reply: FastifyReply) {
- const users = await this.userService.findAllUsers()
- return reply.send(users)
- }
- async createUser(request: FastifyRequest<{ Body: CreateUserBody }>, reply: FastifyReply) {
- try {
- const { password, name, role } = request.body
- const existingUser = await this.userService.findByName(name)
- if (existingUser) {
- return reply.code(400).send({ message: '用户名已存在' })
- }
- const user = await this.userService.create(password, name, role, request.user.id)
- return reply.code(201).send({
- user: {
- id: user.id,
- name: user.name,
- role: user.role,
- createdAt: user.createdAt,
- updatedAt: user.updatedAt
- }
- })
- } catch (error) {
- return reply.code(500).send({ message: '创建用户失败' })
- }
- }
- async updateUser(request: FastifyRequest<{ Body: UpdateUserBody }>, reply: FastifyReply) {
- try {
- const { id, name, password, role } = request.body
- try {
- await this.userService.findById(id)
- } catch (error) {
- return reply.code(404).send({ message: '用户不存在' })
- }
- if (name) {
- const existingUser = await this.userService.findByName(name)
- if (existingUser && existingUser.id !== id) {
- return reply.code(400).send({ message: '用户名已存在' })
- }
- }
- const updatedUser = await this.userService.updateUser(id, { name, password, role })
- return reply.send({
- user: {
- id: updatedUser.id,
- name: updatedUser.name,
- role: updatedUser.role,
- createdAt: updatedUser.createdAt,
- updatedAt: updatedUser.updatedAt
- }
- })
- } catch (error) {
- return reply.code(500).send({ message: '更新用户失败' })
- }
- }
- async getChildApiUsers(request: FastifyRequest<{ Querystring: { parentId?: number } }>, reply: FastifyReply) {
- try {
- const parentId = request.query.parentId || request.user.id
- const childUsers = await this.userService.findChildChannelUsers(parentId)
- return reply.send({
- users: childUsers
- })
- } catch (error) {
- return reply.code(500).send({ message: '获取子用户失败' })
- }
- }
- /**
- * 用户登出
- * 使当前token失效
- */
- async logout(request: FastifyRequest, reply: FastifyReply) {
- try {
- // 使当前用户的所有token失效(包括当前token)
- await this.tokenManagerService.invalidateUserTokens(request.user.id)
-
- return reply.send({
- message: '登出成功,所有设备已下线'
- })
- } catch (error) {
- return reply.code(500).send({ message: '登出失败' })
- }
- }
- }
|