From e6adea5f5243a089d9312890a5e6a2f7a324287b Mon Sep 17 00:00:00 2001 From: LingandRX Date: Sun, 5 Jan 2025 00:13:10 +0800 Subject: [PATCH] =?UTF-8?q?refactor(user):=20=E9=87=8D=E6=9E=84=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=A8=A1=E5=9D=97=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 userController、userModel、userRepository 和 userService 文件中的代码进行重新组织和优化 - 使用 import 语句替代 require 引入模块 - 将函数定义从 es5 改为 es6 语法 - 优化了部分函数的实现,提高了代码可读性和维护性 --- controllers/userController.js | 212 +++++++++++++++++---------------- models/userModel.js | 8 +- repositories/userRepository.js | 75 +++++++----- routes/accountRouter.js | 5 +- services/userService.js | 144 +++++++++++----------- 5 files changed, 230 insertions(+), 214 deletions(-) diff --git a/controllers/userController.js b/controllers/userController.js index b19ff3c..ac2dc82 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -6,121 +6,125 @@ import messages from '../config/messages' import { HTTP_STATUS } from '../common/constant/httpStatus' import { SearchQuery } from '../models/search' -export async function getAllUsers(res) { - try { - const users = await userService.getUserList() - return FetchResult.formatResult(res, HTTP_STATUS.ACCEPTED, 'success', users) - } catch (err) { - return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error') - } -} - -export async function findUserList(req, res) { - try { - const { page, size, sort } = req.query - const search = new SearchQuery({ page: page, size: size, sort: sort }) - const result = await userService.getUserList(search) - return FetchResult.formatResult(res, HTTP_STATUS.ACCEPTED, 'success', result) - } catch (err) { - console.log(err) - - return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error') - } -} - -export const createUser = [ - body('account').isLength({ min: 3 }).withMessage('Account must be at least 3 characters long'), - body('account').isEmpty().withMessage('Account is required'), - body('password').isLength({ min: 6 }).withMessage('Password must be at least 6 characters long'), - body('password').isEmpty().withMessage('Password is required'), - async (req, res, next) => { - const errors = validationResult(req) - if (!errors.isEmpty()) { - return FetchResult.formatResult( - res, - HTTP_STATUS.BAD_REQUEST, - errors - .array() - .map((err) => err.msg) - .join(', ') - ) - } - - next() - }, - async (req, res) => { +export default UserController = { + async getAllUsers(res) { try { - const user = req.body - await userService.createUser(user) - return FetchResult.formatResult(res, HTTP_STATUS.CREATED, messages.user.created) + const users = await userService.getUserList() + return FetchResult.formatResult(res, HTTP_STATUS.ACCEPTED, 'success', users) } catch (err) { - logger('Error creating user: ', err) - if (err.message === messages.user.alreadyExists) { - return FetchResult.formatResult(res, HTTP_STATUS.CONFLICT, messages.user.alreadyExists) - } return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error') } - } -] - -export const login = [ - body('account').notEmpty().withMessage('Account is required'), - body('password').notEmpty().withMessage('Password is required'), - async (req, res, next) => { - const errors = validationResult(req) - if (!errors.isEmpty()) { - console.log(errors) - return FetchResult.formatResult( - res, - 400, - errors - .array() - .map((err) => err.msg) - .join(', ') - ) - } - - next() }, - async (req, res) => { - try { - const { account, password } = req.body - req.session.user = await userService.login(account, password) - return FetchResult.formatResult(res, HTTP_STATUS.ACCEPTED, messages.user.login) - } catch (err) { - if (err.message === messages.user.not_found) { - return FetchResult.formatResult(res, HTTP_STATUS.NOT_FOUND, messages.user.accountPasswordNotMatch) - } - logger('Error logging in: ', err) + async findUserList(req, res) { + try { + const { page, size, sort } = req.query + const search = new SearchQuery({ page: page, size: size, sort: sort }) + const result = await userService.getUserList(search) + return FetchResult.formatResult(res, HTTP_STATUS.ACCEPTED, 'success', result) + } catch (err) { + console.log(err) return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error') } - } -] + }, -export async function logout(req, res) { - try { - req.session.destroy() - return FetchResult.formatResult(res, HTTP_STATUS.OK, messages.user.logout) - } catch (err) { - logger('Error logging out: ', err) - return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error') - } -} + createUser: [ + body('account').isLength({ min: 3 }).withMessage('Account must be at least 3 characters long'), + body('account').isEmpty().withMessage('Account is required'), + body('password').isLength({ min: 6 }).withMessage('Password must be at least 6 characters long'), + body('password').isEmpty().withMessage('Password is required'), + async (req, res, next) => { + const errors = validationResult(req) + if (!errors.isEmpty()) { + return FetchResult.formatResult( + res, + HTTP_STATUS.BAD_REQUEST, + errors + .array() + .map((err) => err.msg) + .join(', ') + ) + } -export async function getUserExists(req, res) { - try { - const { account } = req.query - - const exist = await userService.getUserExists(account) - - if (!exist) { - return FetchResult.formatResult(res, HTTP_STATUS.NOT_FOUND, messages.user.not_found) + next() + }, + async (req, res) => { + try { + const user = req.body + await userService.createUser(user) + return FetchResult.formatResult(res, HTTP_STATUS.CREATED, messages.user.created) + } catch (err) { + logger('Error creating user: ', err) + if (err.message === messages.user.alreadyExists) { + return FetchResult.formatResult(res, HTTP_STATUS.CONFLICT, messages.user.alreadyExists) + } + return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error') + } + } + ], + + login: [ + body('account').notEmpty().withMessage('Account is required'), + body('password').notEmpty().withMessage('Password is required'), + async (req, res, next) => { + const errors = validationResult(req) + if (!errors.isEmpty()) { + console.log(errors) + return FetchResult.formatResult( + res, + 400, + errors + .array() + .map((err) => err.msg) + .join(', ') + ) + } + + next() + }, + async (req, res) => { + try { + const { account, password } = req.body + req.session.user = await userService.login(account, password) + return FetchResult.formatResult(res, HTTP_STATUS.ACCEPTED, messages.user.login) + } catch (err) { + if (err.message === messages.user.not_found) { + return FetchResult.formatResult(res, HTTP_STATUS.NOT_FOUND, messages.user.accountPasswordNotMatch) + } + + logger('Error logging in: ', err) + + return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error') + } + } + ], + + logout: [ + async (req, res) => { + try { + req.session.destroy() + return FetchResult.formatResult(res, HTTP_STATUS.OK, messages.user.logout) + } catch (err) { + logger('Error logging out: ', err) + return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error') + } + } + ], + + async getUserExists(req, res) { + try { + const { account } = req.query + + const exist = await userService.getUserExists(account) + + if (!exist) { + return FetchResult.formatResult(res, HTTP_STATUS.NOT_FOUND, messages.user.not_found) + } + return FetchResult.formatResult(res, HTTP_STATUS.ACCEPTED, messages.user.exists) + } catch (err) { + logger('Error checking user existence: ', err) + return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error') } - return FetchResult.formatResult(res, HTTP_STATUS.ACCEPTED, messages.user.exists) - } catch (err) { - logger('Error checking user existence: ', err) - return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error') } } diff --git a/models/userModel.js b/models/userModel.js index 75aee0b..cd9fdea 100644 --- a/models/userModel.js +++ b/models/userModel.js @@ -1,6 +1,6 @@ -const mongoose = require('mongoose') -const { hashPassword } = require('../utils/hashUtils') -const Schema = mongoose.Schema +import { Schema as _Schema, model } from 'mongoose' +import { hashPassword } from '../utils/hashUtils' +const Schema = _Schema const UserSchema = new Schema({ name: { type: String, required: true, maxlength: 100 }, @@ -29,4 +29,4 @@ UserSchema.pre('save', async function (next) { } }) -module.exports = mongoose.model('User', UserSchema) +export default model('User', UserSchema) diff --git a/repositories/userRepository.js b/repositories/userRepository.js index 6d5782d..3d0d084 100644 --- a/repositories/userRepository.js +++ b/repositories/userRepository.js @@ -1,25 +1,36 @@ -const UserModel = require('../models/userModel') -const { SearchResult } = require('../models/search') +import { + startSession, + find, + aggregate, + findById, + findOne, + exists, + create, + findByIdAndUpdate, + findByIdAndDelete, + deleteMany +} from '../models/userModel' +import { SearchResult } from '../models/search' -exports.startTransaction = async () => { - const session = await UserModel.startSession() +export async function startTransaction() { + const session = await startSession() session.startTransaction() return session } -exports.commitTransaction = async (session) => { +export async function commitTransaction(session) { return session.commitTransaction() } -exports.rollbackTransaction = async (session) => { +export async function rollbackTransaction(session) { return session.abortTransaction() } -exports.selectAllUser = async () => { - return UserModel.find() +export async function selectAllUser() { + return find() } -exports.selectUserList = async (search = {}) => { +export async function selectUserList(search = {}) { try { const { size = 20, page = 1, sort, filters } = search @@ -32,7 +43,7 @@ exports.selectUserList = async (search = {}) => { const matchFilters = filters ? { ...filters } : {} const sortObj = sort && typeof sort === 'object' ? sort : { _id: 1 } // 默认按 _id 升序排序 - const result = await UserModel.aggregate([ + const result = await aggregate([ // 应用过滤条件,确保filters存在时才传入 { $match: matchFilters }, { @@ -57,47 +68,47 @@ exports.selectUserList = async (search = {}) => { } } -exports.selectUserById = async (id) => { - return UserModel.findById(id) +export async function selectUserById(id) { + return findById(id) } -exports.selectUserByAccount = async (account) => { - return UserModel.findOne({ account: account }) +export async function selectUserByAccount(account) { + return findOne({ account: account }) } -exports.selectUserByEmail = async (email) => { - return UserModel.findOne({ email: email }) +export async function selectUserByEmail(email) { + return findOne({ email: email }) } -exports.selectUserByUsername = async (username) => { - return UserModel.findOne({ username: username }) +export async function selectUserByUsername(username) { + return findOne({ username: username }) } -exports.selectUserByPhone = async (phone) => { - return UserModel.findOne({ phone: phone }) +export async function selectUserByPhone(phone) { + return findOne({ phone: phone }) } -exports.selectUserByAccountExist = async (account) => { - const exist = await UserModel.exists({ account: account }) +export async function selectUserByAccountExist(account) { + const exist = await exists({ account: account }) return exist !== null } -exports.createUser = async (user) => { - return UserModel.create(user) +export async function createUser(user) { + return create(user) } -exports.updateUserById = async (id, user) => { - return UserModel.findByIdAndUpdate(id, user) +export async function updateUserById(id, user) { + return findByIdAndUpdate(id, user) } -exports.updateUserByLoginDate = async (id, loginDate) => { - return UserModel.findByIdAndUpdate(id, { last_login_date: loginDate }) +export async function updateUserByLoginDate(id, loginDate) { + return findByIdAndUpdate(id, { last_login_date: loginDate }) } -exports.deleteUserById = async (id) => { - return UserModel.findByIdAndDelete(id) +export async function deleteUserById(id) { + return findByIdAndDelete(id) } -exports.deleteAllUser = async () => { - return UserModel.deleteMany() +export async function deleteAllUser() { + return deleteMany() } diff --git a/routes/accountRouter.js b/routes/accountRouter.js index 27285e1..726d098 100644 --- a/routes/accountRouter.js +++ b/routes/accountRouter.js @@ -1,10 +1,9 @@ // routes/userRoutes.js import express from 'express' - -import userController from '../controllers/userController' +const userController = import('../controllers/userController') const router = express.Router() -router.get('/', userController.getUserExist) +router.get('/', getUserExists) export default router diff --git a/services/userService.js b/services/userService.js index d111894..8bc1f96 100644 --- a/services/userService.js +++ b/services/userService.js @@ -3,80 +3,82 @@ import logger from 'morgan' import messages from '../config/messages' import { comparePassword } from '../utils/hashUtils' -/** - * 用户登录 - * @param {string} account - 用户账号 - * @param {string} password - 用户密码 - * @returns {Promise} - 登录成功返回用户信息 - * @throws {Error} - 如果用户不存在或密码不正确 - */ -export async function login(account, password) { - const user = await userMapper.selectUserByAccount(account) +export default userServeice = { + /** + * 用户登录 + * @param {string} account - 用户账号 + * @param {string} password - 用户密码 + * @returns {Promise} - 登录成功返回用户信息 + * @throws {Error} - 如果用户不存在或密码不正确 + */ + async login(account, password) { + const user = await userMapper.selectUserByAccount(account) - // 用户不存在 - if (!user) { - throw new Error(messages.user.not_found) - } - - // 密码不匹配 - const isMatch = comparePassword(password, user.password) - if (!isMatch) { - throw new Error(messages.user.passwordIncorrect) - } - - // 更新用户的最后登录时间 - user.lastLoginDate = new Date() - await userMapper.updateUserByLoginDate(user.id, user.lastLoginDate) - - return user -} - -/** - * - * @param {string} account - * @returns {Promise} - */ -export async function getUserExists(account) { - return userMapper.selectUserByAccountExist(account) -} - -// Removed the unnecessary try-catch block and simplified the function -export async function getAllUser() { - return await userMapper.selectAllUser() -} - -export async function getUserList(searchQuery) { - return userMapper.selectUserList(searchQuery) -} - -/** - * 创建用户 - * @param {Object} user - 用户对象 - * @returns {Promise} - 创建成功的用户信息 - * @throws {Error} - 如果用户已存在或事务失败 - */ -export async function createUser(user) { - const { account } = user - const session = await userMapper.startTransaction() - - try { - // 检查用户是否已存在 - const existingUser = await userMapper.selectUserByAccount(account) - if (existingUser) { - return new Error(messages.user.alreadyExists) + // 用户不存在 + if (!user) { + throw new Error(messages.user.not_found) } - // 创建新用户 - const result = await userMapper.createUser(user) + // 密码不匹配 + const isMatch = comparePassword(password, user.password) + if (!isMatch) { + throw new Error(messages.user.passwordIncorrect) + } - // 提交事务 - await userMapper.commitTransaction(session) - return result - } catch (err) { - // 回滚事务 - await userMapper.rollbackTransaction(session).catch((rollbackErr) => { - logger('Error rolling back transaction: ', rollbackErr) - }) - throw err // 将错误抛给调用方(Controller 层) + // 更新用户的最后登录时间 + user.lastLoginDate = new Date() + await userMapper.updateUserByLoginDate(user.id, user.lastLoginDate) + + return user + }, + + /** + * + * @param {string} account + * @returns {Promise} + */ + async getUserExists(account) { + return userMapper.selectUserByAccountExist(account) + }, + + // Removed the unnecessary try-catch block and simplified the function + async getAllUser() { + return await userMapper.selectAllUser() + }, + + async getUserList(searchQuery) { + return userMapper.selectUserList(searchQuery) + }, + + /** + * 创建用户 + * @param {Object} user - 用户对象 + * @returns {Promise} - 创建成功的用户信息 + * @throws {Error} - 如果用户已存在或事务失败 + */ + async createUser(user) { + const { account } = user + const session = await userMapper.startTransaction() + + try { + // 检查用户是否已存在 + const existingUser = await userMapper.selectUserByAccount(account) + if (existingUser) { + return new Error(messages.user.alreadyExists) + } + + // 创建新用户 + const result = await userMapper.createUser(user) + + // 提交事务 + await userMapper.commitTransaction(session) + return result + } catch (err) { + // 回滚事务 + await userMapper.rollbackTransaction(session).catch((rollbackErr) => { + logger('Error rolling back transaction: ', rollbackErr) + }) + throw err // 将错误抛给调用方(Controller 层) + } } }