智慧教务系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

520 lines
16 KiB

/**
* UniApp Mock数据服务
* 支持环境变量控制,默认开启Mock数据
* 提供与API响应结构一致的数据格式
*/
import { isMockEnabled, isDebug } from '@/common/config.js'
// Mock数据规则 - 基于MockJS规则
const mockRules = {
// 用户数据规则
user: {
'id|+1': 1,
'username': '@cname',
'phone': /^1[3-9]\d{9}$/,
'avatar': '@image("100x100", "#50B347", "#FFF", "Avatar")',
'email': '@email',
'status|1': ['active', 'inactive'],
'created_at': '@datetime',
'updated_at': '@datetime'
},
// 学生数据规则
student: {
'id|+1': 1,
'name': '@cname',
'student_no': '@string("number", 10)',
'phone': /^1[3-9]\d{9}$/,
'avatar': '@image("100x100", "#50B347", "#FFF", "Student")',
'class_id|1-20': 1,
'status|1': ['active', 'inactive', 'graduated'],
'created_at': '@datetime'
},
// 课程数据规则
course: {
'id|+1': 1,
'name': '@ctitle(5, 15)',
'description': '@cparagraph(1, 3)',
'teacher_id|1-10': 1,
'price|100-1000.2': 1,
'duration|30-120': 1,
'status|1': ['active', 'inactive'],
'created_at': '@datetime'
},
// 课程表数据规则
schedule: {
'id|+1': 1,
'course_id|1-20': 1,
'teacher_id|1-10': 1,
'classroom': '@ctitle(3, 8)',
'date': '@date',
'start_time': '@time',
'end_time': '@time',
'status|1': ['scheduled', 'completed', 'cancelled']
}
}
// 生成Mock数据的函数
function generateMockData(rule, count = 1) {
const result = []
for (let i = 0; i < count; i++) {
const item = {}
for (const key in rule) {
if (key.includes('|')) {
const [field, mockRule] = key.split('|')
if (mockRule.includes('+')) {
item[field] = i + 1
} else if (mockRule.includes('-')) {
const [min, max] = mockRule.split('-')
item[field] = Math.floor(Math.random() * (max - min + 1)) + parseInt(min)
} else if (mockRule === '1') {
const options = rule[key]
item[field] = Array.isArray(options) ?
options[Math.floor(Math.random() * options.length)] :
options
}
} else {
item[key] = rule[key]
}
}
result.push(item)
}
return count === 1 ? result[0] : result
}
// Mock数据存储
const mockData = {
// 用户相关数据
users: generateMockData(mockRules.user, 50),
students: generateMockData(mockRules.student, 100),
courses: generateMockData(mockRules.course, 30),
schedules: generateMockData(mockRules.schedule, 200),
// 登录用户信息
currentUser: {
id: 1,
username: '张三',
phone: '13800138000',
avatar: 'https://via.placeholder.com/100x100?text=User',
email: 'zhangsan@example.com',
status: 'active',
role: 'student',
created_at: '2024-01-01 10:00:00',
updated_at: '2024-01-01 10:00:00'
},
// 学员信息 (xy_memberInfo)
memberInfo: {
id: 1001,
name: '李小明',
student_no: 'ST202401001',
phone: '13800138001',
age: 15,
gender: 1, // 1男 2女
classes_count: 8, // 我的课程数
sign_count: 15, // 已上课时
stay_sign_count: 5, // 待上课时
created_at: '2024-01-01 08:00:00',
memberHasOne: {
headimg: 'https://via.placeholder.com/144x144?text=Student',
id: 1001
},
customerResources: {
member: {
headimg: 'https://via.placeholder.com/144x144?text=Student'
}
}
},
// 体测数据 (xy_physicalTest)
physicalTestData: {
data: [
{
id: 1,
resource_id: 1001,
height: 165,
weight: 55,
calculateChildHealthScore: 85,
created_at: '2024-01-10 14:30:00',
bmi: 20.2,
test_items: {
flexibility: 78,
strength: 85,
endurance: 82
}
}
],
total: 1,
page: 1,
pages: 1
},
// 课程安排数据 (xy_personCourseSchedule)
personCourseSchedule: {
data: [
{
id: 2001,
resources_id: 1001,
course_date: '2024-01-16',
time_slot: '09:00-10:30',
status: '0', // 0待上课 1已上课 2请假
courseScheduleHasOne: {
venue: {
venue_name: '篮球馆A'
},
course: {
course_name: '青少年篮球训练'
}
},
created_at: '2024-01-15 10:00:00'
},
{
id: 2002,
resources_id: 1001,
course_date: '2024-01-18',
time_slot: '14:00-15:30',
status: '0',
courseScheduleHasOne: {
venue: {
venue_name: '足球场B'
},
course: {
course_name: '足球基础课'
}
},
created_at: '2024-01-15 10:00:00'
}
],
total: 2,
page: 1,
pages: 1
},
// 作业数据 (xy_assignment)
assignmentData: {
data: [
{
id: 3001,
resources_id: 1001,
description: '完成本周的体能训练视频拍摄,展示标准动作',
content_type: 2, // 1图片 2视频 3文本
content_text: 'https://example.com/video.mp4',
status: '2', // 1待批改 2未提交 3已提交
created_at: '2024-01-14 16:00:00',
student: {
name: '李小明',
customerResources: {
member: {
headimg: 'https://via.placeholder.com/50x50?text=Student'
}
}
}
},
{
id: 3002,
resources_id: 1001,
description: '上传训练心得体会,字数不少于200字',
content_type: 3,
content_text: '今天的训练很充实,学到了很多新的技巧...',
status: '3',
created_at: '2024-01-12 10:00:00',
student: {
name: '李小明',
customerResources: {
member: {
headimg: 'https://via.placeholder.com/50x50?text=Student'
}
}
}
}
],
total: 2,
page: 1,
pages: 1
},
// 日历数据 (xy_personCourseScheduleGetCalendar)
calendarData: {
'2024-01-15': [
{
id: 2001,
course_name: '篮球训练',
time_slot: '09:00-10:30',
status: 'scheduled'
}
],
'2024-01-16': [
{
id: 2002,
course_name: '足球基础',
time_slot: '14:00-15:30',
status: 'scheduled'
}
]
},
// 教练信息 (xy_personCourseScheduleGetMyCoach)
coachData: {
data: [
{
id: 5001,
name: '王教练',
phone: '13800135001',
specialty: '篮球',
experience: '5年教学经验',
avatar: 'https://via.placeholder.com/100x100?text=Coach',
introduction: '专业篮球教练,擅长青少年基础训练和技能提升',
courses: ['青少年篮球', '篮球进阶训练']
}
],
total: 1
},
// 学生课程表
studentSchedules: [
{
id: 1,
course_name: '数学基础',
teacher_name: '王老师',
classroom: '101教室',
date: '2024-01-15',
start_time: '09:00',
end_time: '10:30',
status: 'scheduled'
},
{
id: 2,
course_name: '英语口语',
teacher_name: '李老师',
classroom: '202教室',
date: '2024-01-15',
start_time: '14:00',
end_time: '15:30',
status: 'scheduled'
}
],
// 考试成绩
examResults: [
{
id: 1,
exam_name: '期中考试',
course_name: '数学',
score: 85,
total_score: 100,
rank: 5,
exam_date: '2024-01-10',
status: 'published'
},
{
id: 2,
exam_name: '期末考试',
course_name: '英语',
score: 92,
total_score: 100,
rank: 2,
exam_date: '2024-01-12',
status: 'published'
}
]
}
// Mock服务类
class MockService {
constructor() {
this.enabled = isMockEnabled
this.debug = isDebug
this.init()
}
init() {
if (this.debug) {
console.log('Mock服务状态:', this.enabled ? '已启用' : '已禁用')
}
}
// 统一的响应格式
createResponse(data, code = 200, message = 'success') {
return {
code,
message,
data,
timestamp: Date.now()
}
}
// 分页响应格式
createPaginatedResponse(list, page = 1, size = 10, total = null) {
const actualTotal = total || list.length
const start = (page - 1) * size
const end = start + size
const paginatedList = list.slice(start, end)
return this.createResponse({
list: paginatedList,
total: actualTotal,
page: parseInt(page),
size: parseInt(size),
pages: Math.ceil(actualTotal / size)
})
}
// 模拟网络延迟
async delay(ms = 500) {
return new Promise(resolve => setTimeout(resolve, ms))
}
// 获取Mock数据
async getMockData(endpoint, params = {}) {
if (!this.enabled) {
return null
}
await this.delay()
// 根据端点返回相应的Mock数据 - 支持完整URL和方法名匹配
const checkEndpoint = (patterns) => {
return patterns.some(pattern => endpoint.includes(pattern))
}
// 学员信息
if (checkEndpoint(['/customerResourcesAuth/info', 'xy_memberInfo'])) {
return this.createResponse(mockData.memberInfo, 1, 'success')
}
// 体测数据
if (checkEndpoint(['/xy/physicalTest', 'xy_physicalTest'])) {
return this.createResponse(mockData.physicalTestData, 1, 'success')
}
// 课程安排
if (checkEndpoint(['/xy/personCourseSchedule', 'xy_personCourseSchedule']) && !endpoint.includes('getCalendar') && !endpoint.includes('getMyCoach')) {
// 根据status参数过滤数据
let scheduleData = mockData.personCourseSchedule.data
if (params.status !== undefined) {
scheduleData = scheduleData.filter(item => item.status === params.status)
}
return this.createResponse({
data: scheduleData,
total: scheduleData.length,
page: params.page || 1,
pages: Math.ceil(scheduleData.length / (params.limit || 10))
}, 1, 'success')
}
// 日历数据
if (checkEndpoint(['/xy/personCourseSchedule/getCalendar', 'xy_personCourseScheduleGetCalendar'])) {
return this.createResponse(mockData.calendarData, 1, 'success')
}
// 教练信息
if (checkEndpoint(['/xy/personCourseSchedule/getMyCoach', 'xy_personCourseScheduleGetMyCoach'])) {
return this.createResponse(mockData.coachData, 1, 'success')
}
// 作业列表
if (checkEndpoint(['/xy/assignment', 'xy_assignment']) && !endpoint.includes('/info') && !endpoint.includes('submitObj')) {
// 根据status参数过滤作业数据
let assignmentData = mockData.assignmentData.data
if (params.status !== undefined) {
assignmentData = assignmentData.filter(item => item.status === params.status)
}
return this.createResponse({
data: assignmentData,
total: assignmentData.length,
page: params.page || 1,
pages: Math.ceil(assignmentData.length / (params.limit || 10))
}, 1, 'success')
}
// 作业详情
if (checkEndpoint(['/xy/assignment/info', 'xy_assignmentsInfo'])) {
const assignmentId = params.id || params.assignment_id
const assignment = mockData.assignmentData.data.find(item => item.id == assignmentId)
return this.createResponse(assignment || {}, assignment ? 1 : 0, assignment ? 'success' : '作业不存在')
}
// 作业提交
if (checkEndpoint(['/xy/assignment/submitObj', 'xy_assignmentSubmitObj'])) {
return this.createResponse({}, 1, '作业提交成功')
}
// 学生登录
if (checkEndpoint(['/xy/login', 'xy_login'])) {
return this.createResponse({
token: 'mock_token_' + Date.now(),
user: mockData.memberInfo,
expires_in: 7200
}, 1, '登录成功')
}
// 原有的通用接口
switch (endpoint) {
case '/user/info':
return this.createResponse(mockData.currentUser)
case '/student/schedule':
return this.createResponse(mockData.studentSchedules)
case '/student/exam/results':
return this.createResponse(mockData.examResults)
case '/courses':
return this.createPaginatedResponse(
mockData.courses,
params.page || 1,
params.size || 10
)
case '/students':
return this.createPaginatedResponse(
mockData.students,
params.page || 1,
params.size || 10
)
default:
return this.createResponse(null, 404, '接口未找到')
}
}
// 检查是否应该使用Mock数据
shouldUseMock(url) {
if (!this.enabled) return false
// 定义需要Mock的接口列表
const mockableEndpoints = [
'/user/info',
'/student/schedule',
'/student/exam/results',
'/courses',
'/students',
// 学员端专用API - URL匹配
'/customerResourcesAuth/info', // xy_memberInfo
'/xy/physicalTest', // xy_physicalTest
'/xy/personCourseSchedule', // xy_personCourseSchedule相关
'/xy/assignment', // xy_assignment相关
'/xy/login', // xy_login
// 学员端专用API - 方法名匹配(用于开发调试)
'xy_memberInfo',
'xy_physicalTest',
'xy_personCourseSchedule',
'xy_assignment',
'xy_assignmentsInfo',
'xy_assignmentSubmitObj',
'xy_personCourseScheduleGetCalendar',
'xy_personCourseScheduleGetMyCoach',
'xy_login'
]
return mockableEndpoints.some(endpoint => url.includes(endpoint))
}
}
// 创建全局Mock服务实例
const mockService = new MockService()
export default mockService