| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537 |
- // 教学活动分析相关接口
- import { moduleRequest } from '@/utils/request'
- import Mock from 'mockjs'
- const request = moduleRequest(`/api/webapp/`)
- // Mock 数据配置
- Mock.setup({
- timeout: '200-600'
- })
- // 课程选项数据
- const courseOptions = [
- { value: '', label: '全部课程' },
- { value: 'course1', label: 'JavaScript基础教程' },
- { value: 'course2', label: 'Python数据分析' },
- { value: 'course3', label: 'React前端开发' },
- { value: 'course4', label: '机器学习入门' },
- { value: 'course5', label: 'Vue.js实战开发' },
- { value: 'course6', label: 'Node.js后端开发' }
- ]
- // 生成日期数据
- const generateDateData = (days) => {
- const dates = []
- const today = new Date()
- for (let i = days - 1; i >= 0; i--) {
- const date = new Date(today)
- date.setDate(date.getDate() - i)
- dates.push(date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' }))
- }
- return dates
- }
- // 生成访问数据
- const generateVisitData = (days, courseId = '') => {
- const data = []
- // 全部课程的访问量应该比单个课程高
- const courseMultiplier = courseId ? 0.15 + Math.random() * 0.25 : 1.0
- for (let i = 0; i < days; i++) {
- const dayOfWeek = (new Date().getDay() - days + i + 7) % 7
- const isWeekend = dayOfWeek === 0 || dayOfWeek === 6
- // 全部课程基础访问量更高
- const baseValue = isWeekend ? 450 : 680
- const randomFactor = 0.7 + Math.random() * 0.6
- const finalValue = Math.round(baseValue * randomFactor * courseMultiplier)
- data.push(finalValue)
- }
- return data
- }
- // 讨论数据 - 这是全部课程的汇总讨论数据
- const discussionData = [
- {
- id: 1,
- title: 'JavaScript闭包概念理解',
- author: '张三',
- createTime: '2024-01-15 10:30',
- replyCount: 25,
- lastReplyTime: '2024-01-16 14:20'
- },
- {
- id: 2,
- title: 'Python数据分析库选择',
- author: '李四',
- createTime: '2024-01-14 16:45',
- replyCount: 18,
- lastReplyTime: '2024-01-15 09:15'
- },
- {
- id: 3,
- title: 'React组件生命周期',
- author: '王五',
- createTime: '2024-01-13 11:20',
- replyCount: 32,
- lastReplyTime: '2024-01-14 17:30'
- },
- {
- id: 4,
- title: '机器学习算法选择',
- author: '赵六',
- createTime: '2024-01-12 14:15',
- replyCount: 16,
- lastReplyTime: '2024-01-13 10:45'
- },
- {
- id: 5,
- title: '前端性能优化技巧',
- author: '钱七',
- createTime: '2024-01-11 09:30',
- replyCount: 45,
- lastReplyTime: '2024-01-15 16:20'
- },
- {
- id: 6,
- title: 'Vue3 Composition API使用心得',
- author: '孙八',
- createTime: '2024-01-10 15:20',
- replyCount: 38,
- lastReplyTime: '2024-01-14 11:30'
- },
- {
- id: 7,
- title: 'Node.js异步编程最佳实践',
- author: '周九',
- createTime: '2024-01-09 13:45',
- replyCount: 29,
- lastReplyTime: '2024-01-13 16:15'
- },
- {
- id: 8,
- title: '数据库索引优化策略',
- author: '陈十',
- createTime: '2024-01-08 11:20',
- replyCount: 22,
- lastReplyTime: '2024-01-12 15:40'
- },
- {
- id: 9,
- title: 'Web安全防护实践',
- author: '刘十一',
- createTime: '2024-01-07 14:30',
- replyCount: 19,
- lastReplyTime: '2024-01-11 09:25'
- },
- {
- id: 10,
- title: '移动端适配解决方案',
- author: '杨十二',
- createTime: '2024-01-06 16:15',
- replyCount: 27,
- lastReplyTime: '2024-01-10 13:50'
- },
- {
- id: 11,
- title: 'TypeScript类型系统深入',
- author: '黄十三',
- createTime: '2024-01-05 10:45',
- replyCount: 34,
- lastReplyTime: '2024-01-09 17:20'
- },
- {
- id: 12,
- title: 'Docker容器化部署',
- author: '吴十四',
- createTime: '2024-01-04 13:20',
- replyCount: 21,
- lastReplyTime: '2024-01-08 11:15'
- },
- {
- id: 13,
- title: 'GraphQL API设计',
- author: '郑十五',
- createTime: '2024-01-03 15:40',
- replyCount: 15,
- lastReplyTime: '2024-01-07 14:30'
- },
- {
- id: 14,
- title: '微服务架构实践',
- author: '王十六',
- createTime: '2024-01-02 09:15',
- replyCount: 28,
- lastReplyTime: '2024-01-06 16:45'
- },
- {
- id: 15,
- title: 'Redis缓存策略',
- author: '李十七',
- createTime: '2024-01-01 11:30',
- replyCount: 23,
- lastReplyTime: '2024-01-05 12:20'
- }
- ]
- // 文档数据 - 这是全部课程的汇总数据,数量较大
- const documentData = [
- {
- id: 1,
- name: 'JavaScript基础语法',
- type: 'PDF文档',
- viewCount: 4856,
- completedCount: 3234,
- completionRate: 66.5,
- avgReadTime: '25:30',
- exitRate: 24.6,
- downloadCount: 1456
- },
- {
- id: 2,
- name: 'Python数据分析入门',
- type: '在线文档',
- viewCount: 3234,
- completedCount: 2587,
- completionRate: 80.0,
- avgReadTime: '32:15',
- exitRate: 18.5,
- downloadCount: 1234
- },
- {
- id: 3,
- name: 'React组件开发指南',
- type: 'PDF文档',
- viewCount: 2987,
- completedCount: 2289,
- completionRate: 76.6,
- avgReadTime: '28:45',
- exitRate: 22.3,
- downloadCount: 989
- },
- {
- id: 4,
- name: '机器学习算法详解',
- type: '在线文档',
- viewCount: 2756,
- completedCount: 1908,
- completionRate: 69.2,
- avgReadTime: '45:20',
- exitRate: 30.8,
- downloadCount: 823
- },
- {
- id: 5,
- name: '前端工程化实践',
- type: 'PDF文档',
- viewCount: 2523,
- completedCount: 1665,
- completionRate: 66.0,
- avgReadTime: '38:15',
- exitRate: 34.0,
- downloadCount: 689
- },
- {
- id: 6,
- name: 'Vue.js进阶开发',
- type: '在线文档',
- viewCount: 2678,
- completedCount: 1802,
- completionRate: 67.3,
- avgReadTime: '35:40',
- exitRate: 32.7,
- downloadCount: 756
- },
- {
- id: 7,
- name: 'Node.js后端开发',
- type: 'PDF文档',
- viewCount: 2345,
- completedCount: 1567,
- completionRate: 66.8,
- avgReadTime: '42:10',
- exitRate: 28.9,
- downloadCount: 634
- },
- {
- id: 8,
- name: '数据库设计原理',
- type: '在线文档',
- viewCount: 2123,
- completedCount: 1489,
- completionRate: 70.1,
- avgReadTime: '38:25',
- exitRate: 26.4,
- downloadCount: 567
- },
- {
- id: 9,
- name: 'Web安全防护',
- type: 'PDF文档',
- viewCount: 1987,
- completedCount: 1345,
- completionRate: 67.7,
- avgReadTime: '33:50',
- exitRate: 29.8,
- downloadCount: 498
- },
- {
- id: 10,
- name: '移动端开发实战',
- type: '在线文档',
- viewCount: 1876,
- completedCount: 1234,
- completionRate: 65.8,
- avgReadTime: '40:15',
- exitRate: 31.2,
- downloadCount: 445
- }
- ]
- // 生成课程选项数据
- const generateCourseOptions = () => {
- return {
- code: 200,
- message: '获取成功',
- data: courseOptions
- }
- }
- // 生成核心统计数据
- const generateStatsData = (options) => {
- const urlParts = options.url.split('?')
- const params = urlParts.length > 1 ? new URLSearchParams(urlParts[1]) : new URLSearchParams()
- const courseId = params.get('courseId') || ''
- const timeRange = parseInt(params.get('timeRange')) || 30
- // 全部课程的数据应该是所有课程的总和,单个课程数据相对较少
- const baseMultiplier = courseId ? 0.15 + Math.random() * 0.25 : 1.0 // 单个课程占总数的15%-40%
- const timeMultiplier = timeRange / 30
- // 基础数据 - 全部课程的总数据
- const baseStats = {
- totalDocViewers: 8560,
- completedDocViewers: 6234,
- totalDocExits: 1890,
- totalDiscussions: 1456,
- totalReplies: 8934
- }
- const calculatedStats = {
- totalDocViewers: Math.round(baseStats.totalDocViewers * baseMultiplier * timeMultiplier),
- completedDocViewers: Math.round(baseStats.completedDocViewers * baseMultiplier * timeMultiplier),
- totalDocExits: Math.round(baseStats.totalDocExits * baseMultiplier * timeMultiplier),
- totalDiscussions: Math.round(baseStats.totalDiscussions * baseMultiplier * timeMultiplier),
- totalReplies: Math.round(baseStats.totalReplies * baseMultiplier * timeMultiplier)
- }
- // 确保完成人数不超过总观看人数
- if (calculatedStats.completedDocViewers > calculatedStats.totalDocViewers) {
- calculatedStats.completedDocViewers = Math.round(calculatedStats.totalDocViewers * 0.7)
- }
- // 计算完成率
- const docCompletionRate =
- calculatedStats.totalDocViewers > 0
- ? parseFloat(((calculatedStats.completedDocViewers / calculatedStats.totalDocViewers) * 100).toFixed(1))
- : 0
- // 计算跳出率 - 单个课程跳出率可能更高
- const baseExitRate = courseId ? 25 + Math.random() * 15 : 18 + Math.random() * 12
- const docExitRate = parseFloat(baseExitRate.toFixed(1))
- // 计算平均回帖数
- const avgRepliesPerDiscussion =
- calculatedStats.totalDiscussions > 0
- ? parseFloat((calculatedStats.totalReplies / calculatedStats.totalDiscussions).toFixed(1))
- : 0
- return {
- code: 200,
- message: '获取成功',
- data: {
- totalDocViewers: calculatedStats.totalDocViewers,
- completedDocViewers: calculatedStats.completedDocViewers,
- docCompletionRate,
- totalDocExits: calculatedStats.totalDocExits,
- docExitRate,
- avgDocExitTime: `${String(Math.floor(Math.random() * 15) + 8).padStart(2, '0')}:${String(
- Math.floor(Math.random() * 60)
- ).padStart(2, '0')}`,
- totalDiscussions: calculatedStats.totalDiscussions,
- totalReplies: calculatedStats.totalReplies,
- avgRepliesPerDiscussion
- }
- }
- }
- // 生成每周统计数据
- const generateWeeklyStatsData = (options) => {
- const urlParts = options.url.split('?')
- const params = urlParts.length > 1 ? new URLSearchParams(urlParts[1]) : new URLSearchParams()
- const courseId = params.get('courseId') || ''
- // 全部课程数据应该是所有课程的总和
- const baseMultiplier = courseId ? 0.12 + Math.random() * 0.28 : 1.0 // 单个课程占总数的12%-40%
- // 基础数据 - 全部课程的总数据
- const baseWeeklyStats = {
- studentWeeklyPosts: 456,
- studentWeeklyReplies: 1678,
- teacherWeeklyPosts: 123,
- teacherWeeklyReplies: 567
- }
- const calculatedStats = {
- studentWeeklyPosts: Math.round(baseWeeklyStats.studentWeeklyPosts * baseMultiplier),
- studentWeeklyReplies: Math.round(baseWeeklyStats.studentWeeklyReplies * baseMultiplier),
- teacherWeeklyPosts: Math.round(baseWeeklyStats.teacherWeeklyPosts * baseMultiplier),
- teacherWeeklyReplies: Math.round(baseWeeklyStats.teacherWeeklyReplies * baseMultiplier)
- }
- return {
- code: 200,
- message: '获取成功',
- data: {
- studentWeeklyPosts: calculatedStats.studentWeeklyPosts,
- studentWeeklyReplies: calculatedStats.studentWeeklyReplies,
- studentAvgPostsPerDay: parseFloat((calculatedStats.studentWeeklyPosts / 7).toFixed(1)),
- teacherWeeklyPosts: calculatedStats.teacherWeeklyPosts,
- teacherWeeklyReplies: calculatedStats.teacherWeeklyReplies,
- teacherAvgPostsPerDay: parseFloat((calculatedStats.teacherWeeklyPosts / 7).toFixed(1))
- }
- }
- }
- // 生成每日访问数据
- const generateDailyVisitsData = (options) => {
- const urlParts = options.url.split('?')
- const params = urlParts.length > 1 ? new URLSearchParams(urlParts[1]) : new URLSearchParams()
- const courseId = params.get('courseId') || ''
- const timeRange = parseInt(params.get('timeRange')) || 30
- const dates = generateDateData(timeRange)
- const visits = generateVisitData(timeRange, courseId)
- return {
- code: 200,
- message: '获取成功',
- data: {
- dates,
- visits
- }
- }
- }
- // 生成讨论数据
- const generateDiscussionData = (options) => {
- const urlParts = options.url.split('?')
- const params = urlParts.length > 1 ? new URLSearchParams(urlParts[1]) : new URLSearchParams()
- const courseId = params.get('courseId') || ''
- const page = parseInt(params.get('page')) || 1
- const pageSize = parseInt(params.get('pageSize')) || 10
- let filteredData = discussionData
- if (courseId) {
- // 单个课程只显示部分讨论数据,模拟该课程相关的讨论
- const courseDiscussionCount = Math.floor(discussionData.length * (0.2 + Math.random() * 0.3)) // 20%-50%
- filteredData = discussionData.slice(0, Math.max(courseDiscussionCount, 2)) // 至少显示2条
- }
- const startIndex = (page - 1) * pageSize
- const endIndex = startIndex + pageSize
- const pageData = filteredData.slice(startIndex, endIndex)
- return {
- code: 200,
- message: '获取成功',
- data: {
- list: pageData,
- total: filteredData.length,
- page,
- pageSize
- }
- }
- }
- // 生成文档数据
- const generateDocumentData = (options) => {
- const urlParts = options.url.split('?')
- const params = urlParts.length > 1 ? new URLSearchParams(urlParts[1]) : new URLSearchParams()
- const courseId = params.get('courseId') || ''
- const page = parseInt(params.get('page')) || 1
- const pageSize = parseInt(params.get('pageSize')) || 10
- let filteredData = [...documentData]
- if (courseId) {
- // 单个课程只显示该课程相关的文档,数量相对较少
- const courseDocumentCount = Math.floor(documentData.length * (0.25 + Math.random() * 0.35)) // 25%-60%
- filteredData = documentData.slice(0, Math.max(courseDocumentCount, 3)) // 至少显示3条
- // 调整单个课程文档的数据,使其相对较小但合理
- filteredData = filteredData.map((doc) => ({
- ...doc,
- viewCount: Math.round(doc.viewCount * (0.15 + Math.random() * 0.25)), // 15%-40%的观看量
- completedCount: Math.round(doc.completedCount * (0.15 + Math.random() * 0.25)),
- downloadCount: Math.round(doc.downloadCount * (0.15 + Math.random() * 0.25)),
- // 完成率和跳出率保持相对合理的范围
- completionRate: parseFloat((doc.completionRate + (Math.random() - 0.5) * 10).toFixed(1)),
- exitRate: parseFloat((doc.exitRate + (Math.random() - 0.5) * 8).toFixed(1))
- }))
- }
- const startIndex = (page - 1) * pageSize
- const endIndex = startIndex + pageSize
- const pageData = filteredData.slice(startIndex, endIndex)
- return {
- code: 200,
- message: '获取成功',
- data: {
- list: pageData,
- total: filteredData.length,
- page,
- pageSize
- }
- }
- }
- // Mock 接口定义
- Mock.mock(/\/api\/webapp\/teaching-analysis\/course-options/, 'get', generateCourseOptions)
- Mock.mock(/\/api\/webapp\/teaching-analysis\/stats/, 'get', generateStatsData)
- Mock.mock(/\/api\/webapp\/teaching-analysis\/weekly-stats/, 'get', generateWeeklyStatsData)
- Mock.mock(/\/api\/webapp\/teaching-analysis\/daily-visits/, 'get', generateDailyVisitsData)
- Mock.mock(/\/api\/webapp\/teaching-analysis\/discussions/, 'get', generateDiscussionData)
- Mock.mock(/\/api\/webapp\/teaching-analysis\/documents/, 'get', generateDocumentData)
- // 导出的API函数
- export const getCourseOptions = (params = {}) => {
- return request('disk/courseinfo/allList', params, 'get')
- }
- // 文档观看统计
- export const getTeachingStats = (params = {}) => {
- return request('teachingActivity/documentStatistic', params, 'get')
- }
- // 文档跳出分析
- export const documentJumpStatistic = (params = {}) => {
- return request('teachingActivity/documentJumpStatistic', params, 'get')
- }
- export const getWeeklyStats = (params = {}) => {
- return request('teaching-analysis/weekly-stats', params, 'get')
- }
- // 开课每日访问人数统计
- export const getDailyVisits = (params = {}) => {
- return request('teachingActivity/courseOpenStatistic', params, 'get')
- }
- export const getDiscussionData = (params = {}) => {
- return request('teaching-analysis/discussions', params, 'get')
- }
- export const getDocumentStats = (params = {}) => {
- return request('teaching-analysis/documents', params, 'get')
- }
|