refactor: 完全移除Mock,100%使用真实DB数据和API

## 清理内容

### 删除的文件(10个Mock文件)
- src/mock/index.js
- src/mock/user.js
- src/mock/school.js
- src/mock/member.js
- src/mock/student.js
- src/mock/application.js
- src/mock/region.js
- src/mock/grade.js
- src/mock/class.js
- src/mock/subject.js

### 修改的文件
- **main.js**: 删除Mock引用注释
- **package.json**: 移除mockjs依赖
- **package-lock.json**: 自动更新(npm uninstall)

## 验证结果

 **真实API测试**: 6/6 通过
- 学校列表 
- 会员列表 
- 学生列表 
- 应用列表 
- 区域列表 
- 年级列表 

## 系统状态

 前端:无Mock依赖,纯净代码
 后端:真实API服务
 数据库:真实数据(MySQL 8.148.25.55)
 测试:100%使用真实数据

## 技术改进

**Before:**
- 混合Mock和真实API
- mockjs依赖占用空间
- 开发/生产环境不一致

**After:**
- 100%真实API调用
- 代码更简洁,减少10个文件
- 开发/生产环境完全一致
- 更真实的测试环境

## 总结

系统现已完全去除Mock机制,所有功能均使用真实数据库和API,
确保开发、测试、生产环境的一致性和可靠性。
This commit is contained in:
神码-方晓辉 2026-02-01 00:21:28 +08:00
parent e405c7015c
commit e416dd5ca8
13 changed files with 0 additions and 1563 deletions

View File

