const express = require('express') const bcrypt = require('bcryptjs') const Joi = require('joi') const router = express.Router() // 引入数据库模型 const { Admin } = require('../models') const sequelize = require('sequelize') /** * @swagger * components: * schemas: * User: * type: object * properties: * id: * type: integer * description: 用户ID * username: * type: string * description: 用户名 * email: * type: string * format: email * description: 邮箱 * phone: * type: string * description: 手机号 * user_type: * type: string * enum: [admin, buyer, supplier, trader] * description: 用户类型 * status: * type: string * enum: [active, inactive, suspended] * description: 用户状态 * createdAt: * type: string * format: date-time * description: 创建时间 * updatedAt: * type: string * format: date-time * description: 更新时间 * CreateUserRequest: * type: object * required: * - username * - email * - password * - user_type * properties: * username: * type: string * description: 用户名 * email: * type: string * format: email * description: 邮箱 * phone: * type: string * description: 手机号 * password: * type: string * description: 密码 * user_type: * type: string * enum: [admin, buyer, supplier, trader] * description: 用户类型 * status: * type: string * enum: [active, inactive, suspended] * description: 用户状态 * UpdateUserRequest: * type: object * properties: * username: * type: string * description: 用户名 * email: * type: string * format: email * description: 邮箱 * phone: * type: string * description: 手机号 * user_type: * type: string * enum: [admin, buyer, supplier, trader] * description: 用户类型 * status: * type: string * enum: [active, inactive, suspended] * description: 用户状态 */ // 验证模式 const createUserSchema = Joi.object({ username: Joi.string().min(2).max(50).required(), email: Joi.string().email().required(), phone: Joi.string().pattern(/^1[3-9]\d{9}$/).allow(''), password: Joi.string().min(6).max(100).required(), user_type: Joi.string().valid('admin', 'buyer', 'supplier', 'trader').required(), status: Joi.string().valid('active', 'inactive', 'suspended').default('active') }) const updateUserSchema = Joi.object({ username: Joi.string().min(2).max(50), email: Joi.string().email(), phone: Joi.string().pattern(/^1[3-9]\d{9}$/).allow(''), user_type: Joi.string().valid('admin', 'buyer', 'supplier', 'trader'), status: Joi.string().valid('active', 'inactive', 'suspended') }) /** * @swagger * /api/users: * get: * summary: 获取用户列表 * tags: [用户管理] * security: * - bearerAuth: [] * parameters: * - in: query * name: page * schema: * type: integer * description: 页码,默认为1 * - in: query * name: pageSize * schema: * type: integer * description: 每页条数,默认为20 * - in: query * name: keyword * schema: * type: string * description: 关键词搜索(用户名、邮箱、手机号) * - in: query * name: user_type * schema: * type: string * description: 用户类型筛选 * - in: query * name: status * schema: * type: string * description: 用户状态筛选 * responses: * 200: * description: 获取成功 * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * data: * type: object * properties: * items: * type: array * items: * $ref: '#/components/schemas/User' * total: * type: integer * page: * type: integer * pageSize: * type: integer * totalPages: * type: integer * 401: * description: 未授权 * 500: * description: 服务器内部错误 */ // 获取用户列表 router.get('/', async (req, res) => { try { const { page = 1, pageSize = 20, keyword, user_type, status } = req.query // 构建查询条件 const where = {} if (keyword) { where[sequelize.Op.or] = [ { username: { [sequelize.Op.like]: `%${keyword}%` } }, { email: { [sequelize.Op.like]: `%${keyword}%` } }, { phone: { [sequelize.Op.like]: `%${keyword}%` } } ] } if (user_type) where.user_type = user_type if (status) where.status = status // 分页查询 const result = await Admin.findAndCountAll({ where, limit: parseInt(pageSize), offset: (parseInt(page) - 1) * parseInt(pageSize), order: [['createdAt', 'DESC']] }) res.json({ success: true, data: { items: result.rows, total: result.count, page: parseInt(page), pageSize: parseInt(pageSize), totalPages: Math.ceil(result.count / parseInt(pageSize)) } }) } catch (error) { console.error('获取用户列表失败:', error) res.status(500).json({ success: false, message: '获取用户列表失败' }) } }) /** * @swagger * /api/users/{id}: * get: * summary: 获取用户详情 * tags: [用户管理] * security: * - bearerAuth: [] * parameters: * - in: path * name: id * schema: * type: integer * required: true * description: 用户ID * responses: * 200: * description: 获取成功 * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * data: * $ref: '#/components/schemas/User' * 401: * description: 未授权 * 404: * description: 用户不存在 * 500: * description: 服务器内部错误 */ // 获取用户详情 router.get('/:id', async (req, res) => { try { const { id } = req.params const user = await Admin.findByPk(id) if (!user) { return res.status(404).json({ success: false, message: '用户不存在' }) } res.json({ success: true, data: user }) } catch (error) { console.error('获取用户详情失败:', error) res.status(500).json({ success: false, message: '获取用户详情失败' }) } }) /** * @swagger * /api/users: * post: * summary: 创建新用户 * tags: [用户管理] * security: * - bearerAuth: [] * requestBody: * required: true * content: * application/json: * schema: * $ref: '#/components/schemas/CreateUserRequest' * responses: * 201: * description: 创建成功 * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * message: * type: string * data: * $ref: '#/components/schemas/User' * 400: * description: 参数验证失败 * 401: * description: 未授权 * 500: * description: 服务器内部错误 */ // 创建新用户 router.post('/', async (req, res) => { try { const { error, value } = createUserSchema.validate(req.body) if (error) { return res.status(400).json({ success: false, message: '参数验证失败', details: error.details[0].message }) } const { username, email, phone, password, user_type, status } = value // 检查用户名、邮箱是否已存在 const existingUser = await Admin.findOne({ where: { [sequelize.Op.or]: [ { username }, { email } ] } }) if (existingUser) { return res.status(400).json({ success: false, message: '用户名或邮箱已被使用' }) } // 密码加密 const hashedPassword = await bcrypt.hash(password, 10) // 创建用户 const user = await Admin.create({ username, email, phone, password_hash: hashedPassword, user_type, status }) // 移除密码哈希,避免返回敏感信息 const userData = user.toJSON() delete userData.password_hash res.status(201).json({ success: true, message: '用户创建成功', data: userData }) } catch (error) { console.error('创建用户失败:', error) res.status(500).json({ success: false, message: '创建用户失败' }) } }) /** * @swagger * /api/users/{id}: * put: * summary: 更新用户信息 * tags: [用户管理] * security: * - bearerAuth: [] * parameters: * - in: path * name: id * schema: * type: integer * required: true * description: 用户ID * requestBody: * required: true * content: * application/json: * schema: * $ref: '#/components/schemas/UpdateUserRequest' * responses: * 200: * description: 更新成功 * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * message: * type: string * data: * $ref: '#/components/schemas/User' * 400: * description: 参数验证失败 * 401: * description: 未授权 * 404: * description: 用户不存在 * 500: * description: 服务器内部错误 */ // 更新用户信息 router.put('/:id', async (req, res) => { try { const { id } = req.params const { error, value } = updateUserSchema.validate(req.body) if (error) { return res.status(400).json({ success: false, message: '参数验证失败', details: error.details[0].message }) } // 查找用户 const user = await Admin.findByPk(id) if (!user) { return res.status(404).json({ success: false, message: '用户不存在' }) } // 更新用户信息 await user.update(value) res.json({ success: true, message: '用户更新成功', data: user }) } catch (error) { console.error('更新用户失败:', error) res.status(500).json({ success: false, message: '更新用户失败' }) } }) /** * @swagger * /api/users/{id}: * delete: * summary: 删除用户 * tags: [用户管理] * security: * - bearerAuth: [] * parameters: * - in: path * name: id * schema: * type: integer * required: true * description: 用户ID * responses: * 200: * description: 删除成功 * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * message: * type: string * 401: * description: 未授权 * 404: * description: 用户不存在 * 500: * description: 服务器内部错误 */ // 删除用户 router.delete('/:id', async (req, res) => { try { const { id } = req.params const user = await Admin.findByPk(id) if (!user) { return res.status(404).json({ success: false, message: '用户不存在' }) } // 软删除或永久删除 // 如果需要软删除,可以改为更新status为'inactive' await user.destroy() res.json({ success: true, message: '用户删除成功' }) } catch (error) { console.error('删除用户失败:', error) res.status(500).json({ success: false, message: '删除用户失败' }) } }) module.exports = router