| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- import dayjs from 'dayjs';
- import { isEnv } from '../config/config.default.js';
- import { Log, User } from '../model/index.js';
- import { getTokenFu } from '../middleware/jwt.js';
- import { passWordJia, passWordJie } from '../util/pass.js';
- import resSend from '../util/resSend.js';
- import { generateCaptcha, ipLocResFu } from '../util/index.js';
- // 登录模块 需要做定时器处理,防止短时间多次发送
- let loginFlag: any = {};
- export const clearLoginCode = () => {
- loginFlag = {};
- };
- const loginTimeFu = (key: string) => {
- if (loginFlag[key].loginFlagTime === 0) loginFlag[key].loginFlagTime = Date.now();
- const nowTime = Date.now();
- if (nowTime - loginFlag[key].loginFlagTime <= 60000) loginFlag[key].loginFlagNum++;
- };
- const user = {
- getCode: async (req: any, res: any) => {
- req.apiDescription = '用户模块-获取验证码';
- const clientIp = ipLocResFu(req);
- const captcha = generateCaptcha();
- // 将验证码文本存入session(小写以便不区分大小写校验)
- const captchaTxt = captcha.text.toLowerCase();
- if (loginFlag[clientIp]) loginFlag[clientIp].loginFlagCode = captchaTxt;
- else loginFlag[clientIp] = { loginFlagCode: captchaTxt };
- // console.log('生成的验证码(开发调试用):', captchaTxt); // 调试时可查看
- // 设置响应头,告诉浏览器这是SVG图片
- res.type('svg');
- res.send(captcha.data);
- },
- login: async (req: any, res: any) => {
- req.apiDescription = '用户模块-用户登录';
- const clientIp = ipLocResFu(req);
- if (!loginFlag[clientIp]) {
- loginFlag[clientIp] = {
- loginFlagNum: 0,
- loginFlagTime: 0,
- loginFlagRef: null,
- loginFlagCode: '',
- };
- }
- if (loginFlag[clientIp].loginFlagNum >= 5) {
- if (loginFlag[clientIp].loginFlagRef) clearTimeout(loginFlag[clientIp].loginFlagRef);
- loginFlag[clientIp].loginFlagRef = setTimeout(() => {
- loginFlag[clientIp].loginFlagNum = 0;
- loginFlag[clientIp].loginFlagTime = 0;
- loginFlag[clientIp].loginFlagRef = null;
- }, 60 * 1 * 1000);
- return resSend(res, 500, '请稍后重试');
- } else {
- const codeTxt = req.body.code.toLowerCase();
- if (loginFlag[clientIp].loginFlagCode === codeTxt || (isEnv && codeTxt === '1111')) {
- const dbUser = await User.findOne({
- userName: req.body.userName,
- }).select('+passWord');
- if (dbUser && dbUser._id) {
- const pass1 = passWordJie(dbUser.passWord);
- const pass2 = passWordJie(req.body.passWord);
- if (pass1 === pass2) {
- loginFlag[clientIp].loginFlagCode = '';
- loginFlag[clientIp].loginFlagNum = 0;
- loginFlag[clientIp].loginFlagTime = 0;
- delete loginFlag[clientIp];
- const dbUserJson: any = dbUser.toObject();
- delete dbUserJson.passWord;
- // 获取token
- const token = await getTokenFu(dbUserJson);
- // 登录模块记录日志,由于没有token,需要特殊处理
- req.userName = dbUserJson.userName;
- return resSend(res, 0, '登录成功', { user: dbUserJson, token });
- } else {
- loginTimeFu(clientIp);
- return resSend(res, 400, '密码错误');
- }
- } else {
- loginTimeFu(clientIp);
- return resSend(res, 400, '用户名错误');
- }
- } else {
- loginTimeFu(clientIp);
- return resSend(res, 400, '验证码错误');
- }
- }
- },
- loginText: async (req: any, res: any) => {
- req.apiDescription = '用户模块-用户登录调试';
- const dbUser = await User.findOne({
- userName: req.body.userName,
- });
- if (dbUser && dbUser._id) {
- const dbUserJson: any = dbUser.toJSON();
- // 获取token
- const token = await getTokenFu(dbUserJson);
- return resSend(res, 0, '获取token成功', { token });
- } else {
- return resSend(res, 400, '用户名错误');
- }
- },
- addOrEdit: async (req: any, res: any) => {
- // console.log('xxxxxqqqxxx', JSON.stringify(req.body));
- // 拿到参数模型
- if (req.body._id) {
- // 编辑用户
- // 检查用户是否存在
- const existingUser: any = await User.findById(req.body._id);
- if (!existingUser) return resSend(res, 404, '用户不存在');
- // 更新字段
- // 过滤一些字段
- const filetStr = ['userName', 'passWord'];
- Object.keys(req.body).forEach((key) => {
- if (key !== '_id' && req.body[key] !== undefined) {
- if (!filetStr.includes(key)) {
- existingUser[key] = req.body[key];
- }
- }
- });
- existingUser.updateTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
- const updatedUser = await existingUser.save();
- const userObj = updatedUser.toObject();
- delete userObj.passWord;
- req.apiDescription = `用户模块-编辑用户-${userObj.userName}`;
- return resSend(res, 0, '编辑用户成功', userObj);
- } else {
- const infoModel = new User({ ...req.body, passWord: passWordJia('Aa147852') });
- // 新增用户
- // 判断用户名是否已经存在
- const dbUser = await User.findOne({ userName: req.body.userName });
- if (dbUser && dbUser._id) {
- return resSend(res, 400, '用户名已存在');
- } else {
- infoModel.createTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
- infoModel.updateTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
- // 保存数据到数据库
- const dbBack = await infoModel.save();
- // 将文档转换为普通对象并删除密码字段
- const userObj = dbBack.toObject();
- req.apiDescription = `用户模块-新增用户-${userObj.userName}`;
- delete userObj.passWord;
- return resSend(res, 0, '新增用户成功', userObj);
- }
- }
- },
- list: async (req: any, res: any) => {
- req.apiDescription = '用户模块-获取用户列表';
- // 拿到参数模型
- // const userModel = new User(req.body);
- const { pageNum = 1, pageSize = 10, searchKey = '' } = req.body;
- // 构建查询条件
- const query: any = {};
- if (searchKey) {
- // 使用正则表达式实现模糊查询,'i'表示不区分大小写
- query.userName = { $regex: searchKey, $options: 'i' };
- }
- // 计算跳过的文档数量
- const skip = (pageNum - 1) * pageSize;
- // 并行执行:获取总条数和查询当前页数据
- const [total, data] = await Promise.all([
- // 获取满足条件的总记录数
- User.countDocuments(query),
- // 查询当前页数据
- User.find(query).skip(skip).limit(parseInt(pageSize)).sort({ createdAt: -1 }), // 按创建时间倒序
- ]);
- // 计算总页数
- const totalPages = Math.ceil(total / pageSize);
- return resSend(res, 0, '获取用户列表成功', {
- list: data,
- pageNum: parseInt(pageNum),
- pageSize: parseInt(pageSize),
- total,
- totalPages,
- });
- },
- log: async (req: any, res: any) => {
- req.apiDescription = '用户模块-获取操作日志';
- // 拿到参数模型
- // const userModel = new User(req.body);
- const { pageNum = 1, pageSize = 10, searchKey = '', startTime = '', endTime = '' } = req.body;
- // 构建查询条件
- const query: any = {};
- // 1. 处理模糊搜索条件
- if (searchKey) {
- query.userName = { $regex: searchKey, $options: 'i' }; // 'i'表示不区分大小写
- }
- // 2. 处理时间范围条件
- if (startTime && endTime) {
- query.createTime = {
- $gte: startTime,
- $lte: endTime,
- };
- }
- // 计算跳过的文档数量
- const skip = (pageNum - 1) * pageSize;
- // 并行执行:获取总条数和查询当前页数据
- const [total, data] = await Promise.all([
- // 获取满足条件的总记录数
- Log.countDocuments(query),
- // 查询当前页数据,按时间倒序排列
- Log.find(query).sort({ createTime: -1 }).skip(skip).limit(parseInt(pageSize)),
- ]);
- // 计算总页数
- const totalPages = Math.ceil(total / pageSize);
- return resSend(res, 0, '获取日志列表成功', {
- list: data,
- pageNum: parseInt(pageNum),
- pageSize: parseInt(pageSize),
- total,
- totalPages,
- });
- },
- resetPassWord: async (req: any, res: any) => {
- const _id = req.params._id;
- if (_id) {
- const resPassWord = passWordJia('Aa147852');
- const filter = { _id };
- const update = {
- $set: {
- passWord: resPassWord,
- updateTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
- },
- };
- const result = await User.findOneAndUpdate(filter, update);
- if (result) {
- req.apiDescription = `用户模块-重置密码-${result.userName}`;
- return resSend(res, 0, '重置密码成功');
- } else return resSend(res, 404, '未找到对应用户或密码未变更');
- } else return resSend(res, 400, '用户_id不能为空');
- },
- editPassWord: async (req: any, res: any) => {
- req.apiDescription = `用户模块-修改自己的密码`;
- const dbUser = await User.findOne({
- userName: req.user.userName,
- }).select('+passWord');
- const { oldPassword, newPassword } = req.body;
- const oldPassRes = passWordJie(oldPassword);
- const pass1 = passWordJie(dbUser!.passWord);
- if (oldPassRes === pass1) {
- const filter = { userName: req.user.userName };
- const update = {
- $set: {
- passWord: newPassword,
- updateTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
- },
- };
- const result = await User.updateOne(filter, update);
- if (result.modifiedCount === 1) return resSend(res, 0, '修改密码成功');
- else return resSend(res, 404, '未找到对应用户或密码未变更');
- } else return resSend(res, 400, '旧密码错误');
- },
- del: async (req: any, res: any) => {
- const { _id } = req.params; // 从URL参数中获取用户ID
- // 1. 根据ID查找用户
- const user = await User.findById(_id);
- if (!user) return resSend(res, 404, '用户不存在');
- if (user.isAdmin === 1) return resSend(res, 500, '管理员无法删除');
- const deletedUser: any = await User.findByIdAndDelete(_id);
- req.apiDescription = `用户模块-删除用户-${deletedUser.userName}`;
- return resSend(res, 0, '删除用户成功');
- },
- setAuthority: async (req: any, res: any) => {
- const { _id, authorityIds } = req.body;
- if (!_id) return resSend(res, 400, '_id不能为空');
- let authorityIdsRes: any[] = authorityIds || [];
- authorityIdsRes = authorityIdsRes.map((v) => Number(v));
- if (!authorityIdsRes.length) return resSend(res, 400, '权限数组不能为空');
- const updatedUser = await User.findByIdAndUpdate(
- _id, // 用户ID
- {
- authorityIds: authorityIdsRes,
- updateTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
- }, // 要更新的字段
- {
- new: true, // 返回更新后的文档
- runValidators: true, // 确保更新操作也运行Schema级别的验证
- }
- );
- if (!updatedUser) return resSend(res, 404, '未找到该用户');
- req.apiDescription = `用户模块-修改用户页面权限-${updatedUser.userName}`;
- return resSend(res, 0, '用户权限更新成功');
- },
- getInfo: async (req: any, res: any) => {
- const { _id } = req.params;
- if (!_id) return resSend(res, 400, '_id不能为空');
- // 根据ID查询用户信息
- const user = await User.findById(_id);
- if (!user) {
- return resSend(res, 404, '未找到该用户');
- }
- req.apiDescription = `用户模块-获取用户详情-${user.userName}`;
- return resSend(res, 0, '获取用户详情成功', user);
- },
- };
- export default user;
|