@ -11,7 +11,6 @@
"@element-plus/icons-vue": "^2.3.2", "@element-plus/icons-vue": "^2.3.2",
"axios": "^1.13.4", "axios": "^1.13.4",
"element-plus": "^2.13.2", "element-plus": "^2.13.2",
"mockjs": "^1.1.0",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"vue": "^3.5.26", "vue": "^3.5.26",
"vue-router": "^4.6.4" "vue-router": "^4.6.4"
@ -1252,15 +1251,6 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/commander": {
"version": "14.0.3",
"resolved": "https://registry.npmmirror.com/commander/-/commander-14.0.3.tgz",
"integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
"license": "MIT",
"engines": {
"node": ">=20"
}
},
"node_modules/copy-anything": { "node_modules/copy-anything": {
"version": "4.0.5", "version": "4.0.5",
"resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-4.0.5.tgz", "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-4.0.5.tgz",
@ -1699,17 +1689,6 @@
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/mockjs": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/mockjs/-/mockjs-1.1.0.tgz",
"integrity": "sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==",
"dependencies": {
"commander": "*"
},
"bin": {
"random": "bin/random"
}
},
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.11", "version": "3.3.11",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz",

View File

@ -14,7 +14,6 @@
"@element-plus/icons-vue": "^2.3.2", "@element-plus/icons-vue": "^2.3.2",
"axios": "^1.13.4", "axios": "^1.13.4",
"element-plus": "^2.13.2", "element-plus": "^2.13.2",
"mockjs": "^1.1.0",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"vue": "^3.5.26", "vue": "^3.5.26",
"vue-router": "^4.6.4" "vue-router": "^4.6.4"

View File

@ -7,9 +7,6 @@ import App from './App.vue'
import './assets/styles/index.css' import './assets/styles/index.css'
import router from './router' import router from './router'
// 引入Mock开发阶段已关闭使用真实API
// import './mock'
const app = createApp(App) const app = createApp(App)
// 注册所有图标 // 注册所有图标

View File

@ -1,196 +0,0 @@
/**
* 应用管理Mock数据
* @author pangu
*/
import Mock from 'mockjs'
// API接口列表与 pg_api_dict 一致)
const apiList = [
{ apiCode: 'STUDENT_LIST', apiName: '查询学生信息', apiPath: '/open/student/list', apiMethod: 'GET' },
{ apiCode: 'SCHOOL_LIST', apiName: '查询学校信息', apiPath: '/open/school/list', apiMethod: 'GET' },
{ apiCode: 'GRADE_LIST', apiName: '查询年级信息', apiPath: '/open/grade/list', apiMethod: 'GET' },
{ apiCode: 'CLASS_LIST', apiName: '查询班级信息', apiPath: '/open/class/list', apiMethod: 'GET' },
{ apiCode: 'MEMBER_LIST', apiName: '查询会员信息', apiPath: '/open/member/list', apiMethod: 'GET' },
{ apiCode: 'REGION_TREE', apiName: '查询区域树', apiPath: '/open/region/tree', apiMethod: 'GET' }
]
// 生成32位随机密钥
function genAppSecret() {
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
let s = ''
for (let i = 0; i < 32; i++) {
s += chars.charAt(Math.floor(Math.random() * chars.length))
}
return s
}
// 生成应用编码 YY + 6位数字
let appCodeSeq = 1
function genAppCode() {
const code = 'YY' + String(appCodeSeq).padStart(6, '0')
appCodeSeq += 1
return code
}
// 预置应用数据(与文档示例一致)
let applicationList = [
{
appId: 1,
appCode: 'YY000001',
appName: 'AI智慧平台',
appSecret: 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6',
appDesc: 'AI智慧教育平台接入',
contactPerson: '张经理',
contactPhone: '13812345678',
status: '0',
createTime: '2026-01-01 10:00:00',
createBy: 'admin',
apis: [
{ apiCode: 'SCHOOL_LIST', apiName: '查询学校信息', apiPath: '/open/school/list' },
{ apiCode: 'GRADE_LIST', apiName: '查询年级信息', apiPath: '/open/grade/list' },
{ apiCode: 'CLASS_LIST', apiName: '查询班级信息', apiPath: '/open/class/list' }
]
}
]
// 列表返回时密钥脱敏
function maskSecret(secret) {
if (!secret || secret.length < 8) return '********'
return secret.substring(0, 4) + '****************************'
}
// 获取应用列表
Mock.mock(/\/api\/app\/list/, 'get', (options) => {
const url = new URL('http://localhost' + options.url)
const appName = url.searchParams.get('appName') || ''
const appCode = url.searchParams.get('appCode') || ''
const status = url.searchParams.get('status') || ''
const pageNum = parseInt(url.searchParams.get('pageNum')) || 1
const pageSize = parseInt(url.searchParams.get('pageSize')) || 10
let filtered = applicationList.filter(item => {
let match = true
if (appName) match = match && item.appName.includes(appName)
if (appCode) match = match && item.appCode.includes(appCode)
if (status !== '' && status !== null) match = match && item.status === status
return match
})
const total = filtered.length
const start = (pageNum - 1) * pageSize
const rows = filtered.slice(start, start + pageSize).map(item => ({
...item,
appSecret: maskSecret(item.appSecret)
}))
return {
code: 200,
msg: '查询成功',
total,
rows
}
})
// 获取应用详情
Mock.mock(/\/api\/app\/\d+$/, 'get', (options) => {
const appId = parseInt(options.url.match(/\/api\/app\/(\d+)/)[1])
const app = applicationList.find(item => item.appId === appId)
if (app) {
return {
code: 200,
msg: '查询成功',
data: {
...app,
appSecret: maskSecret(app.appSecret),
apis: app.apis || []
}
}
}
return { code: 500, msg: '应用不存在' }
})
// 新增应用
Mock.mock('/api/app', 'post', (options) => {
const data = JSON.parse(options.body)
const appCode = genAppCode()
const appSecret = genAppSecret()
const newApp = {
appId: applicationList.length ? Math.max(...applicationList.map(a => a.appId)) + 1 : 1,
appCode,
appName: data.appName,
appSecret,
appDesc: data.appDesc || '',
contactPerson: data.contactPerson || '',
contactPhone: data.contactPhone || '',
status: data.status || '0',
createTime: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
createBy: 'admin',
apis: (data.apiCodes || []).map(code => {
const api = apiList.find(a => a.apiCode === code)
return api ? { apiCode: api.apiCode, apiName: api.apiName, apiPath: api.apiPath } : null
}).filter(Boolean)
}
applicationList.unshift(newApp)
return { code: 200, msg: '新增成功' }
})
// 修改应用
Mock.mock('/api/app', 'put', (options) => {
const data = JSON.parse(options.body)
const index = applicationList.findIndex(item => item.appId === data.appId)
if (index !== -1) {
const existing = applicationList[index]
applicationList[index] = {
...existing,
appName: data.appName !== undefined ? data.appName : existing.appName,
appDesc: data.appDesc !== undefined ? data.appDesc : existing.appDesc,
contactPerson: data.contactPerson !== undefined ? data.contactPerson : existing.contactPerson,
contactPhone: data.contactPhone !== undefined ? data.contactPhone : existing.contactPhone,
status: data.status !== undefined ? data.status : existing.status,
apis: data.apiCodes
? data.apiCodes.map(code => {
const api = apiList.find(a => a.apiCode === code)
return api ? { apiCode: api.apiCode, apiName: api.apiName, apiPath: api.apiPath } : null
}).filter(Boolean)
: existing.apis
}
return { code: 200, msg: '修改成功' }
}
return { code: 500, msg: '应用不存在' }
})
// 删除应用
Mock.mock(/\/api\/app\/\d+$/, 'delete', (options) => {
const appId = parseInt(options.url.match(/\/api\/app\/(\d+)/)[1])
const index = applicationList.findIndex(item => item.appId === appId)
if (index !== -1) {
applicationList.splice(index, 1)
return { code: 200, msg: '删除成功' }
}
return { code: 500, msg: '应用不存在' }
})
// 重置应用密钥 PUT /api/app/resetSecret/{appId}
Mock.mock(/\/api\/app\/resetSecret\/\d+/, 'put', (options) => {
const appId = parseInt(options.url.match(/\/api\/app\/resetSecret\/(\d+)/)[1])
const app = applicationList.find(item => item.appId === appId)
if (app) {
const newSecret = genAppSecret()
app.appSecret = newSecret
return {
code: 200,
msg: '密钥重置成功',
data: { appSecret: newSecret }
}
}
return { code: 500, msg: '应用不存在' }
})
// 获取API接口列表用于接口授权勾选
Mock.mock('/api/app/apiList', 'get', () => {
return {
code: 200,
msg: '查询成功',
data: apiList
}
})

View File

@ -1,89 +0,0 @@
/**
* 班级管理Mock数据
* @author pangu
*/
import Mock from 'mockjs'
// 班级预置数据
const classData = [
{ id: 1, className: '1班', classCode: 'C01', sort: 1, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 2, className: '2班', classCode: 'C02', sort: 2, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 3, className: '3班', classCode: 'C03', sort: 3, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 4, className: '4班', classCode: 'C04', sort: 4, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 5, className: '5班', classCode: 'C05', sort: 5, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 6, className: '6班', classCode: 'C06', sort: 6, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 7, className: '7班', classCode: 'C07', sort: 7, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 8, className: '8班', classCode: 'C08', sort: 8, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 9, className: '9班', classCode: 'C09', sort: 9, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 10, className: '10班', classCode: 'C10', sort: 10, status: '0', createTime: '2026-01-01 10:00:00' }
]
// 获取班级列表
Mock.mock(/\/api\/class\/list/, 'get', (options) => {
const url = new URL('http://localhost' + options.url)
const className = url.searchParams.get('className') || ''
const status = url.searchParams.get('status')
const pageNum = parseInt(url.searchParams.get('pageNum')) || 1
const pageSize = parseInt(url.searchParams.get('pageSize')) || 10
let list = classData.filter(item => {
let match = true
if (className) {
match = match && item.className.includes(className)
}
if (status !== null && status !== '') {
match = match && item.status === status
}
return match
})
const total = list.length
const start = (pageNum - 1) * pageSize
const rows = list.slice(start, start + pageSize)
return {
code: 200,
msg: '查询成功',
total,
rows
}
})
// 获取班级选项
Mock.mock(/\/api\/class\/options/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: classData.filter(item => item.status === '0').map(item => ({
id: item.id,
className: item.className,
classCode: item.classCode
}))
}
})
// 获取班级详情
Mock.mock(/\/api\/class\/\d+/, 'get', (options) => {
const id = parseInt(options.url.match(/\/api\/class\/(\d+)/)[1])
const item = classData.find(c => c.id === id)
return {
code: 200,
msg: '查询成功',
data: item || null
}
})
// 新增班级
Mock.mock('/api/class', 'post', () => {
return { code: 200, msg: '新增成功' }
})
// 修改班级
Mock.mock('/api/class', 'put', () => {
return { code: 200, msg: '修改成功' }
})
// 删除班级
Mock.mock(/\/api\/class\/\d+/, 'delete', () => {
return { code: 200, msg: '删除成功' }
})

