| import Mock from 'mockjs' |
| |
| // 模拟延迟 |
| Mock.setup({ |
| timeout: '300-600' |
| }) |
| |
| // 模拟用户数据 |
| const users = [ |
| { |
| id: 1, |
| username: 'LukasWu', |
| password: '060050bbb', |
| email: '22301102@bjtu.edu.cn', |
| role: 'user', |
| userType: 0, // 普通用户 |
| avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=LukasWu', |
| createTime: '2025-05-13 17:51:08' |
| }, |
| { |
| id: 2, |
| username: 'IcyIron', |
| password: '111111', |
| email: 'icyiron@example.com', |
| role: 'admin', |
| userType: 1, // 管理员 |
| avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=IcyIron', |
| createTime: '2025-05-13 18:00:00' |
| }, |
| { |
| id: 3, |
| username: 'tanzhennan727', |
| password: 'password123', |
| email: 'tanzhennan727@example.com', |
| role: 'user', |
| userType: 0, |
| avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=tanzhennan727', |
| createTime: '2025-05-14 10:00:00' |
| }, |
| { |
| id: 4, |
| username: 'ybt', |
| password: 'ybt123', |
| email: 'ybt@example.com', |
| role: 'user', |
| userType: 0, |
| avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=ybt', |
| createTime: '2025-05-15 14:30:00' |
| } |
| ] |
| |
| // 模拟帖子数据 |
| const posts = [ |
| { |
| id: 1, |
| title: '如何成为云顶高手', |
| content: '向icyiron学习', |
| author: 'LukasWu', |
| createTime: '2025-05-18 16:43:51', |
| views: 256, |
| likes: 57 |
| }, |
| { |
| id: 101, |
| title: '北京交通大学实训心得', |
| content: '实训非常有趣,学到了很多知识', |
| author: 'LukasWu', |
| createTime: '2025-05-17 09:30:00', |
| views: 128, |
| likes: 32 |
| }, |
| { |
| id: 102, |
| title: '前端开发技巧分享', |
| content: 'React和Vue的使用经验总结...', |
| author: 'IcyIron', |
| createTime: '2025-05-16 15:20:00', |
| views: 345, |
| likes: 89 |
| }, |
| { |
| id: 103, |
| title: '后端接口设计规范', |
| content: 'RESTful API设计的最佳实践...', |
| author: 'tanzhennan727', |
| createTime: '2025-05-15 11:10:00', |
| views: 210, |
| likes: 45 |
| }, |
| { |
| id: 104, |
| title: '数据库优化技巧', |
| content: 'MySQL索引优化与查询性能提升...', |
| author: 'ybt', |
| createTime: '2025-05-14 16:40:00', |
| views: 178, |
| likes: 36 |
| }, |
| { |
| id: 105, |
| title: '云顶之弈攻略', |
| content: '最强阵容搭配与装备选择...', |
| author: 'IcyIron', |
| createTime: '2025-05-13 20:15:00', |
| views: 567, |
| likes: 120 |
| } |
| ] |
| |
| // 模拟评论数据 |
| const comments = [ |
| { |
| id: 1001, |
| postId: 105, |
| content: '感谢分享,学到了很多!', |
| author: 'LukasWu', |
| createTime: '2025-05-19 12:30:15' |
| }, |
| { |
| id: 1002, |
| postId: 105, |
| content: '这个阵容我试了,确实很强', |
| author: 'tanzhennan727', |
| createTime: '2025-05-19 14:25:30' |
| }, |
| { |
| id: 1003, |
| postId: 101, |
| content: '实训课程安排得很合理', |
| author: 'ybt', |
| createTime: '2025-05-18 10:15:45' |
| }, |
| { |
| id: 1004, |
| postId: 102, |
| content: 'React Hooks确实好用', |
| author: 'LukasWu', |
| createTime: '2025-05-17 16:40:20' |
| }, |
| { |
| id: 1005, |
| postId: 103, |
| content: '接口文档写得很清晰', |
| author: 'IcyIron', |
| createTime: '2025-05-16 09:35:10' |
| } |
| ] |
| |
| // 生成JWT格式的token |
| const generateToken = (username, userType) => { |
| const header = { alg: 'HS256', typ: 'JWT' }; |
| const payload = { |
| username: username, |
| userType: userType, |
| exp: Math.floor(Date.now() / 1000) + 86400 // 24小时后过期 |
| }; |
| |
| // Base64编码 |
| const encodeBase64 = (obj) => { |
| return btoa(JSON.stringify(obj)).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); |
| }; |
| |
| const headerEncoded = encodeBase64(header); |
| const payloadEncoded = encodeBase64(payload); |
| |
| // 在实际应用中应该使用正确的签名算法,这里简化处理 |
| const signature = encodeBase64(`${username}-${Date.now()}`); |
| |
| return `${headerEncoded}.${payloadEncoded}.${signature}`; |
| }; |
| |
| // 验证token |
| const verifyToken = (token) => { |
| if (!token) return false; |
| |
| try { |
| // 解析token的payload部分 |
| const parts = token.split('.'); |
| if (parts.length !== 3) return false; |
| |
| const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/'))); |
| const now = Math.floor(Date.now() / 1000); |
| |
| // 检查过期时间 |
| if (payload.exp <= now) return false; |
| |
| // 检查用户是否存在 |
| const user = users.find(u => u.username === payload.username); |
| if (!user) return false; |
| |
| return { valid: true, user, userType: payload.userType }; |
| } catch (e) { |
| return false; |
| } |
| }; |
| |
| // 用户信息相关接口 |
| |
| // 1. 用户登录 |
| Mock.mock('/user/login', 'post', (options) => { |
| const body = JSON.parse(options.body); |
| const { username, password } = body; |
| |
| const user = users.find(u => u.username === username && u.password === password); |
| |
| if (user) { |
| const token = generateToken(user.username, user.userType); |
| |
| return { |
| code: 200, |
| message: '登录成功', |
| success: true, |
| data: { |
| token, |
| user: { |
| id: user.id, |
| username: user.username, |
| email: user.email, |
| role: user.role, |
| userType: user.userType, |
| avatar: user.avatar |
| } |
| } |
| }; |
| } else { |
| return { |
| code: 401, |
| message: '用户名或密码错误', |
| success: false |
| }; |
| } |
| }); |
| |
| // 2. 用户注册 |
| Mock.mock('/user/register', 'post', (options) => { |
| const body = JSON.parse(options.body); |
| const { username, password, email } = body; |
| |
| // 检查用户名是否已存在 |
| if (users.some(u => u.username === username)) { |
| return { |
| code: 400, |
| message: '用户名已存在', |
| success: false |
| }; |
| } |
| |
| // 检查邮箱是否已存在 |
| if (users.some(u => u.email === email)) { |
| return { |
| code: 400, |
| message: '邮箱已被注册', |
| success: false |
| }; |
| } |
| |
| // 创建新用户 |
| const newUser = { |
| id: users.length + 1, |
| username, |
| password, |
| email, |
| role: 'user', |
| userType: 0, // 普通用户 |
| avatar: `https://api.dicebear.com/7.x/avataaars/svg?seed=${username}`, |
| createTime: new Date().toISOString().replace('T', ' ').substring(0, 19) |
| }; |
| |
| users.push(newUser); |
| |
| const token = generateToken(newUser.username, newUser.userType); |
| |
| return { |
| code: 200, |
| message: '注册成功', |
| success: true, |
| data: { |
| token, |
| user: { |
| id: newUser.id, |
| username: newUser.username, |
| email: newUser.email, |
| role: newUser.role, |
| userType: newUser.userType, |
| avatar: newUser.avatar |
| } |
| } |
| }; |
| }); |
| |
| // 3. 修改用户名 |
| Mock.mock('/user/update/username', 'post', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid) { |
| return { |
| code: 401, |
| message: '未授权访问', |
| success: false |
| }; |
| } |
| |
| const body = JSON.parse(options.body); |
| const { username, newUsername } = body; |
| |
| // 检查用户名是否存在 |
| const userIndex = users.findIndex(u => u.username === username); |
| if (userIndex === -1) { |
| return { |
| code: 404, |
| message: '用户不存在', |
| success: false |
| }; |
| } |
| |
| // 检查新用户名是否已被使用 |
| if (users.some(u => u.username === newUsername && u.id !== users[userIndex].id)) { |
| return { |
| code: 400, |
| message: '用户名已存在', |
| success: false |
| }; |
| } |
| |
| // 更新用户名 |
| users[userIndex].username = newUsername; |
| users[userIndex].avatar = `https://api.dicebear.com/7.x/avataaars/svg?seed=${newUsername}`; |
| |
| return { |
| code: 200, |
| message: '用户名修改成功', |
| success: true, |
| data: { |
| user: { |
| id: users[userIndex].id, |
| username: users[userIndex].username, |
| email: users[userIndex].email, |
| role: users[userIndex].role, |
| userType: users[userIndex].userType, |
| avatar: users[userIndex].avatar |
| } |
| } |
| }; |
| }); |
| |
| // 4. 修改密码 |
| Mock.mock('/user/update/password', 'post', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid) { |
| return { |
| code: 401, |
| message: '未授权访问', |
| success: false |
| }; |
| } |
| |
| const body = JSON.parse(options.body); |
| const { username, newPassword } = body; |
| |
| // 检查用户名是否存在 |
| const userIndex = users.findIndex(u => u.username === username); |
| if (userIndex === -1) { |
| return { |
| code: 404, |
| message: '用户不存在', |
| success: false |
| }; |
| } |
| |
| // 更新密码 |
| users[userIndex].password = newPassword; |
| |
| return { |
| code: 200, |
| message: '密码修改成功', |
| success: true |
| }; |
| }); |
| |
| // 5. 修改邮箱 |
| Mock.mock('/user/update/email', 'post', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid) { |
| return { |
| code: 401, |
| message: '未授权访问', |
| success: false |
| }; |
| } |
| |
| const body = JSON.parse(options.body); |
| const { username, newEmail } = body; |
| |
| // 检查用户名是否存在 |
| const userIndex = users.findIndex(u => u.username === username); |
| if (userIndex === -1) { |
| return { |
| code: 404, |
| message: '用户不存在', |
| success: false |
| }; |
| } |
| |
| // 检查邮箱是否已被使用 |
| if (users.some(u => u.email === newEmail && u.id !== users[userIndex].id)) { |
| return { |
| code: 400, |
| message: '邮箱已被注册', |
| success: false |
| }; |
| } |
| |
| // 更新邮箱 |
| users[userIndex].email = newEmail; |
| |
| return { |
| code: 200, |
| message: '邮箱修改成功', |
| success: true, |
| data: { |
| user: { |
| id: users[userIndex].id, |
| username: users[userIndex].username, |
| email: users[userIndex].email, |
| role: users[userIndex].role, |
| userType: users[userIndex].userType, |
| avatar: users[userIndex].avatar |
| } |
| } |
| }; |
| }); |
| |
| // 6. 获取用户信息 |
| Mock.mock(new RegExp('/user/get/info\\?username=.+'), 'get', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid) { |
| return { |
| code: 401, |
| message: '未授权访问', |
| success: false |
| }; |
| } |
| |
| const url = options.url; |
| const username = url.split('username=')[1]; |
| |
| const user = users.find(u => u.username === username); |
| if (!user) { |
| return { |
| code: 404, |
| message: '用户不存在', |
| success: false |
| }; |
| } |
| |
| return { |
| code: 200, |
| message: '获取用户信息成功', |
| success: true, |
| data: { |
| user: { |
| id: user.id, |
| username: user.username, |
| email: user.email, |
| role: user.role, |
| userType: user.userType, |
| avatar: user.avatar, |
| createTime: user.createTime |
| } |
| } |
| }; |
| }); |
| |
| // 帖子相关接口 |
| |
| // 7. 新建帖子 |
| Mock.mock('/posts/create', 'post', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid) { |
| return { |
| code: 401, |
| message: '未授权访问', |
| success: false |
| }; |
| } |
| |
| const body = JSON.parse(options.body); |
| const { title, content, author } = body; |
| |
| // 生成新帖子ID |
| const id = posts.length > 0 ? Math.max(...posts.map(p => p.id)) + 1 : 1; |
| |
| const newPost = { |
| id, |
| title, |
| content, |
| author, |
| createTime: new Date().toISOString().replace('T', ' ').substring(0, 19), |
| views: 0, |
| likes: 0 |
| }; |
| |
| posts.push(newPost); |
| |
| return { |
| code: 200, |
| message: '帖子发布成功', |
| success: true, |
| data: { post: newPost } |
| }; |
| }); |
| |
| // 8. 查询帖子 |
| Mock.mock(new RegExp('/posts/list\\?.*'), 'get', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid) { |
| return { |
| code: 401, |
| message: '未授权访问', |
| success: false |
| }; |
| } |
| |
| const url = options.url; |
| const params = new URLSearchParams(url.split('?')[1]); |
| |
| const username = params.get('username'); |
| const title = params.get('title'); |
| const author = params.get('author'); |
| const date = params.get('date'); |
| |
| // 过滤帖子 |
| let filteredPosts = [...posts]; |
| |
| if (title) { |
| filteredPosts = filteredPosts.filter(p => p.title.includes(title)); |
| } |
| |
| if (author) { |
| filteredPosts = filteredPosts.filter(p => p.author.includes(author)); |
| } |
| |
| if (date) { |
| filteredPosts = filteredPosts.filter(p => p.createTime.startsWith(date)); |
| } |
| |
| return { |
| code: 200, |
| message: '查询帖子成功', |
| success: true, |
| data: { |
| total: filteredPosts.length, |
| posts: filteredPosts |
| } |
| }; |
| }); |
| |
| // 评论相关接口 |
| |
| // 9. 获取帖子评论 |
| Mock.mock(new RegExp('/comment/get\\?.*'), 'get', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid) { |
| return { |
| code: 401, |
| message: '未授权访问', |
| success: false |
| }; |
| } |
| |
| const url = options.url; |
| const params = new URLSearchParams(url.split('?')[1]); |
| |
| const postId = params.get('postId'); |
| |
| if (!postId) { |
| return { |
| code: 400, |
| message: '参数错误', |
| success: false |
| }; |
| } |
| |
| // 查找帖子 |
| const post = posts.find(p => p.id === parseInt(postId)); |
| if (!post) { |
| return { |
| code: 404, |
| message: '帖子不存在', |
| success: false |
| }; |
| } |
| |
| // 获取帖子的评论 |
| const postComments = comments.filter(c => c.postId === parseInt(postId)); |
| |
| return { |
| code: 200, |
| message: '获取评论成功', |
| success: true, |
| data: { |
| total: postComments.length, |
| comments: postComments |
| } |
| }; |
| }); |
| |
| // 10. 发布帖子评论 |
| Mock.mock('/comment/add', 'post', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid) { |
| return { |
| code: 401, |
| message: '未授权访问', |
| success: false |
| }; |
| } |
| |
| const body = JSON.parse(options.body); |
| const { content, username, postId } = body; |
| |
| // 检查帖子是否存在 |
| const post = posts.find(p => p.id === parseInt(postId)); |
| if (!post) { |
| return { |
| code: 404, |
| message: '帖子不存在', |
| success: false |
| }; |
| } |
| |
| // 检查用户是否存在 |
| const user = users.find(u => u.username === username); |
| if (!user) { |
| return { |
| code: 404, |
| message: '用户不存在', |
| success: false |
| }; |
| } |
| |
| // 生成评论ID |
| const id = comments.length > 0 ? Math.max(...comments.map(c => c.id)) + 1 : 1001; |
| |
| const newComment = { |
| id, |
| postId: parseInt(postId), |
| content, |
| author: username, |
| createTime: new Date().toISOString().replace('T', ' ').substring(0, 19) |
| }; |
| |
| comments.push(newComment); |
| |
| return { |
| code: 200, |
| message: '评论发布成功', |
| success: true, |
| data: { comment: newComment } |
| }; |
| }); |
| |
| // 管理员相关接口 |
| |
| // 11. 管理员登录 |
| Mock.mock('/admin/login', 'post', (options) => { |
| const body = JSON.parse(options.body); |
| const { username, password } = body; |
| |
| // 查找管理员用户 |
| const admin = users.find(u => u.username === username && u.password === password && u.userType === 1); |
| |
| if (admin) { |
| const token = generateToken(admin.username, admin.userType); |
| |
| return { |
| code: 200, |
| message: '管理员登录成功', |
| success: true, |
| data: { |
| token, |
| user: { |
| id: admin.id, |
| username: admin.username, |
| email: admin.email, |
| role: admin.role, |
| userType: admin.userType, |
| avatar: admin.avatar |
| } |
| } |
| }; |
| } else { |
| return { |
| code: 401, |
| message: '用户名或密码错误,或无管理员权限', |
| success: false |
| }; |
| } |
| }); |
| |
| // 12. 获取用户列表 (管理员) |
| Mock.mock(new RegExp('/user/list\\?.*'), 'get', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid || auth.userType !== 1) { |
| return { |
| code: 403, |
| message: '无权限访问', |
| success: false |
| }; |
| } |
| |
| // 返回除密码外的用户信息 |
| const userList = users.map(user => ({ |
| id: user.id, |
| username: user.username, |
| email: user.email, |
| role: user.role, |
| userType: user.userType, |
| avatar: user.avatar, |
| createTime: user.createTime |
| })); |
| |
| return { |
| code: 200, |
| message: '获取用户列表成功', |
| success: true, |
| data: { |
| total: userList.length, |
| users: userList |
| } |
| }; |
| }); |
| |
| // 13. 删除指定用户 (管理员) |
| Mock.mock('/user/delete', 'delete', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid || auth.userType !== 1) { |
| return { |
| code: 403, |
| message: '无权限访问', |
| success: false |
| }; |
| } |
| |
| const body = JSON.parse(options.body); |
| const { username, targetUsername } = body; |
| |
| // 确保操作者是管理员 |
| const admin = users.find(u => u.username === username && u.userType === 1); |
| if (!admin) { |
| return { |
| code: 403, |
| message: '无权限操作', |
| success: false |
| }; |
| } |
| |
| // 查找要删除的用户 |
| const userIndex = users.findIndex(u => u.username === targetUsername); |
| if (userIndex === -1) { |
| return { |
| code: 404, |
| message: '用户不存在', |
| success: false |
| }; |
| } |
| |
| // 不允许删除管理员 |
| if (users[userIndex].userType === 1) { |
| return { |
| code: 403, |
| message: '不能删除管理员账户', |
| success: false |
| }; |
| } |
| |
| // 删除用户 |
| const deletedUser = users.splice(userIndex, 1)[0]; |
| |
| return { |
| code: 200, |
| message: '用户删除成功', |
| success: true, |
| data: { |
| username: deletedUser.username |
| } |
| }; |
| }); |
| |
| // 14. 删除帖子 (管理员) |
| Mock.mock('/posts/delete', 'delete', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid || auth.userType !== 1) { |
| return { |
| code: 403, |
| message: '无权限访问', |
| success: false |
| }; |
| } |
| |
| const body = JSON.parse(options.body); |
| const { username, pid } = body; |
| |
| // 确保操作者是管理员 |
| const admin = users.find(u => u.username === username && u.userType === 1); |
| if (!admin) { |
| return { |
| code: 403, |
| message: '无权限操作', |
| success: false |
| }; |
| } |
| |
| // 查找要删除的帖子 |
| const postIndex = posts.findIndex(p => p.id === parseInt(pid)); |
| if (postIndex === -1) { |
| return { |
| code: 404, |
| message: '帖子不存在', |
| success: false |
| }; |
| } |
| |
| // 删除帖子 |
| const deletedPost = posts.splice(postIndex, 1)[0]; |
| |
| // 同时删除该帖子的所有评论 |
| const relatedComments = comments.filter(c => c.postId === parseInt(pid)); |
| relatedComments.forEach(comment => { |
| const commentIndex = comments.findIndex(c => c.id === comment.id); |
| if (commentIndex !== -1) { |
| comments.splice(commentIndex, 1); |
| } |
| }); |
| |
| return { |
| code: 200, |
| message: '帖子删除成功', |
| success: true, |
| data: { |
| title: deletedPost.title, |
| deletedComments: relatedComments.length |
| } |
| }; |
| }); |
| |
| // 15. 删除帖子评论 (管理员) |
| Mock.mock('/comment/delete', 'delete', (options) => { |
| const headers = options.headers || {}; |
| const token = headers.token; |
| const auth = verifyToken(token); |
| |
| if (!auth || !auth.valid || auth.userType !== 1) { |
| return { |
| code: 403, |
| message: '无权限访问', |
| success: false |
| }; |
| } |
| |
| const body = JSON.parse(options.body); |
| const { username, commentId } = body; |
| |
| // 确保操作者是管理员 |
| const admin = users.find(u => u.username === username && u.userType === 1); |
| if (!admin) { |
| return { |
| code: 403, |
| message: '无权限操作', |
| success: false |
| }; |
| } |
| |
| // 查找要删除的评论 |
| const commentIndex = comments.findIndex(c => c.id === parseInt(commentId)); |
| if (commentIndex === -1) { |
| return { |
| code: 404, |
| message: '评论不存在', |
| success: false |
| }; |
| } |
| |
| // 删除评论 |
| const deletedComment = comments.splice(commentIndex, 1)[0]; |
| |
| return { |
| code: 200, |
| message: '评论删除成功', |
| success: true, |
| data: { |
| commentId: deletedComment.id, |
| postId: deletedComment.postId |
| } |
| }; |
| }); |
| |
| export default Mock |