View File

@ -1,91 +0,0 @@
/**
* 年级管理Mock数据
* @author pangu
*/
import Mock from 'mockjs'
// 年级预置数据
const gradeData = [
{ id: 1, gradeName: '一年级', gradeCode: 'G01', sort: 1, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 2, gradeName: '二年级', gradeCode: 'G02', sort: 2, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 3, gradeName: '三年级', gradeCode: 'G03', sort: 3, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 4, gradeName: '四年级', gradeCode: 'G04', sort: 4, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 5, gradeName: '五年级', gradeCode: 'G05', sort: 5, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 6, gradeName: '六年级', gradeCode: 'G06', sort: 6, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 7, gradeName: '七年级', gradeCode: 'G07', sort: 7, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 8, gradeName: '八年级', gradeCode: 'G08', sort: 8, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 9, gradeName: '九年级', gradeCode: 'G09', sort: 9, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 10, gradeName: '高一', gradeCode: 'G10', sort: 10, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 11, gradeName: '高二', gradeCode: 'G11', sort: 11, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 12, gradeName: '高三', gradeCode: 'G12', sort: 12, status: '0', createTime: '2026-01-01 10:00:00' }
]
// 获取年级列表
Mock.mock(/\/api\/grade\/list/, 'get', (options) => {
const url = new URL('http://localhost' + options.url)
const gradeName = url.searchParams.get('gradeName') || ''
const status = url.searchParams.get('status')
const pageNum = parseInt(url.searchParams.get('pageNum')) || 1
const pageSize = parseInt(url.searchParams.get('pageSize')) || 10
let list = gradeData.filter(item => {
let match = true
if (gradeName) {
match = match && item.gradeName.includes(gradeName)
}
if (status !== null && status !== '') {
match = match && item.status === status
}
return match
})
const total = list.length
const start = (pageNum - 1) * pageSize
const rows = list.slice(start, start + pageSize)
return {
code: 200,
msg: '查询成功',
total,
rows
}
})
// 获取年级选项
Mock.mock(/\/api\/grade\/options/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: gradeData.filter(item => item.status === '0').map(item => ({
id: item.id,
gradeName: item.gradeName,
gradeCode: item.gradeCode
}))
}
})
// 获取年级详情
Mock.mock(/\/api\/grade\/\d+/, 'get', (options) => {
const id = parseInt(options.url.match(/\/api\/grade\/(\d+)/)[1])
const item = gradeData.find(g => g.id === id)
return {
code: 200,
msg: '查询成功',
data: item || null
}
})
// 新增年级
Mock.mock('/api/grade', 'post', () => {
return { code: 200, msg: '新增成功' }
})
// 修改年级
Mock.mock('/api/grade', 'put', () => {
return { code: 200, msg: '修改成功' }
})
// 删除年级
Mock.mock(/\/api\/grade\/\d+/, 'delete', () => {
return { code: 200, msg: '删除成功' }
})

View File

@ -1,18 +0,0 @@
/**
* Mock数据入口
* @author pangu
*/
// 基础数据
import './class'
import './grade'
import './region'
import './subject'
// 业务模块
import './application'
import './member'
import './school'
import './student'
import './user'

View File

@ -1,284 +0,0 @@
/**
* 会员管理Mock数据
* @author pangu
*/
import Mock from 'mockjs'
// 会员列表数据
const memberList = []
for (let i = 1; i <= 50; i++) {
const identityType = Mock.mock('@pick(["1", "2"])')
memberList.push({
memberId: i,
memberCode: 'JS' + Mock.mock('@natural(1700000000000, 1799999999999)'),
phone: Mock.mock(/^1[3-9]\d{9}$/),
phoneFull: Mock.mock(/^1[3-9]\d{9}$/),
nickname: Mock.mock('@cname'),
gender: Mock.mock('@pick(["0", "1", "2"])'),
genderName: Mock.mock('@pick(["未知", "男", "女"])'),
birthday: Mock.mock('@date("yyyy-MM-dd")'),
identityType: identityType,
identityTypeName: identityType === '1' ? '家长' : '教师',
registerTime: Mock.mock('@datetime("yyyy-MM-dd HH:mm:ss")'),
registerSource: Mock.mock('@pick(["1", "2", "3", "4"])'),
registerSourceName: Mock.mock('@pick(["小程序", "H5", "后台新增", "批量导入"])'),
status: Mock.mock('@pick(["0", "1"])'),
// 教师才有学校信息
regionId: identityType === '2' ? Mock.mock('@pick([111, 112, 113, 114])') : null,
regionPath: identityType === '2' ? '湖北省-武汉市-' + Mock.mock('@pick(["武昌区", "汉口区", "汉阳区", "江夏区"])') : null,
schoolId: identityType === '2' ? i : null,
schoolName: identityType === '2' ? Mock.mock('@ctitle(4, 8)') + '学校' : null,
schoolGradeId: identityType === '2' ? Mock.mock('@natural(1, 6)') : null,
gradeName: identityType === '2' ? Mock.mock('@pick(["一年级", "二年级", "三年级", "四年级", "五年级", "六年级"])') : null,
schoolClassId: identityType === '2' ? Mock.mock('@natural(1, 5)') : null,
className: identityType === '2' ? Mock.mock('@natural(1, 5)') + '班' : null,
// 绑定的学生
students: Mock.mock({
'list|0-3': [{
'studentId|+1': 1000,
studentName: '@cname',
studentNo: 'STU' + Mock.mock('@natural(20260001, 20269999)'),
schoolName: '@ctitle(4, 8)学校',
gradeName: '@pick(["一年级", "二年级", "三年级"])',
className: '@natural(1, 5)班'
}]
}).list
})
}
// 区域树数据
const regionTree = [
{
id: 1,
label: '湖北省',
children: [
{
id: 11,
label: '武汉市',
children: [
{ id: 111, label: '武昌区' },
{ id: 112, label: '汉口区' },
{ id: 113, label: '汉阳区' },
{ id: 114, label: '江夏区' }
]
},
{
id: 12,
label: '黄冈市',
children: [
{ id: 121, label: '黄州区' },
{ id: 122, label: '红安县' }
]
}
]
}
]
// 学校列表
const schoolList = [
{ id: 1, name: '武昌实验小学' },
{ id: 2, name: '武汉小学' },
{ id: 3, name: '华师附小' },
{ id: 4, name: '水果湖第一小学' },
{ id: 5, name: '武珞路小学' }
]
// 年级列表
const gradeList = [
{ id: 1, name: '一年级' },
{ id: 2, name: '二年级' },
{ id: 3, name: '三年级' },
{ id: 4, name: '四年级' },
{ id: 5, name: '五年级' },
{ id: 6, name: '六年级' }
]
// 班级列表
const classList = [
{ id: 1, name: '1班' },
{ id: 2, name: '2班' },
{ id: 3, name: '3班' },
{ id: 4, name: '4班' },
{ id: 5, name: '5班' }
]
// 查询会员列表
Mock.mock(/\/api\/member\/list/, 'get', (options) => {
const params = new URLSearchParams(options.url.split('?')[1])
const pageNum = parseInt(params.get('pageNum')) || 1
const pageSize = parseInt(params.get('pageSize')) || 10
const phone = params.get('phone')
const nickname = params.get('nickname')
const identityType = params.get('identityType')
const status = params.get('status')
let filteredList = [...memberList]
// 手机号筛选
if (phone) {
filteredList = filteredList.filter(item => item.phone.includes(phone))
}
// 昵称筛选
if (nickname) {
filteredList = filteredList.filter(item => item.nickname.includes(nickname))
}
// 身份类型筛选
if (identityType) {
filteredList = filteredList.filter(item => item.identityType === identityType)
}
// 状态筛选
if (status) {
filteredList = filteredList.filter(item => item.status === status)
}
const start = (pageNum - 1) * pageSize
const end = start + pageSize
const rows = filteredList.slice(start, end)
return {
code: 200,
msg: '查询成功',
total: filteredList.length,
rows
}
})
// 获取会员详情
Mock.mock(/\/api\/member\/\d+$/, 'get', (options) => {
const id = parseInt(options.url.match(/\/api\/member\/(\d+)$/)[1])
const member = memberList.find(item => item.id === id)
return {
code: 200,
msg: '查询成功',
data: member || null
}
})
// 新增会员
Mock.mock('/api/member', 'post', () => {
return {
code: 200,
msg: '新增成功'
}
})
// 修改会员
Mock.mock('/api/member', 'put', () => {
return {
code: 200,
msg: '修改成功'
}
})
// 删除会员
Mock.mock(/\/api\/member\/\d+$/, 'delete', () => {
return {
code: 200,
msg: '删除成功'
}
})
// 重置密码
Mock.mock(/\/api\/member\/resetPwd\/\d+$/, 'put', () => {
const newPassword = Mock.mock(/^[A-Za-z0-9]{8}$/)
return {
code: 200,
msg: '重置成功',
password: newPassword
}
})
// 修改状态
Mock.mock('/api/member/changeStatus', 'put', () => {
return {
code: 200,
msg: '状态修改成功'
}
})
// 绑定学生
Mock.mock('/api/member/bindStudent', 'post', () => {
return {
code: 200,
msg: '绑定成功'
}
})
// 解绑学生
Mock.mock(/\/api\/member\/unbindStudent\/\d+\/\d+$/, 'delete', () => {
return {
code: 200,
msg: '解绑成功'
}
})
// 检查手机号唯一性
Mock.mock(/\/api\/member\/checkPhone/, 'get', () => {
return {
code: 200,
msg: '查询成功',
unique: Mock.mock('@boolean')
}
})
// 获取区域树
Mock.mock(/\/api\/region\/tree/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: regionTree
}
})
// 获取学校列表
Mock.mock(/\/api\/school\/list/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: schoolList
}
})
// 获取年级列表
Mock.mock(/\/api\/school\/gradeList/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: gradeList
}
})
// 获取班级列表
Mock.mock(/\/api\/school\/classList/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: classList
}
})
// 获取可绑定的学生列表
Mock.mock(/\/api\/student\/bindableList/, 'get', (options) => {
const params = new URLSearchParams(options.url.split('?')[1])
const pageNum = parseInt(params.get('pageNum')) || 1
const pageSize = parseInt(params.get('pageSize')) || 10
// 生成学生列表
const students = Mock.mock({
[`list|${pageSize}`]: [{
'studentId|+1': 1000,
studentName: '@cname',
studentNo: 'STU' + Mock.mock('@natural(20260001, 20269999)'),
schoolName: '@ctitle(4, 8)学校',
gradeName: '@pick(["一年级", "二年级", "三年级", "四年级", "五年级", "六年级"])',
className: '@natural(1, 5)班'
}]
}).list
return {
code: 200,
msg: '查询成功',
total: 100,
rows: students
}
})

View File

@ -1,141 +0,0 @@
/**
* 区域管理Mock数据
* @author pangu
*/
import Mock from 'mockjs'
// 区域树形数据
const regionTree = [
{
id: 1,
regionName: '湖北省',
regionCode: 'HB',
level: 1,
parentId: 0,
sort: 1,
status: '0',
createTime: '2026-01-01 10:00:00',
children: [
{
id: 11,
regionName: '武汉市',
regionCode: 'WH',
level: 2,
parentId: 1,
sort: 1,
status: '0',
createTime: '2026-01-01 10:00:00',
children: [
{ id: 111, regionName: '武昌区', regionCode: 'WC', level: 3, parentId: 11, sort: 1, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 112, regionName: '洪山区', regionCode: 'HS', level: 3, parentId: 11, sort: 2, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 113, regionName: '江夏区', regionCode: 'JX', level: 3, parentId: 11, sort: 3, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 114, regionName: '汉阳区', regionCode: 'HY', level: 3, parentId: 11, sort: 4, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 115, regionName: '江岸区', regionCode: 'JA', level: 3, parentId: 11, sort: 5, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 116, regionName: '江汉区', regionCode: 'JH', level: 3, parentId: 11, sort: 6, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 117, regionName: '硚口区', regionCode: 'QK', level: 3, parentId: 11, sort: 7, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 118, regionName: '青山区', regionCode: 'QS', level: 3, parentId: 11, sort: 8, status: '0', createTime: '2026-01-01 10:00:00' }
]
},
{
id: 12,
regionName: '黄冈市',
regionCode: 'HG',
level: 2,
parentId: 1,
sort: 2,
status: '0',
createTime: '2026-01-01 10:00:00',
children: [
{ id: 121, regionName: '黄州区', regionCode: 'HZ', level: 3, parentId: 12, sort: 1, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 122, regionName: '红安县', regionCode: 'HA', level: 3, parentId: 12, sort: 2, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 123, regionName: '麻城市', regionCode: 'MC', level: 3, parentId: 12, sort: 3, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 124, regionName: '武穴市', regionCode: 'WX', level: 3, parentId: 12, sort: 4, status: '0', createTime: '2026-01-01 10:00:00' }
]
},
{
id: 13,
regionName: '宜昌市',
regionCode: 'YC',
level: 2,
parentId: 1,
sort: 3,
status: '0',
createTime: '2026-01-01 10:00:00',
children: [
{ id: 131, regionName: '西陵区', regionCode: 'XL', level: 3, parentId: 13, sort: 1, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 132, regionName: '伍家岗区', regionCode: 'WJG', level: 3, parentId: 13, sort: 2, status: '0', createTime: '2026-01-01 10:00:00' }
]
},
{
id: 14,
regionName: '襄阳市',
regionCode: 'XY',
level: 2,
parentId: 1,
sort: 4,
status: '0',
createTime: '2026-01-01 10:00:00',
children: [
{ id: 141, regionName: '襄城区', regionCode: 'XCQ', level: 3, parentId: 14, sort: 1, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 142, regionName: '樊城区', regionCode: 'FC', level: 3, parentId: 14, sort: 2, status: '0', createTime: '2026-01-01 10:00:00' }
]
}
]
}
]
// 获取区域树
Mock.mock(/\/api\/region\/tree/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: regionTree
}
})
// 获取区域列表(树形)
Mock.mock(/\/api\/region\/list/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: regionTree
}
})
// 获取区域详情
Mock.mock(/\/api\/region\/\d+/, 'get', (options) => {
const id = parseInt(options.url.match(/\/api\/region\/(\d+)/)[1])
// 递归查找
const findById = (list, targetId) => {
for (const item of list) {
if (item.id === targetId) return item
if (item.children) {
const found = findById(item.children, targetId)
if (found) return found
}
}
return null
}
return {
code: 200,
msg: '查询成功',
data: findById(regionTree, id)
}
})
// 新增区域
Mock.mock('/api/region', 'post', () => {
return { code: 200, msg: '新增成功' }
})
// 修改区域
Mock.mock('/api/region', 'put', () => {
return { code: 200, msg: '修改成功' }
})
// 删除区域
Mock.mock(/\/api\/region\/\d+/, 'delete', () => {
return { code: 200, msg: '删除成功' }
})

View File

@ -1,391 +0,0 @@
/**
* 学校管理Mock数据
* @author pangu
*/
import Mock from 'mockjs'
// 区域树数据
const regionTree = [
{
regionId: 1,
regionName: '湖北省',
children: [
{
regionId: 11,
regionName: '武汉市',
children: [
{ regionId: 111, regionName: '武昌区' },
{ regionId: 112, regionName: '汉口区' },
{ regionId: 113, regionName: '汉阳区' },
{ regionId: 114, regionName: '江夏区' },
{ regionId: 115, regionName: '洪山区' }
]
},
{
regionId: 12,
regionName: '黄冈市',
children: [
{ regionId: 121, regionName: '黄州区' },
{ regionId: 122, regionName: '红安县' },
{ regionId: 123, regionName: '麻城市' }
]
},
{
regionId: 13,
regionName: '宜昌市',
children: [
{ regionId: 131, regionName: '西陵区' },
{ regionId: 132, regionName: '伍家岗区' }
]
}
]
}
]
// 学校类型选项
const schoolTypes = ['小学', '初中', '高中', '九年一贯制', '完全中学']
// 生成学校列表Mock数据
const generateSchoolList = () => {
const list = []
const regions = [
{ id: 111, name: '湖北省/武汉市/武昌区' },
{ id: 112, name: '湖北省/武汉市/汉口区' },
{ id: 113, name: '湖北省/武汉市/汉阳区' },
{ id: 114, name: '湖北省/武汉市/江夏区' },
{ id: 121, name: '湖北省/黄冈市/黄州区' },
{ id: 122, name: '湖北省/黄冈市/红安县' }
]
const schoolNames = [
'武昌实验小学', '华师一附中', '武汉外国语学校', '水果湖第一小学',
'武汉第二中学', '武汉六中', '江夏区第一中学', '武汉市第三中学',
'红安县第一中学', '黄州中学', '武汉小学', '光谷第一小学',
'华中科技大学附属小学', '武汉市育才小学', '武汉市常青第一学校'
]
for (let i = 0; i < schoolNames.length; i++) {
const region = regions[i % regions.length]
list.push({
id: i + 1,
schoolName: schoolNames[i],
schoolType: schoolTypes[i % schoolTypes.length],
regionId: region.id,
regionName: region.name,
status: Mock.Random.pick(['0', '1']),
createTime: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
createBy: Mock.Random.pick(['admin', '张三', '李四'])
})
}
return list
}
const schoolList = generateSchoolList()
// 年级选项
const gradeOptions = [
{ value: '1', label: '一年级' },
{ value: '2', label: '二年级' },
{ value: '3', label: '三年级' },
{ value: '4', label: '四年级' },
{ value: '5', label: '五年级' },
{ value: '6', label: '六年级' },
{ value: '7', label: '七年级' },
{ value: '8', label: '八年级' },
{ value: '9', label: '九年级' },
{ value: '10', label: '高一' },
{ value: '11', label: '高二' },
{ value: '12', label: '高三' }
]
// 班级选项
const classOptions = [
{ value: '1', label: '1班' },
{ value: '2', label: '2班' },
{ value: '3', label: '3班' },
{ value: '4', label: '4班' },
{ value: '5', label: '5班' },
{ value: '6', label: '6班' },
{ value: '7', label: '7班' },
{ value: '8', label: '8班' },
{ value: '9', label: '9班' },
{ value: '10', label: '10班' }
]
// 获取区域树
Mock.mock(/\/api\/region\/tree/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: regionTree
}
})
// 获取学校列表
Mock.mock(/\/api\/school\/list/, 'get', (options) => {
const url = new URL('http://localhost' + options.url)
const pageNum = parseInt(url.searchParams.get('pageNum')) || 1
const pageSize = parseInt(url.searchParams.get('pageSize')) || 10
const schoolName = url.searchParams.get('schoolName') || ''
const status = url.searchParams.get('status')
const regionId = url.searchParams.get('regionId')
let filteredList = [...schoolList]
// 按学校名称筛选
if (schoolName) {
filteredList = filteredList.filter(item =>
item.schoolName.includes(schoolName)
)
}
// 按状态筛选
if (status !== null && status !== '') {
filteredList = filteredList.filter(item => item.status === status)
}
// 按区域筛选(包含子区域)
if (regionId) {
const rid = parseInt(regionId)
filteredList = filteredList.filter(item => {
// 匹配当前区域或其子区域
const itemRegionId = item.regionId
if (rid < 10) {
// 省级
return Math.floor(itemRegionId / 100) === rid
} else if (rid < 100) {
// 市级
return Math.floor(itemRegionId / 10) === rid
} else {
// 区级
return itemRegionId === rid
}
})
}
const total = filteredList.length
const start = (pageNum - 1) * pageSize
const rows = filteredList.slice(start, start + pageSize)
return {
code: 200,
msg: '查询成功',
total,
rows
}
})
// 获取学校详情
Mock.mock(/\/api\/school\/\d+$/, 'get', (options) => {
const id = parseInt(options.url.match(/\/api\/school\/(\d+)/)[1])
const school = schoolList.find(item => item.id === id)
return {
code: 200,
msg: '查询成功',
data: school || null
}
})
// 新增学校
Mock.mock('/api/school', 'post', (options) => {
const data = JSON.parse(options.body)
const newSchool = {
id: schoolList.length + 1,
...data,
createTime: Mock.Random.now('yyyy-MM-dd HH:mm:ss'),
createBy: 'admin'
}
schoolList.unshift(newSchool)
return {
code: 200,
msg: '新增成功'
}
})
// 修改学校
Mock.mock('/api/school', 'put', (options) => {
const data = JSON.parse(options.body)
const index = schoolList.findIndex(item => item.id === data.id)
if (index !== -1) {
schoolList[index] = { ...schoolList[index], ...data }
}
return {
code: 200,
msg: '修改成功'
}
})
// 删除学校
Mock.mock(/\/api\/school\/\d+$/, 'delete', (options) => {
const id = parseInt(options.url.match(/\/api\/school\/(\d+)/)[1])
const index = schoolList.findIndex(item => item.id === id)
if (index !== -1) {
schoolList.splice(index, 1)
}
return {
code: 200,
msg: '删除成功'
}
})
// 获取年级选项
Mock.mock(/\/api\/grade\/options/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: gradeOptions
}
})
// 获取班级选项
Mock.mock(/\/api\/class\/options/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: classOptions
}
})
// 为学校添加年级
Mock.mock('/api/school/grade', 'post', () => {
return {
code: 200,
msg: '添加年级成功'
}
})
// 为年级添加班级
Mock.mock('/api/school/class', 'post', () => {
return {
code: 200,
msg: '添加班级成功'
}
})
// 获取学校树形结构
Mock.mock(/\/api\/school\/tree/, 'get', (options) => {
const url = new URL('http://localhost' + options.url)
const regionId = url.searchParams.get('regionId')
// 根据区域筛选学校
let filteredSchools = [...schoolList]
if (regionId) {
const rid = parseInt(regionId)
filteredSchools = filteredSchools.filter(item => {
const itemRegionId = item.regionId
if (rid < 10) {
return Math.floor(itemRegionId / 100) === rid
} else if (rid < 100) {
return Math.floor(itemRegionId / 10) === rid
} else {
return itemRegionId === rid
}
})
}
// 构建树形结构
const tree = filteredSchools.map(school => ({
id: school.id,
type: 'school',
name: school.schoolName,
code: `SCH2026${String(school.id).padStart(4, '0')}`,
status: school.status,
regionPath: school.regionName,
schoolId: school.id,
children: [
{
id: `${school.id}-1`,
type: 'grade',
name: '七年级',
schoolGradeId: `${school.id}-1`,
gradeId: 7,
children: [
{
id: `${school.id}-1-1`,
type: 'class',
name: '1班',
schoolClassId: `${school.id}-1-1`,
classId: 1
},
{
id: `${school.id}-1-2`,
type: 'class',
name: '2班',
schoolClassId: `${school.id}-1-2`,
classId: 2
}
]
},
{
id: `${school.id}-2`,
type: 'grade',
name: '八年级',
schoolGradeId: `${school.id}-2`,
gradeId: 8,
children: []
}
]
}))
return {
code: 200,
msg: '查询成功',
data: tree
}
})
// 挂载年级
Mock.mock('/api/school/bindGrades', 'post', () => {
return {
code: 200,
msg: '挂载年级成功'
}
})
// 挂载班级
Mock.mock('/api/school/bindClasses', 'post', () => {
return {
code: 200,
msg: '挂载班级成功'
}
})
// 删除学校年级
Mock.mock(/\/api\/school\/grade\/\d+$/, 'delete', () => {
return {
code: 200,
msg: '删除年级成功'
}
})
// 删除学校班级
Mock.mock(/\/api\/school\/class\/\d+$/, 'delete', () => {
return {
code: 200,
msg: '删除班级成功'
}
})
// 获取年级列表
Mock.mock(/\/api\/grade\/list/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: gradeOptions.map(item => ({
gradeId: parseInt(item.value),
gradeName: item.label
}))
}
})
// 获取班级列表
Mock.mock(/\/api\/class\/list/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: classOptions.map(item => ({
classId: parseInt(item.value),
className: item.label
}))
}
})

View File

@ -1,121 +0,0 @@
/**
* 学生管理Mock数据
* @author pangu
*/
import Mock from 'mockjs'
// 学生列表数据
const studentList = []
for (let i = 1; i <= 50; i++) {
studentList.push({
studentId: i,
studentName: Mock.Random.cname(),
studentNo: `STU202600${String(i).padStart(2, '0')}`,
gender: Mock.Random.pick(['1', '2']),
genderName: Mock.Random.pick(['男', '女']),
birthday: Mock.Random.date('yyyy-MM'),
regionId: 111,
regionPath: '湖北省-武汉市-武昌区',
schoolId: Mock.Random.pick([1, 2, 3]),
schoolName: Mock.Random.pick(['武汉市第一中学', '武汉市第二中学', '武汉市第三中学']),
schoolGradeId: Mock.Random.pick([1, 2, 3]),
gradeName: Mock.Random.pick(['七年级', '八年级', '九年级']),
schoolClassId: Mock.Random.pick([1, 2, 3, 4]),
className: Mock.Random.pick(['1班', '2班', '3班', '4班']),
subjectId: Mock.Random.pick([1, 2, 3, null]),
subjectName: Mock.Random.pick(['语文', '数学', '英语', null]),
memberId: Mock.Random.pick([1, 2]),
memberNickname: Mock.Random.cname() + '家长',
memberPhone: '138****' + Mock.Random.string('number', 4),
status: '0',
createTime: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
remark: null
})
}
// 查询学生列表
Mock.mock(/\/api\/student\/list/, 'get', (options) => {
const { pageNum = 1, pageSize = 10 } = options.body ? JSON.parse(options.body) : {}
const start = (pageNum - 1) * pageSize
const end = start + pageSize
return {
code: 200,
msg: '查询成功',
rows: studentList.slice(start, end),
total: studentList.length
}
})
// 获取学生详情
Mock.mock(/\/api\/student\/\d+$/, 'get', (options) => {
const id = parseInt(options.url.match(/\/api\/student\/(\d+)$/)[1])
const student = studentList.find(s => s.studentId === id)
return {
code: 200,
msg: '查询成功',
data: student
}
})
// 新增学生
Mock.mock('/api/student', 'post', () => {
return {
code: 200,
msg: '新增成功'
}
})
// 修改学生
Mock.mock('/api/student', 'put', () => {
return {
code: 200,
msg: '修改成功'
}
})
// 删除学生
Mock.mock(/\/api\/student\/\d+$/, 'delete', () => {
return {
code: 200,
msg: '删除成功'
}
})
// 批量导入学生
Mock.mock('/api/student/import', 'post', () => {
return {
code: 200,
msg: '导入成功',
data: {
total: 100,
successCount: 95,
failCount: 5,
errorList: [
{ rowNum: 3, studentName: '张三', studentNo: 'STU001', errorMsg: '学号已存在' },
{ rowNum: 15, studentName: '李四', studentNo: 'STU015', errorMsg: '手机号格式错误' },
{ rowNum: 28, studentName: '王五', studentNo: 'STU028', errorMsg: '学校不存在' },
{ rowNum: 45, studentName: '赵六', studentNo: 'STU045', errorMsg: '年级不存在' },
{ rowNum: 67, studentName: '孙七', studentNo: 'STU067', errorMsg: '班级不存在' }
]
}
}
})
// 下载导入模板
Mock.mock('/api/student/template', 'get', () => {
return {
code: 200,
msg: '下载成功'
}
})
// 检查学号唯一性
Mock.mock(/\/api\/student\/checkStudentNo/, 'get', () => {
return {
code: 200,
msg: '查询成功',
data: true
}
})

View File

@ -1,75 +0,0 @@
/**
* 学科管理Mock数据
* @author pangu
*/
import Mock from 'mockjs'
// 学科预置数据
const subjectData = [
{ id: 1, subjectName: '语文', subjectCode: 'S01', sort: 1, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 2, subjectName: '数学', subjectCode: 'S02', sort: 2, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 3, subjectName: '英语', subjectCode: 'S03', sort: 3, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 4, subjectName: '物理', subjectCode: 'S04', sort: 4, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 5, subjectName: '化学', subjectCode: 'S05', sort: 5, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 6, subjectName: '生物', subjectCode: 'S06', sort: 6, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 7, subjectName: '历史', subjectCode: 'S07', sort: 7, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 8, subjectName: '地理', subjectCode: 'S08', sort: 8, status: '0', createTime: '2026-01-01 10:00:00' },
{ id: 9, subjectName: '政治', subjectCode: 'S09', sort: 9, status: '0', createTime: '2026-01-01 10:00:00' }
]
// 获取学科列表
Mock.mock(/\/api\/subject\/list/, 'get', (options) => {
const url = new URL('http://localhost' + options.url)
const subjectName = url.searchParams.get('subjectName') || ''
const status = url.searchParams.get('status')
const pageNum = parseInt(url.searchParams.get('pageNum')) || 1
const pageSize = parseInt(url.searchParams.get('pageSize')) || 10
let list = subjectData.filter(item => {
let match = true
if (subjectName) {
match = match && item.subjectName.includes(subjectName)
}
if (status !== null && status !== '') {
match = match && item.status === status
}
return match
})
const total = list.length
const start = (pageNum - 1) * pageSize
const rows = list.slice(start, start + pageSize)
return {
code: 200,
msg: '查询成功',
total,
rows
}
})
// 获取学科详情
Mock.mock(/\/api\/subject\/\d+/, 'get', (options) => {
const id = parseInt(options.url.match(/\/api\/subject\/(\d+)/)[1])
const item = subjectData.find(s => s.id === id)
return {
code: 200,
msg: '查询成功',
data: item || null
}
})
// 新增学科
Mock.mock('/api/subject', 'post', () => {
return { code: 200, msg: '新增成功' }
})
// 修改学科
Mock.mock('/api/subject', 'put', () => {
return { code: 200, msg: '修改成功' }
})
// 删除学科
Mock.mock(/\/api\/subject\/\d+/, 'delete', () => {
return { code: 200, msg: '删除成功' }
})

View File

@ -1,132 +0,0 @@
/**
* 用户相关Mock接口
* @author pangu
*/
import Mock from 'mockjs'
// 存储验证码模拟服务端session
const captchaStore = {}
/**
* 生成验证码图片简单的SVG
*/
const generateCaptcha = () => {
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789'
let code = ''
for (let i = 0; i < 4; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length))
}
// 生成简单的SVG验证码
const colors = ['#f56c6c', '#409eff', '#67c23a', '#e6a23c', '#909399']
const randomColor = () => colors[Math.floor(Math.random() * colors.length)]
const svg = `
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="40">
<rect width="100%" height="100%" fill="#f5f5f5"/>
${code.split('').map((char, i) => `
<text x="${15 + i * 22}" y="${28 + Math.random() * 8 - 4}"
fill="${randomColor()}"
font-size="${18 + Math.random() * 6}"
transform="rotate(${Math.random() * 20 - 10}, ${15 + i * 22}, 25)">
${char}
</text>
`).join('')}
${Array.from({ length: 3 }).map(() => `
<line x1="${Math.random() * 100}" y1="${Math.random() * 40}"
x2="${Math.random() * 100}" y2="${Math.random() * 40}"
stroke="${randomColor()}" stroke-width="1"/>
`).join('')}
</svg>
`.trim()
// 转为base64
const base64 = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svg)))
return { code, img: base64 }
}
// 获取验证码
Mock.mock(/\/api\/captchaImage/, 'get', () => {
const uuid = Mock.Random.guid()
const captcha = generateCaptcha()
// 存储验证码
captchaStore[uuid] = captcha.code.toLowerCase()
// 5分钟后过期
setTimeout(() => {
delete captchaStore[uuid]
}, 5 * 60 * 1000)
return {
code: 200,
msg: '操作成功',
img: captcha.img,
uuid: uuid
}
})
// 登录
Mock.mock('/api/login', 'post', (options) => {
const body = JSON.parse(options.body)
const { username, password, code, uuid } = body
// 验证码校验开发环境可以用1234绕过
const storedCode = captchaStore[uuid]
if (code !== '1234' && (!storedCode || storedCode !== code.toLowerCase())) {
return { code: 500, msg: '验证码错误' }
}
// 删除已使用的验证码
delete captchaStore[uuid]
// 账号密码校验
if (username === 'admin' && password === 'admin123') {
return {
code: 200,
msg: '登录成功',
token: Mock.Random.guid()
}
}
return { code: 500, msg: '用户名或密码错误' }
})
// 获取用户信息
Mock.mock(/\/api\/getInfo/, 'get', () => {
return {
code: 200,
msg: '操作成功',
data: {
userId: 1,
userName: 'admin',
nickName: '超级管理员',
avatar: '',
roles: ['admin'],
permissions: ['*:*:*']
}
}
})
// 退出登录
Mock.mock('/api/logout', 'post', () => {
return {
code: 200,
msg: '退出成功'
}
})
// 首页统计数据
Mock.mock(/\/api\/dashboard\/stats/, 'get', () => {
return {
code: 200,
msg: '操作成功',
data: {
schoolCount: Mock.Random.integer(50, 200),
memberCount: Mock.Random.integer(10000, 50000),
studentCount: Mock.Random.integer(50000, 200000),
appCount: Mock.Random.integer(5, 20)
}
}
})