Compare commits

...

363 Commits

Author SHA1 Message Date
huweihang
f2e188c0e6 feat: 新增根据关键字检索用户的API,增强用户选择功能 2025-12-17 22:50:08 +08:00
huweihang
a9b36884c3 feat: 新增获取全量机构树的API,优化SignupModal和ManageListRemote组件的组织树交互逻辑 2025-12-17 18:48:29 +08:00
huweihang
e176769174 fix: 修改删除报名记录的确认提示文本,更新删除API调用以包含学生ID 2025-12-17 17:45:18 +08:00
huweihang
5f518b713a feat: 增强报名管理功能,新增删除课程学习记录API,优化受众选择弹窗的多选逻辑和搜索功能 2025-12-17 17:44:58 +08:00
huweihang
b2395fd3a2 style: 更新对话框样式,调整按钮尺寸和间距,增强用户界面一致性 2025-12-17 11:38:36 +08:00
huweihang
100ad78c9b style: 添加滚动条样式并调整选区区域的类名以提升用户体验
(cherry picked from commit a6c389b80b)
2025-12-17 02:07:30 +08:00
huweihang
4831da0c47 feat: Add 添加SignupModal组件,并在CourseManage中集成注册功能; 2025-12-17 01:56:52 +08:00
huweihang
e8615ff1db style: 受众弹窗宽度修改 2025-12-17 01:54:41 +08:00
huweihang
9e4f2038f0 feat: 增加报名管理功能,支持添加和删除报名记录,优化受众选择弹窗逻辑 2025-12-17 01:54:17 +08:00
huweihang
3a35a475dd feat: 添加新的受众选择和报名功能,新增多个API请求,更新样式以优化用户体验 2025-12-17 01:44:01 +08:00
huweihang
32e83b6f97 style: 调整index.scss以优化对话框和按钮的样式;更新ManageListRemote.vue以增强下拉框的交互体验和过滤功能。 2025-12-17 01:42:34 +08:00
huweihang
6bee4e8e87 style: 调整对话框和按钮尺寸,更新工具提示文本以提高清晰度,并对教师和创建者的选择实施下拉可见性处理。 2025-12-17 01:23:03 +08:00
huweihang
4ebd8f5225 refactor: 更新注册和AudienceMode组件中的受众管理功能,包括API调整和UI修改。 2025-12-17 01:22:08 +08:00
huweihang
79f068198d feat: 通过注册管理功能增强CourseManage,包括添加和删除操作,以及用于受众选择和注册创建的模块。 2025-12-17 01:21:09 +08:00
huweihang
6cfd0e8720 Merge branch '251114-feature-course-online' into 251114-feature-course-online-hwh
# Conflicts:
#	src/views/course/CourseManage.vue
2025-12-17 01:11:21 +08:00
huweihang
ed672905f2 [FIX]新增受众弹窗 2025-12-16 18:42:37 +08:00
赵依梦
626f1dbd21 一期问题修改 2025-12-16 18:13:21 +08:00
huweihang
80299d231e [FIX]"全部"移除
(cherry picked from commit 2f1ea68c70)
2025-12-16 15:20:09 +08:00
huweihang
2f1ea68c70 [FIX]"全部"移除 2025-12-16 15:19:40 +08:00
huweihang
7a28e362f7 [FIX]全部还原 2025-12-16 15:18:46 +08:00
赵依梦
f2d57c8d98 一期问题修改 2025-12-16 14:12:46 +08:00
huweihang
e12437484b feat: Add 添加SignupModal组件,并在CourseManage中集成注册功能; 2025-12-16 01:08:10 +08:00
huweihang
78be53013b Merge branch '251114-feature-course-online' into 251114-feature-course-online-hwh 2025-12-15 21:30:54 +08:00
huweihang
f9c69d074c style: 更新index.scss以增强按钮的颜色对比度;调整ManageListRemote.vue中的过滤器布局,优化用户体验。
(cherry picked from commit c9c714ddfa)
2025-12-15 17:30:55 +08:00
huweihang
c9c714ddfa style: 更新index.scss以增强按钮的颜色对比度;调整ManageListRemote.vue中的过滤器布局,优化用户体验。 2025-12-15 17:30:38 +08:00
赵依梦
ce4259b0be 教师端1期 姓名搜索组件 2025-12-15 15:32:50 +08:00
赵依梦
bee726ebd2 教师端1期问题修复 2025-12-14 18:22:48 +08:00
huweihang
07506d0fff [FIX]置顶修改、表格居中修改
(cherry picked from commit ffeb5bf0b6)
2025-12-12 23:32:26 +08:00
huweihang
ffeb5bf0b6 [FIX]置顶修改、表格居中修改 2025-12-12 23:32:06 +08:00
赵依梦
5a1d03b02d 教师端部门展示ui调整 学习时间还原 2025-12-12 19:32:27 +08:00
赵依梦
915d90f368 教师端1期问题修复 2025-12-12 18:17:39 +08:00
huweihang
a953c02028 style: 更新ManageListRemote.vue以动态计算授课教师列的最小宽度,优化输入框的最大长度限制,增强用户体验;调整index.scss以修正列表项文本对齐方式。
(cherry picked from commit f680e1c394)
2025-12-12 18:14:29 +08:00
huweihang
f680e1c394 style: 更新ManageListRemote.vue以动态计算授课教师列的最小宽度,优化输入框的最大长度限制,增强用户体验;调整index.scss以修正列表项文本对齐方式。 2025-12-12 18:13:57 +08:00
huweihang
3bb96d29b1 style: 调整ManageListRemote.vue中的选择器样式,优化课程管理界面的操作按钮布局,增强用户体验;更新index.scss以修正列表项内文本对齐方式。
(cherry picked from commit ef926e6418)
2025-12-12 17:21:04 +08:00
huweihang
ef926e6418 style: 调整ManageListRemote.vue中的选择器样式,优化课程管理界面的操作按钮布局,增强用户体验;更新index.scss以修正列表项内文本对齐方式。 2025-12-12 17:20:29 +08:00
huweihang
5454ead5cf style: 更新样式以优化课程管理界面,调整消息框和过滤器布局,增强用户体验。
(cherry picked from commit 2d06dde984)
2025-12-12 15:14:17 +08:00
huweihang
2d06dde984 style: 更新样式以优化课程管理界面,调整消息框和过滤器布局,增强用户体验。 2025-12-12 15:13:37 +08:00
赵依梦
9ae159d047 教师端1期问题修复 2025-12-12 10:09:36 +08:00
huweihang
794177b358 [FIX]新增 tooltip
(cherry picked from commit 5cd85a3e15)
2025-12-12 09:15:14 +08:00
huweihang
4c1c9b2afe [FIX]资源归属样式修改
(cherry picked from commit 89364b1aef)
2025-12-12 09:15:09 +08:00
huweihang
574897263c style: 添加自定义确认对话框样式,优化ManageListRemote.vue的过滤器布局与样式,更新课程管理相关功能以提升用户体验。
(cherry picked from commit a34f87410f)
2025-12-12 09:14:53 +08:00
huweihang
489f4d6559 feat: 添加课程管理相关功能,新增显示置顶功能的API接口,并优化ManageListRemote.vue的过滤器布局与样式,提升用户体验。
(cherry picked from commit 361675c369)
2025-12-12 09:14:38 +08:00
huweihang
5cd85a3e15 [FIX]新增 tooltip 2025-12-12 01:48:05 +08:00
huweihang
89364b1aef [FIX]资源归属样式修改 2025-12-12 01:23:20 +08:00
huweihang
a34f87410f style: 添加自定义确认对话框样式,优化ManageListRemote.vue的过滤器布局与样式,更新课程管理相关功能以提升用户体验。 2025-12-12 01:12:54 +08:00
huweihang
361675c369 feat: 添加课程管理相关功能,新增显示置顶功能的API接口,并优化ManageListRemote.vue的过滤器布局与样式,提升用户体验。 2025-12-11 18:47:15 +08:00
赵依梦
8eb678e180 教师端1期需求ui优化 2025-12-11 18:07:58 +08:00
赵依梦
bc8c0004f8 教师端1期需求ui优化 2025-12-11 12:01:08 +08:00
huweihang
2bd430aee2 [FIX]授课教师、全部资源归属、创建人最大长度修改 2025-12-10 18:54:04 +08:00
huweihang
5dcb12f26a Enhance ManageListRemote.vue: 更新输入框占位符,强制设置输入框最大长度,改进教师与创作者选项标签,并应用自定义滚动条样式以提升界面一致性。 2025-12-10 15:05:13 +08:00
huweihang
52d51a53fd [FXI]在线管理列表函数打印 2025-12-10 10:48:46 +08:00
huweihang
d125990697 feat: 添加课程管理新版组件及路由,更新ManageListRemote.vue以优化查询按钮文本和二维码功能 2025-12-09 18:29:09 +08:00
huweihang
83665ae4ed style #app样式修改 2025-12-08 21:54:01 +08:00
huweihang
b259082c10 Update scrollbar 滚动条样式:增加边框半径并调整尺寸以提高美观度。 2025-12-08 21:50:35 +08:00
huweihang
48cb64df63 Refactor ManageListRemote.vue: 使用管理列表的新类更新布局,重构过滤器操作,并增强分页和滚动条的样式。 2025-12-08 21:46:14 +08:00
赵依梦
223e3abe43 教师端1期需求 2025-12-07 11:32:25 +08:00
赵依梦
e7581efddf Merge branch '251114-feature-course-online' of https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/learning-system-portal into 251114-feature-course-online
# Conflicts:
#	src/api/modules/course.js
#	src/data/pages.js
2025-12-07 11:17:47 +08:00
赵依梦
57b233601d 教师端1期需求 2025-12-07 11:03:44 +08:00
huweihang
e53da5d324 feat:新增用户检索功能,更新课程管理页面,添加课程置顶排序组件,优化课程管理列表,支持新课程管理视图。 2025-12-05 17:40:09 +08:00
陈昱达
e6b319bce3 Merge remote-tracking branch 'origin/master' into 251114-feature-course-online
# Conflicts:
#	src/views/portal/course/Index.vue
2025-11-18 10:09:54 +08:00
joshen
bf20eced9b Merge branch 'master' into ebiz-uat-2025-11-06 2025-11-17 18:58:49 +08:00
670788339
8f2da1c736 取消processStatus setup写法 2025-11-17 18:25:29 +08:00
赵依梦
c11fb55ce3 课程列表侧边栏修改 课程详情评分修改 课程详情章节目录修改 2025-11-17 16:11:14 +08:00
670788339
322172edec Merge branch 'master-20251023-tag' into merge-20251113-tag
# Conflicts:
#	src/components/Course/courseTag.vue
2025-11-17 13:28:18 +08:00
670788339
c801dc8a3d 精品课导航样式 2025-11-14 10:32:42 +08:00
670788339
838e704ab0 精品课导航样式 2025-11-14 08:58:42 +08:00
670788339
d3e891e5cc 精品课导航样式 2025-11-14 08:45:27 +08:00
670788339
40ac85f1fe 在线标签提示改版 2025-11-13 18:43:33 +08:00
670788339
6ee8eaca00 课程库样式调整 2025-11-13 14:29:23 +08:00
670788339
d78cc1f97c 标签选择后直接关闭下拉框 2025-11-13 09:00:48 +08:00
670788339
2576174e95 当输入文字与标签匹配时 选择下拉框匹配标签 手动输入文字未直接消失 2025-11-13 08:51:51 +08:00
670788339
7316215809 当输入文字与标签匹配时 选择下拉框匹配标签 手动输入文字未直接消失 2025-11-13 08:47:31 +08:00
670788339
c5e794ef45 Merge branch 'master-20251023-tag' into merge-20251113-tag 2025-11-12 17:16:17 +08:00
670788339
720cff1d1e 提示修改 2025-11-12 14:54:24 +08:00
hz
f3cc59d313 feat: 修复 setup 异常 2025-11-12 12:41:34 +08:00
670788339
dc57becb0d 精品课点击全部未显示选中 2025-11-12 11:20:11 +08:00
670788339
a94d101853 还原 2025-11-12 10:55:35 +08:00
670788339
426ed75bc3 精品课全部切换 2025-11-12 10:51:14 +08:00
670788339
7e8b807825 标签提示样式调整 2025-11-12 10:19:26 +08:00
670788339
bf13c953be 标签提示 2025-11-12 09:17:39 +08:00
670788339
8d07122420 标签提示 2025-11-12 09:05:16 +08:00
670788339
471a790010 课程详情页 标签与x人学习 留点间距 2025-11-11 18:13:01 +08:00
670788339
d39e1e98ef 提示文案更改 2025-11-11 18:06:29 +08:00
670788339
a82a65da8e 课程库样式调整 2025-11-11 16:58:59 +08:00
670788339
2070466786 在线课标签样式 2025-11-11 16:38:51 +08:00
670788339
57d9f9b483 课程库标签高亮显示 2025-11-11 15:42:36 +08:00
670788339
1710e34f89 全部选中样式 2025-11-11 14:26:57 +08:00
670788339
e292a57b20 课程详情页标签样式 2025-11-11 10:44:24 +08:00
670788339
88c83af460 1111修改课程库内容导航底色样式 2025-11-11 09:10:04 +08:00
670788339
a78bac9368 1110修改样式 2025-11-10 19:26:10 +08:00
670788339
f121a2aaf9 1110修改样式 2025-11-10 19:01:19 +08:00
670788339
8228b33cb0 提示 2025-11-10 18:49:54 +08:00
670788339
702255d9d0 精品课标签导航调整样式 2025-11-10 10:29:56 +08:00
670788339
df3e246d25 精品课标签导航取消加粗 2025-11-10 10:24:02 +08:00
670788339
1d20f11861 精品类型加标签 2025-11-10 08:54:17 +08:00
670788339
d5ec4c1833 开发 2025-11-09 16:25:03 +08:00
670788339
89a9be76d4 开发 2025-11-09 15:25:13 +08:00
670788339
73026b0ab5 在线标签无数据显示调整 2025-11-08 14:46:53 +08:00
670788339
9b11cc3f92 课程详情页标签调整 2025-11-08 11:42:43 +08:00
670788339
372a7c22ed 搜索条件取消红色标记 2025-11-08 09:29:40 +08:00
670788339
2678d22302 修改导航区域结构 2025-11-08 09:06:44 +08:00
hz
914b80c374 Merge branch '20250922-cyd' into ebiz-uat-2025-11-06
# Conflicts:
#	src/views/portal/case/Index.vue
#	src/views/portal/case/components/messages.vue
#	src/views/portal/case/components/sendMessage.vue
2025-11-06 09:45:06 +08:00
陈昱达
5d81f72f5f feat(ai-call):优化AI对话组件初始化逻辑
- 添加组件准备就绪状态标识
- 确保组件挂载完成后再执行自动滚动
-重置对话时正确处理组件状态
- 避免未初始化完成时的滚动操作
2025-11-06 17:20:26 +08:00
陈昱达
c9c34501ce feat(ai-call): 实现对话框尺寸和位置状态持久化
- 添加对话框尺寸状态保存与恢复功能
- 支持通过 sessionStorage 存储对话框宽高及坐标
-优化欢迎消息区域高度计算逻辑- 移除旧的状态处理机制,采用事件驱动方式- 确保在无保存状态时使用默认尺寸配置
2025-11-06 16:42:14 +08:00
陈昱达
1812c0901c feat(portal): 调整AI通话弹窗宽度
- 设置AI通话弹窗默认宽度为800px
- 优化弹窗显示效果和用户体验
2025-11-06 16:29:50 +08:00
陈昱达
13281d8a7d feat(portal): 调整AI通话弹窗宽度
- 设置AI通话弹窗默认宽度为800px
- 优化弹窗显示效果和用户体验
2025-11-06 15:53:38 +08:00
陈昱达
5fdf8efedb fix(portal): 调整AI通话弹窗显示逻辑
- 修改弹窗显示条件,确保仅在最大化状态下显示
- 移除冗余的宽度设置
-优化窗口状态控制逻辑
2025-11-06 15:46:11 +08:00
hz
58f517d2fb Merge remote-tracking branch 'origin/20250922-da' into ebiz-uat-2025-11-06 2025-11-06 09:40:28 +08:00
670788339
ef9e4a0f68 检查标签是否在下拉框中已存在 2025-11-05 14:38:00 +08:00
670788339
a2640771fb 课程库标签样式 2025-11-04 18:50:08 +08:00
670788339
25cb97f462 课程库标签样式 2025-11-04 18:44:09 +08:00
670788339
51c3d29854 样式调整 2025-11-04 17:48:59 +08:00
670788339
c49d69dede 样式调整 2025-11-04 17:35:06 +08:00
670788339
6a764dd698 样式调整 2025-11-04 17:29:39 +08:00
670788339
af10b1fa32 样式调整 2025-11-04 17:16:41 +08:00
陈昱达
1a475c8612 feat(ai-call):优化对话框拖拽与缩放功能- 增强对话框拖拽逻辑,防止事件冒泡
- 完善对话框缩放功能,动态调整欢迎消息区域高度
- 修正机器人欢迎文本中的错别字
- 调整消息列表区域样式,优化滚动条显示
- 监听对话框可见性变化,确保内容正确渲染
2025-11-04 17:14:38 +08:00
Caojr
782bcc31e5 szx-1282 超时清空展示文件 2025-11-04 15:54:23 +08:00
670788339
7be0bdee6c 样式调整 2025-11-04 15:26:21 +08:00
670788339
f88a3a0b53 在线标签交互 2025-11-04 14:58:31 +08:00
Caojr
1a95852912 szx-1282 超时清空展示文件 2025-11-04 14:55:16 +08:00
陈昱达
01e4c676fc feat(portal/case): 增强AI对话窗口交互功能
-为sendMessage组件添加textarea输入框,支持多行输入
- 为AI对话窗口添加拖拽和调整大小功能
- 在最小化窗口中添加关闭按钮- 优化窗口样式和布局,提升用户体验
- 添加拖拽手柄和窗口控制按钮
- 实现窗口位置和大小的动态调整
- 引入open.png图标用于最小化窗口操作
2025-11-04 14:54:51 +08:00
670788339
48ec56dcbc 创建调整 2025-11-04 13:51:02 +08:00
Caojr
f5d865ccc3 szx-1282 增加超时配置 2025-11-04 13:47:02 +08:00
670788339
25c2e673dc 调整计数样式 2025-11-03 19:20:20 +08:00
670788339
78cc822464 调整 2025-11-03 18:37:28 +08:00
670788339
366f1dc45b 标签清除 2025-11-02 18:08:19 +08:00
670788339
4ee6697166 默认提示 2025-11-02 15:28:16 +08:00
670788339
a54c642f4b 标签调整 2025-11-02 10:22:23 +08:00
670788339
6a77bd9dc4 在线新增 2025-11-01 15:04:02 +08:00
670788339
8e51663b86 详情页标签调整 2025-10-31 20:19:35 +08:00
670788339
cbe7981abd 调试 2025-10-31 19:08:54 +08:00
670788339
1ad2816622 调试 2025-10-31 18:21:08 +08:00
670788339
03b3c61c6b 调试 2025-10-31 18:10:32 +08:00
670788339
b3756280cf 调试 2025-10-31 16:58:56 +08:00
670788339
f34d2a6e94 热点标签+保存标签调试 2025-10-31 16:36:07 +08:00
Caojr
65673561d8 szx-1280 编辑时长无效问题修复 2025-10-31 16:16:29 +08:00
670788339
4d5b462b61 热点标签调试 2025-10-31 15:55:13 +08:00
670788339
055476c583 热点标签 2025-10-31 14:54:05 +08:00
670788339
78f681b4cb 热点标签 2025-10-31 13:33:41 +08:00
670788339
520fb4ee5e 取消无分类时限制标签 2025-10-31 11:13:16 +08:00
670788339
ba7bfe5f11 课程库标签 2025-10-31 11:09:09 +08:00
670788339
86bcf06d87 标签输入框下拉调整 日志 2025-10-30 20:08:16 +08:00
670788339
3e1b545d2a 标签输入框下拉调整 2025-10-30 19:42:31 +08:00
670788339
3f028e5cd8 标签输入框调整 2025-10-30 19:10:17 +08:00
670788339
d94bcf96a1 还原释在线保存前创建标签 2025-10-30 15:39:17 +08:00
670788339
36b739d139 注释在线保存前创建标签 2025-10-30 14:10:54 +08:00
Caojr
2cbb379fa6 样式修改 2025-10-29 18:10:07 +08:00
670788339
8bf7a8e8e7 注释在线保存前创建标签 2025-10-29 15:27:43 +08:00
670788339
4b92308d1d 注释在线保存前创建标签 2025-10-29 14:59:23 +08:00
670788339
a25ea0c4ba 注释在线保存前创建标签 2025-10-29 14:46:25 +08:00
670788339
e55aa09409 日志 2025-10-28 16:42:07 +08:00
670788339
5a3b57bd1c Merge branch '104-master' into master-20251023-tag 2025-10-28 15:13:59 +08:00
670788339
6d4af3aa2d 还原视频状态 调试 2025-10-24 13:29:09 +08:00
670788339
b8ba52731f Merge remote-tracking branch 'nyx/20250912-tag-add' into master-20251023-tag 2025-10-24 09:28:26 +08:00
陈昱达
86e25f69f9 feat(portal): 添加消息组件最小化窗口功能
- 在消息组件中新增 getMinWindow事件触发
- 在 AI 呼叫页面监听并处理最小化事件
- 实现窗口状态管理,支持最小化显示
-优化组件间通信逻辑,确保状态同步准确- 修复可能引起状态异常的注释代码问题- 调整样式以适配最小化窗口显示效果
2025-10-23 10:22:40 +08:00
陈昱达
b8daef0983 更新lock 2025-10-15 10:33:22 +08:00
陈昱达
df45c9d896 feat(case): 支持消息内容Markdown渲染并优化样式
- 消息内容支持Markdown格式渲染
- 注释掉推荐问题模块,暂时不显示
- 调整消息气泡样式,去除背景色和边框
- 修改消息气泡圆角大小,提升视觉效果
- 调整链接颜色为黑色,增强可读性- 提高打字机效果速度,改善用户体验
2025-10-14 17:48:26 +08:00
陈昱达
b9caf2c4ad fix(portal): 禁用消息组件中的打字机效果
- 注释掉了启动打字机效果的函数调用
- 直接设置显示文本以避免延迟
2025-10-14 15:43:36 +08:00
陈昱达
0afd733f47 feat(portal):优化AI对话框宽度与消息展示
- 将AI对话框宽度从65%调整为800px- 修改初始欢迎消息格式,使用HTML标签替换Markdown语法-修复机器人消息显示逻辑,确保displayText正确赋值- 优化消息渲染流程,提升用户体验
2025-10-14 15:43:13 +08:00
陈昱达
3720b5667d feat(portal): 实现消息组件支持 Mermaid 图表渲染
- 添加 markdown-it-mermaid 插件支持 Mermaid 语法
- 集成 mermaid 库并初始化配置
- 实现打字机效果与 Mermaid 渲染结合
-优化案例引用展示逻辑与样式- 添加推荐问题展示功能
- 改进消息组件的响应式与样式细节
- 修复组件销毁时定时器未清除的问题
- 更新依赖包引入 Mermaid 相关库
2025-10-14 15:32:20 +08:00
陈昱达
72472979bd feat(portal): 支持消息内容的 Markdown 和 LaTeX 渲染- 引入 markdown-it 与 highlight.js 实现 Markdown 渲染- 集成 KaTeX 支持数学公式显示
- 更新消息组件以支持实时渲染 Markdown 与 LaTeX
- 调整 AI 对话框宽度为百分比布局
- 优化初始欢迎文案格式并添加段落间距
- 添加必要的依赖项:katex、markdown-it、markdown-it-highlightjs 等- 配置 vue-katex 插件并定义分隔符规则
- 使用 null-loader 处理部分资源加载问题
2025-10-14 11:51:03 +08:00
hz
70000e2e10 添加 Accept : EventStream 请求头 2025-10-14 09:25:05 +08:00
joshen
5ebee96ce4 Merge remote-tracking branch 'yx/202599-da' 2025-09-29 17:42:32 +08:00
408d6a1612 修复视频 status 状态 2025-09-29 17:26:53 +08:00
陈昱达
969c9f6797 feat(portal): 添加案例专区AI专家提示
- 在案例列表页头部添加AI案例专家提示文案
- 调整banner样式以支持绝对定位元素
- 设置提示文案位置和颜色以匹配设计要求
2025-09-29 16:12:27 +08:00
陈昱达
33406f6964 feat(portal): 初始化新对话时重置对话ID- 在开始新对话时将 conversationId 设置为空字符串
- 确保每次新建对话都有独立的标识符
-修复可能因对话ID重复导致的消息发送错误
2025-09-29 09:36:42 +08:00
陈昱达
e1f2e91648 feat(portal):优化AI对话窗口状态管理
- 移除硬编码的HTTP地址注释
- 修改最小化窗口点击事件处理逻辑- 移除窗口状态自动恢复的旧逻辑
- 新增restore事件机制处理窗口状态- 调整按钮图标颜色值- 完善AI Call组件的状态控制逻辑
- 保留
2025-09-29 09:33:12 +08:00
陈昱达
8c023d459f feat(portal): 添加AI Call最小化窗口控制功能
- 在app store中新增showAICallMinimized状态用于控制AI Call最小化窗口显示
- 添加对应的mutation和action用于更新最小化窗口显示状态
- 在AICall.vue组件中实现最小化窗口的条件显示逻辑
- 修改case消息组件中的链接跳转方式为路由跳转
- 更新AI聊天接口的请求地址为统一网关路径
- 在App.vue中添加路由监听,根据路由动态控制AI Call窗口显示状态- 实现case和caseDetail路由下显示AI Call最小化窗口的逻辑
2025-09-28 18:07:02 +08:00
陈昱达
47c1d29ef2 feat(app): 添加AI Call组件控制功能- 在app模块中新增showAICall状态用于控制AI Call组件显示
- 添加对应的mutation和action来修改showAICall状态
- 在App.vue中引入并条件渲染AICall组件
- 新增AICaseConsult组件用于触发AI Call显示
- 在Detail.vue页面中集成AICaseConsult组件-修复sendMessage.vue中conversationId的sessionStorage存储问题
- 调整AICall.vue组件的窗口显示逻辑
2025-09-28 17:50:13 +08:00
陈昱达
a3dab45af0 feat(portal): 实现AI对话窗口最小化功能
- 新增窗口最小化与最大化切换功能
- 调整对话框结构支持两种显示状态
-优化消息建议显示条件判断
- 修改API地址为本地开发环境地址- 更新错误提示文案提升用户体验
- 移除旧版AI入口相关逻辑和样式
- 引入新的AICaseConsult组件替换原有实现
- 修复消息列表为空时的默认展示逻辑
- 添加getLastUserMessage方法提取纯文本内容- 优化窗口控制按钮样式和交互逻辑
2025-09-28 16:39:55 +08:00
陈昱达
e3422d15ee fix(portal):修复AI案例点击事件缺失问题- 在AI案例卡片上添加@click事件处理
- 确保点击功能正常触发getAICase方法
- 移除重复的点击绑定以避免冲突
2025-09-28 15:07:22 +08:00
王卓煜
581be5567f 标签管理未选择分类给个提示语 2025-09-28 11:59:09 +08:00
王卓煜
c9465492f4 标签管理未选择分类给个提示语 2025-09-28 11:46:33 +08:00
陈昱达
2c630eac70 feat(ai-chat): 实现案例专家功能入口权限控制及消息展示优化- 修改AI聊天接口地址为本地开发环境地址
- 新增showCaseAiEntrance接口用于控制案例专家功能入口显示
- 优化消息组件中的案例引用展示逻辑,支持展开/收起功能
- 增加案例引用的上传时间、作者机构等信息展示
- 实现打字机效果的文本逐字显示功能
- 优化AI消息响应处理逻辑,支持think标签内容解析
2025-09-28 11:40:35 +08:00
陈昱达
3cef730e61 feat(ai-chat): 实现案例专家功能入口权限控制及消息展示优化- 修改AI聊天接口地址为本地开发环境地址
- 新增showCaseAiEntrance接口用于控制案例专家功能入口显示
- 优化消息组件中的案例引用展示逻辑,支持展开/收起功能
- 增加案例引用的上传时间、作者机构等信息展示
- 实现打字机效果的文本逐字显示功能
- 优化AI消息响应处理逻辑,支持think标签内容解析
2025-09-28 11:28:36 +08:00
王卓煜
b18500bad7 标签管理查询条件 缺少重置按钮 2025-09-28 11:12:06 +08:00
王卓煜
5536fc06e1 标签管理修改无数据也可以回车创建 2025-09-28 11:07:08 +08:00
王卓煜
18f3804536 标签管理修改提示语 2025-09-28 11:03:09 +08:00
王卓煜
7230bd18e8 标签管理无目录课程添加标签 2025-09-26 19:03:56 +08:00
b1508ad226 更新精品课图片 2025-09-26 09:18:51 +08:00
a9764bf2f8 更新精品课图片 2025-09-26 09:15:55 +08:00
陈昱达
483b57f667 feat(ai-chat): 实现AI聊天对话与会话消息记录功能
新增AI聊天对话接口和会话消息记录查询接口,支持SSE流式响应处理。
在sendMessage组件中集成真实SE调用逻辑,替换原有模拟实现,
并完善conversationId的获取与保存机制。新增sseHelper工具类用于统一处理SSE连接和数据解析。
2025-09-24 14:26:37 +08:00
陈昱达
be411ec72d feat(portal-case): 新增AI智能问答对话功能新增消息展示组件和发送消息组件,实现机器人与用户的消息交互。
支持打字机效果展示AI回复内容,并可显示思考过程与相关案例推荐。
添加对话框背景样式及自动滚动功能,优化用户体验。
提供开启新对话和推荐问题功能,增强交互性。
2025-09-24 09:34:45 +08:00
dong.ai
d7e425ce9d 案例专家添加图片 2025-09-24 09:27:26 +08:00
dong.ai
8b68489b25 案例AI弹窗ui 2025-09-23 09:50:21 +08:00
王卓煜
fd10d99454 标签管理去除无效功能 2025-09-22 10:17:37 +08:00
joshen
c3f53515b9 Merge branch '202599-da' 2025-09-19 18:58:47 +08:00
王卓煜
a51d87fbe8 标签关联课程下面展示标签 2025-09-19 17:12:24 +08:00
087be5dd38 fix: 修复分数异常展示的问题 2025-09-19 13:43:23 +08:00
王卓煜
2aa36c82ab 标签管理搜索关键字和搜索条件区别显示 2025-09-19 11:12:58 +08:00
joshen
1772c972b9 Merge branch '202599-da' 2025-09-18 18:51:50 +08:00
王卓煜
0bba87cb3d 标签管理前端友好提示 2025-09-18 09:45:33 +08:00
dong.ai
91bafcb5b9 调整字体展示位置 2025-09-15 17:15:47 +08:00
dong.ai
8c533c5f3a 修改字体大小 2025-09-15 17:02:45 +08:00
dong.ai
bb17784501 修改图片大小,背景图片 2025-09-15 16:32:23 +08:00
dong.ai
69530fe6ad 标题展示隐藏判断2 2025-09-15 14:01:32 +08:00
dong.ai
b1cd8e2f63 标题展示隐藏判断 2025-09-15 13:57:19 +08:00
dong.ai
7335dd4eba 首页教师名称展示 2025-09-15 13:45:35 +08:00
3860087fac feat: 增加搜索标签展示,修复样式问题,提示语修改 2025-09-15 11:36:08 +08:00
046509f70d fix: 修复课程名称展示异常的问题 2025-09-15 10:06:35 +08:00
bf0ae91184 feat: 优化调用显示方案 2025-09-15 10:06:35 +08:00
f61742a0b9 fix: 修复教师无法展示的问题 2025-09-14 22:09:03 +08:00
dong.ai
c886a80193 教师展示 2025-09-14 21:30:12 +08:00
05ad90b025 fix: 修复标签无法正常高亮的问题 2025-09-14 21:23:56 +08:00
f3833a23fa style: 优化选择年份和边距 2025-09-14 21:16:02 +08:00
d957a8d44b fix: 修复 主页图片无法正常展示的问题 2025-09-14 21:16:01 +08:00
dong.ai
89ed79828f 修复跳转详情2 2025-09-14 21:09:57 +08:00
dong.ai
b926590edc 修改跳转详情 2025-09-14 21:04:21 +08:00
19bc757dc2 fix: 修复 systype 错误的问题 2025-09-14 20:59:38 +08:00
f3a1036b64 feat: 样式修改,功能修复 2025-09-14 20:50:42 +08:00
3c1650b751 Merge branch '2025-912-hz' into 202599-da
# Conflicts:
#	src/api/phase2/index.js
2025-09-14 20:30:44 +08:00
ff2bdb4ae5 fix: 修复获取课程精品课标记时间年份列表
# Conflicts:
#	src/api/phase2/index.js
2025-09-14 20:29:53 +08:00
dong.ai
14fb53ccd3 解决冲突 2025-09-14 20:10:29 +08:00
dong.ai
72f9661150 Merge branch '202599-da' of https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/learning-system-portal into 202599-da 2025-09-14 19:43:10 +08:00
dong.ai
7806afc5f7 还原代码 2025-09-14 19:40:05 +08:00
e1af233c5f feat: 完成精品课程专区的内容 2025-09-14 19:39:41 +08:00
2738493030 fix: 修复刷新页面自动调整错误的问题 2025-09-14 19:39:08 +08:00
480a4f5564 chore: 修正路由名称拼写错误 2025-09-14 19:39:06 +08:00
dong.ai
205bf5469f 字段展示 2025-09-14 19:08:21 +08:00
dong.ai
30897a1fa5 修改展示 2025-09-14 19:02:38 +08:00
dong.ai
1c59cffd3e 标题展示 2025-09-14 18:54:18 +08:00
dong.ai
6e9f93d6c9 字段处理 2025-09-14 18:48:47 +08:00
dong.ai
3ee4a2fd6e 调整首页字段展示 2025-09-14 18:11:33 +08:00
dong.ai
1b442ef040 首页跳转详情 2025-09-14 17:50:31 +08:00
dong.ai
4693cb0db1 收藏图标展示 2025-09-14 17:43:35 +08:00
dong.ai
92fecbec80 收藏图表展示 2025-09-14 17:36:13 +08:00
dong.ai
be63f5a1aa 收藏图片展示 2025-09-14 17:28:04 +08:00
dong.ai
c9899eda6b 修改收藏 2025-09-14 17:20:15 +08:00
dong.ai
0f52a69beb 收藏展示 2025-09-14 17:07:30 +08:00
dong.ai
3410afedcf 收藏发消息接口字段 2025-09-14 16:45:13 +08:00
dong.ai
33866c0f49 修改收藏 2025-09-14 16:28:36 +08:00
dong.ai
c9e51fc21f 完善收藏 2025-09-14 16:03:49 +08:00
dong.ai
a42668c929 调整背景样式 2025-09-14 15:29:45 +08:00
dong.ai
01d4bc0536 调整背景图样式 2025-09-14 14:52:19 +08:00
dong.ai
d52e8b389b 修改首页展示样式 2025-09-14 13:55:28 +08:00
dong.ai
e9a86d0364 修改入参格式 2025-09-14 12:25:56 +08:00
dong.ai
0e43ca5e82 修改请求头类型 2025-09-14 12:01:08 +08:00
dong.ai
0771460f60 首页精品课部分 2025-09-14 11:45:27 +08:00
dong.ai
1a2829d70a 精品课列表接口 2025-09-13 19:58:11 +08:00
dong.ai
68eda7efcc 首页添加精品课模块 2025-09-13 15:39:35 +08:00
王卓煜
98ba239494 标签管理添加图片(社招新员工的样式影响了所以添加一下) 2025-09-12 16:14:43 +08:00
王卓煜
df3b1d7162 标签管理 2025-09-12 15:47:26 +08:00
0b0789feda feat: 右侧菜单高度调整为 650 2025-09-09 17:51:26 +08:00
70bb87a17a feat: 溢出控制高度的代码, 防止内容塌陷 2025-09-09 17:51:25 +08:00
4e60811542 feat: 溢出控制高度的代码, 防止内容塌陷 2025-09-09 17:51:24 +08:00
670788339
075fdb1913 认证讲师库删除年份后缀 2025-09-09 17:39:58 +08:00
670788339
8c7569ae4e banner跳转 2025-09-04 16:46:09 +08:00
670788339
56f565cbf3 banner跳转暂时注释 2025-09-02 08:46:33 +08:00
670788339
c15f52e325 banner跳转 2025-09-01 15:37:12 +08:00
670788339
98c10e703e 教师专区banner点击跳转 2025-09-01 13:21:12 +08:00
670788339
2078c128c9 教师专区banner点击跳转 2025-09-01 13:12:22 +08:00
joshen
e8fe7b4fd3 fix: 修复火狐报错的弹窗提醒 2025-08-14 14:03:53 +08:00
joshen
029d5b0791 修复1181案例不显示案主信息 2025-08-05 15:26:27 +08:00
joshen
12a6ed8fea Merge remote-tracking branch '104/master-0626' into master-0626 2025-08-05 14:30:02 +08:00
joshen
363492866f 修复1181案例不显示案主信息 2025-08-05 14:29:24 +08:00
joshen
d237dc99ee 修改弹框可见 2025-07-25 21:01:58 +08:00
joshen
995933ae56 Merge remote-tracking branch '104-git/master-0626' into master-0626 2025-07-25 20:53:15 +08:00
joshen
dff81df91d 修改弹框可见 2025-07-25 20:52:43 +08:00
670788339
0864704c4c 仅内网可见-管理员端 调试 2025-07-23 17:53:43 +08:00
670788339
58fc6264fe 仅内网可见-管理员端 调试 2025-07-23 17:45:30 +08:00
670788339
5276813eba 仅内网可见-管理员端 调试 2025-07-23 17:28:36 +08:00
670788339
3485435c9e 仅内网可见-管理员端 调试 2025-07-23 17:24:51 +08:00
670788339
2ee3daedf6 仅内网可见-管理员端 调试 2025-07-23 17:10:19 +08:00
joshen
5d0d64abbf 修改背景颜色 2025-07-23 16:49:08 +08:00
joshen
ea97aee4af 修复评分会点错 2025-07-23 15:07:30 +08:00
joshen
a968062936 修复视频进度条拖动 2025-07-23 14:40:06 +08:00
joshen
6d11475456 修改边界颜色 2025-07-23 13:45:38 +08:00
joshen
a7396e0a6a 修改边界颜色 2025-07-23 13:37:42 +08:00
670788339
ac236e8d7c 仅内网可见-管理员端 调试 2025-07-21 21:17:18 +08:00
670788339
f537608e4f 仅内网可见-管理员端 调试 2025-07-21 21:10:41 +08:00
670788339
c7f4a224ff 仅内网可见-管理员端 调试 2025-07-21 20:59:06 +08:00
670788339
a4d088a3ae 仅内网可见-管理员端 调试 2025-07-21 20:44:20 +08:00
670788339
3cd2c5f433 仅内网可见-管理员端 调试 2025-07-21 20:33:47 +08:00
670788339
8c69fac9be 仅内网可见-管理员端 调试 2025-07-21 20:24:39 +08:00
670788339
4033eb2294 仅内网可见-管理员端 调试 2025-07-21 20:18:33 +08:00
670788339
ec469db72a 仅内网可见-管理员端 调试 2025-07-21 20:15:20 +08:00
670788339
5e1ea2469b 仅内网可见-管理员端 调试 2025-07-21 20:11:41 +08:00
670788339
2baa5c61a4 仅内网可见-管理员端 调试 2025-07-21 20:10:25 +08:00
670788339
b627398b7d 仅内网可见-管理员端 调试 2025-07-21 19:57:51 +08:00
670788339
7be5c072d9 仅内网可见-管理员端 调试 2025-07-21 19:37:32 +08:00
670788339
de14f9f561 仅内网可见-管理员端 调试 2025-07-21 19:26:19 +08:00
joshen
44f79c93a5 修改前端 2025-07-21 19:24:24 +08:00
joshen
e501b8d23f 修改前端 2025-07-21 19:16:49 +08:00
joshen
ea8143db2b 修改前端 2025-07-21 18:57:40 +08:00
joshen
89277f8868 修改前端 2025-07-21 18:35:09 +08:00
joshen
13af8ba4e0 前端参数调整 2025-07-21 15:21:19 +08:00
joshen
e3735e4b92 前端参数调整 2025-07-21 15:09:39 +08:00
joshen
f4c9b921bb 前端参数调整 2025-07-21 15:02:46 +08:00
joshen
ed899cdd2c Merge remote-tracking branch 'aliyun/master-0720-lyc' into master-0720-lyc 2025-07-21 15:00:08 +08:00
王卓煜
c24b54957a 内网环境判断 2025-07-21 14:57:51 +08:00
joshen
1dc9c941d7 Merge remote-tracking branch 'aliyun/master-0720-lyc' into master-0720-lyc 2025-07-21 14:45:56 +08:00
王卓煜
33c9d2140f 内网环境判断 2025-07-21 14:42:42 +08:00
王卓煜
afd1bec458 内网环境判断 2025-07-21 14:33:05 +08:00
joshen
202bf7b123 test2 2025-07-21 11:19:59 +08:00
joshen
ce1d662350 Merge remote-tracking branch 'aliyun/master-0720-lyc' into master-0720-lyc 2025-07-21 11:01:12 +08:00
王卓煜
81602506c7 内网环境判断 2025-07-21 11:00:33 +08:00
joshen
053a2a60b2 Merge remote-tracking branch 'aliyun/master-0720-lyc' into master-0720-lyc 2025-07-21 10:47:32 +08:00
王卓煜
b9f23eb657 内网环境判断 2025-07-21 10:46:30 +08:00
joshen
ceeb3efcf5 Merge remote-tracking branch 'aliyun/master-0720-lyc' into master-0720-lyc 2025-07-21 10:43:23 +08:00
王卓煜
147366f738 内网环境判断 2025-07-21 10:33:44 +08:00
joshen
4ac09a8793 test2 2025-07-20 18:27:45 +08:00
joshen
9c768337c6 test2 2025-07-20 18:23:55 +08:00
joshen
e202946fe7 test2 2025-07-20 18:16:54 +08:00
joshen
fbddf6806a test 2025-07-20 18:11:37 +08:00
670788339
3cfa3ffec3 仅内网可见-管理员端 调试 2025-07-20 17:47:53 +08:00
670788339
a8bcd3832b 仅内网可见-管理员端 调试 2025-07-20 16:56:47 +08:00
670788339
d9f69001a5 仅内网可见-管理员端 调试 2025-07-20 16:38:42 +08:00
670788339
93e769be42 仅内网可见-管理员端 调试 2025-07-20 16:15:02 +08:00
670788339
206f0e825d 仅内网可见-管理员端 2025-07-20 15:39:37 +08:00
670788339
3bb4b519f1 仅内网可见-管理员端 2025-07-20 14:16:02 +08:00
joshen
fe790389ca 日志打印 2025-07-17 11:24:07 +08:00
joshen
44a5baec18 日志打印 2025-07-17 10:14:42 +08:00
670788339
ee8a76c4df 作业提交按钮判断 2025-07-09 13:48:31 +08:00
670788339
12c1bdb1a8 查询考试限制加大 2025-06-27 16:53:34 +08:00
670788339
df0e1ad0ed Merge branch 'csg-250625-lyc' into master-0626 2025-06-26 15:47:36 +08:00
670788339
ea54ea2c20 热点-替换图片 2025-06-25 16:42:45 +08:00
670788339
5fe9d2eb96 热点-替换图片 2025-06-25 15:24:34 +08:00
chensg
b6562e5c9c 修改25年热点论坛组件名称 2025-06-16 14:07:25 +08:00
chensg
a0dcd27f8c 修改2025热点论坛 2025-06-16 13:37:22 +08:00
chensg
8bc2bc96a8 添加2025热点论坛 2025-06-16 11:25:28 +08:00
670788339
ab2ac961f5 替换图片 2025-06-13 09:17:26 +08:00
670788339
6727dd838b 替换图片 2025-06-12 09:36:58 +08:00
joshen
28aa639e1c Merge remote-tracking branch 'yx/master-20250428-shl' 2025-05-13 15:42:12 +08:00
joshen
05d48f5313 Merge remote-tracking branch 'yx/250415-bugfix-shl' 2025-05-13 15:41:28 +08:00
sunhonglai
7a67aca620 修改教师端我的授课记录查询和导出 2025-04-29 16:33:42 +08:00
sunhonglai
a810da8978 修改教师端我的授课记录查询和导出 2025-04-29 16:29:36 +08:00
sunhonglai
b4538150df 修改教师端我的授课记录查询和导出 2025-04-29 16:20:57 +08:00
sunhonglai
e79abe7aee 修改教师端我的授课记录查询和导出 2025-04-29 16:07:35 +08:00
sunhonglai
65dfa4f0e3 修改教师端我的授课记录查询和导出 2025-04-29 16:01:30 +08:00
sunhonglai
4784b02ca4 修改教师端我的授课记录查询和导出 2025-04-29 15:44:55 +08:00
sunhonglai
45e006a4e7 修改教师端我的授课记录查询和导出 2025-04-29 15:34:09 +08:00
sunhonglai
577357ccd0 修改教师端我的授课记录查询和导出 2025-04-29 15:03:58 +08:00
sunhonglai
f92954aa6b 修改教师端我的授课记录查询和导出 2025-04-29 14:53:51 +08:00
sunhonglai
d59b5a9e06 修改教师端我的授课记录查询和导出 2025-04-29 14:53:24 +08:00
sunhonglai
4be009a6d8 修改教师端我的授课记录查询和导出 2025-04-29 14:13:34 +08:00
sunhonglai
b5f01c6357 修改教师端我的授课记录查询和导出 2025-04-29 13:55:05 +08:00
sunhonglai
78cbb21155 修改教师端我的授课记录查询和导出 2025-04-29 13:47:56 +08:00
sunhonglai
adc33e5892 修改教师端我的授课记录查询和导出 2025-04-29 13:36:24 +08:00
sunhonglai
a9de4ad77c 修改教师端我的授课记录查询和导出 2025-04-29 11:49:39 +08:00
sunhonglai
a3c85cbd19 修改教师端我的授课记录查询和导出 2025-04-29 11:46:40 +08:00
sunhonglai
9a6727e52f 修改教师端我的授课记录查询和导出 2025-04-29 11:40:29 +08:00
sunhonglai
7cee4b5ad1 修改教师端我的授课记录查询和导出 2025-04-29 11:33:51 +08:00
sunhonglai
c3b5f1baf0 修改教师端我的授课记录查询和导出 2025-04-29 11:23:45 +08:00
sunhonglai
213990a7b0 每次加载pdf前,清空路径 2025-04-23 14:16:21 +08:00
sunhonglai
505e3ce00c 修改进度条文案 2025-04-21 14:37:53 +08:00
sunhonglai
ff908554fd 修改上报时长接口 2025-04-21 11:10:21 +08:00
sunhonglai
e031dcd935 修改上报时长接口 2025-04-18 09:42:06 +08:00
sunhonglai
2139e15813 修改上报时长接口 2025-04-18 09:41:46 +08:00
sunhonglai
8497deea52 增加日志打印 2025-04-18 09:27:01 +08:00
sunhonglai
8746904cb9 学习时长上报接口合并 2025-04-18 08:51:48 +08:00
sunhonglai
213e5abce3 去掉无用注释影响后绪修改逻辑 2025-04-16 14:01:43 +08:00
sunhonglai
dc7f942303 先修改对应的后端接口 2025-04-16 10:19:56 +08:00
sunhonglai
4c1c370879 清除无用注释,影响排查要搜索修改的代码 2025-04-16 08:51:10 +08:00
sunhonglai
ffbc4ef808 增加乐享强制走sso 2025-04-15 16:20:23 +08:00
sunhonglai
5936183912 增加乐享转向 2025-04-15 09:12:11 +08:00
sunhonglai
702881c100 修改排行榜展示数据不对问题 2025-04-09 14:28:42 +08:00
670788339
b0229f6cde 测试 2025-04-03 16:36:38 +08:00
670788339
9c6c1708fc 测试 2025-04-03 16:33:42 +08:00
670788339
b67d7f4311 测试 2025-04-03 16:24:13 +08:00
670788339
c5e54f0170 测试 2025-04-03 16:17:04 +08:00
670788339
5c5a71ec55 测试 2025-04-03 15:21:51 +08:00
joshen
b6a3a32412 Merge remote-tracking branch 'aliyun/master_20250319-lyc' 2025-04-02 16:59:49 +08:00
670788339
f9e332ab7c SZX-1045 2025-03-28 11:47:43 +08:00
124 changed files with 23233 additions and 20250 deletions

22046
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,7 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@mermaid-js/parser": "^0.6.3",
"axios": "^0.21.4",
"core-js": "^3.6.5",
"driver.js": "^0.9.8",
@@ -23,9 +24,15 @@
"element-ui": "^2.15.7",
"file-saver": "^2.0.5",
"fuse.js": "^6.4.6",
"highlight.js": "^11.11.1",
"image-conversion": "^2.1.1",
"jsencrypt": "^3.2.1",
"json-bigint": "^1.0.0",
"katex": "^0.16.25",
"markdown-it": "^14.1.0",
"markdown-it-highlightjs": "^4.2.0",
"markdown-it-mermaid": "^0.2.5",
"mermaid": "^8.13.10",
"mockjs": "^1.1.0",
"moment": "^2.29.1",
"nprogress": "^0.2.0",
@@ -43,6 +50,7 @@
"vue": "^2.6.11",
"vue-awesome-swiper": "^3.1.3",
"vue-cookies": "^1.7.4",
"vue-katex": "^0.5.0",
"vue-pdf": "^4.2.0",
"vue-quill-editor": "^3.0.6",
"vue-router": "^3.5.2",
@@ -60,6 +68,7 @@
"html-webpack-plugin": "^5.5.0",
"less": "^4.1.1",
"less-loader": "^6.2.0",
"null-loader": "^4.0.1",
"sass": "^1.32.13",
"sass-loader": "^10.1.0",
"vue-template-compiler": "^2.6.11"

BIN
public/images/case-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

BIN
public/images/qualityBg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,25 +1,74 @@
<template>
<div id="app">
<div id="app" style="width: 100vw">
<keep-alive :include="['case']">
<router-view />
12312
</keep-alive>
<!-- 添加AI Call组件 -->
<AICall
:dialogVisible="showAICall"
@close="onCloseAICall"
@restore="onRestoreAICall"
/>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { mapGetters, mapState } from 'vuex';
import AICall from '@/views/portal/case/AICall.vue';
export default{
name: 'App',
computed: {
...mapGetters(['userInfo'])
components: {
AICall
},
mounted() {
computed: {
...mapGetters(['userInfo']),
...mapState('app', ['showAICall', 'showAICallMinimized'])
},
methods: {
onCloseAICall() {
// 通过Vuex关闭AI Call组件
this.$store.dispatch('app/setShowAICall', false);
},
onRestoreAICall() {
// 通过Vuex显示AI Call组件
this.$store.dispatch('app/setShowAICall', true);
},
// 检查当前路由是否应该显示AI弹窗
checkRouteForAICall() {
const currentRoute = this.$route.name;
// 只在case或caseDetail路由显示弹窗
if (currentRoute === 'case' || currentRoute === 'caseDetail') {
// 设置最小化窗口显示状态为true
this.$store.dispatch('app/setShowAICallMinimized', true);
// 注意这里不再强制设置showAICall为true保留用户之前的操作状态
} else {
// 其他路由关闭弹窗
this.$store.dispatch('app/setShowAICall', false);
// 设置最小化窗口显示状态为false
this.$store.dispatch('app/setShowAICallMinimized', false);
}
}
},
mounted() {
//从状态值中取,因为登录处理所以移动watch中
// console.log(this.userInfo);
// if(this.userInfo && this.userInfo.name!=''){
// this.$watermark.set(this.userInfo.name+this.userInfo.loginName);
// }
// 初始化检查路由
this.checkRouteForAICall();
},
watch: {
// 监听路由变化
$route(to, from) {
this.checkRouteForAICall();
}
}
// watch:{
// userInfo(newVal,oldVal){
// if(newVal && newVal.name!=''){
@@ -39,4 +88,3 @@
box-shadow: 0px 1px 5px 1px rgba(92,98,111,.3);
}
</style>

30
src/api/boe/aiChat.js Normal file
View File

@@ -0,0 +1,30 @@
import ajax from '@/utils/xajax.js'
/**
* AI聊天对话接口
* @param {Object} data - 请求参数
* @param {string} data.conversationId - 会话ID如果为空则创建新会话
* @param {string} data.query - 用户提问内容
* @returns {Promise} - 返回SSE流
*/
export function aiChat(data) {
return ajax.postJson('http://192.168.3.178/xboe/m/boe/case/ai/chat', data)
}
/**
* 查询会话消息记录接口
* @param {string} conversationId - 会话ID
* @returns {Promise} - 返回会话历史记录
*/
export function getChatMessages(conversationId) {
return ajax.get('/xboe/m/boe/case/ai/messages?conversationId=' + conversationId)
}
/**
* 案例专家功能入口显示权限判断接口
* 判断当前登录用户是否显示"案例专家"功能入口
* @returns {Promise} - 返回是否显示功能入口的布尔值
*/
export function showCaseAiEntrance() {
return ajax.get('/xboe/m/boe/case/ai/show-entrance')
}

View File

@@ -62,15 +62,62 @@ const courseRecordList = function(data) {
return ajax.postJson('/b1/system/teacher/teacher-course-list',data);
}
const getListByToken = function(data) {
return ajax2.get('/manageApi',`/admin/teacherRecord/getListByToken?courseName=${data.courseName}&page=${data.page}&pageSize=${data.pageSize}`);
return ajax2.get('/manageApi',`/admin/teacherRecord/getListByToken?courseName=${data.courseName}&pageNo=${data.pageNo}&pageSize=${data.pageSize}`);
}
/**
* 导出授课记录
*
* @param {Object} data
*/
const courseRecordExport2 = function(data) {
return axios.request({
baseURL: "/manageApi",
url: '/admin/export/exportInTeacherRecord',
method: 'get',
data:data,
headers:{'Content-Type':'application/json;charset=utf-8'},
responseType: 'blob'
})
}
/**
* 导出课程下的学员信息
*
*/
const exportStudentOfCourse2 = function(courseId,courseType) {
return axios.request({
baseURL: "/manageApi",
url: '/admin/export/exportTeacherRecordStudentInfo?courseId='+courseId+'&courseType='+courseType,
method: 'get'
// headers:{'Content-Type':'application/json;charset=utf-8'},
// responseType: 'blob'
})
}
/**
* 导出教师下的所有授课记录下的学员信息
*
*/
const exportStudentOfTearcher2 = function(userId) {
return axios.request({
baseURL: "/manageApi",
url: '/b1/system/teacher/teacher-course-student-export?userId='+userId,
method: 'post',
headers:{'Content-Type':'application/json;charset=utf-8'},
responseType: 'blob'
})
}
export default {
courseRecordExport,
courseRecordExport2,
courseRecordList,
getListByToken,
exportStudentOfCourse,
exportStudentOfTearcher
exportStudentOfCourse2,
exportStudentOfTearcher,
exportStudentOfTearcher2,
}

View File

@@ -46,6 +46,14 @@ const getUserInfoById = function(id) {
return ajax.postJson(baseURL,'/user/list',{id});
}
/**
* 获取全量机构树
* GET /userbasic/organization/all/tree
*/
const getAllOrgTree = function () {
return ajax.get(baseURL, '/organization/all/tree');
};
/**
* https://u-pre.boe.com/userbasic/audience/userAudiences
* 【当前代码中未查询到】获取当前用户受众信息
@@ -103,6 +111,15 @@ const getUsersByIds = function(ids) {
return ajax.postJson(baseURL,'/user/getUserMessageToDai',ids);
}
/**
* 根据关键字检索用户(创建人下拉)
* @param {string} keyword
*/
const selectUser = function(keyword = '') {
return ajax.postJson(baseURL,'/user/selectuser',{ keyword });
}
export default {
userParentOrg,
findOrgsByKeyword,
@@ -116,5 +133,7 @@ export default {
getInAudienceIds,
getUsersByIds,
updateUser,
logout
logout,
getAllOrgTree,
selectUser
}

208
src/api/httpAjax.js Normal file
View File

@@ -0,0 +1,208 @@
import axios from 'axios'
import qs from 'qs'
import {Notification, MessageBox, Message} from 'element-ui'
import store from '@/store'
import {getToken} from '@/utils/token'
import errorCode from '@/utils/errorCode'
/**
*request请求 axios.request(config)
*requestJson请求 axios.request(config)
*get请求 axios.get(url[, config])
*post请求 axios.post(url[, data[, config]])
*postJson请求 axios.post(url[, data[, config]])
*put请求 axios.put(url[, data[, config]])
*putJson请求 axios.put(url[, data[, config]])
*patch请求 axios.patch(url[, data[, config]])
*patchJson请求 axios.patch(url[, data[, config]])
*delete请求 axios.delete(url[, config])
*/
// const ReLoginUrl=process.env.VUE_APP_LOGIN_URL;
const TokenName = 'token';
/**axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded'**/
//只是用于发送json对象数据时使用post,put,patch
/**axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded'**/
//只是用于发送json对象数据时使用post,put,patch
//用于普通的发送请求
const formRequest = axios.create({
//headers:{'Content-Type':'application/x-www-form-urlencoded'},
// axios中请求配置有baseURL选项表示请求URL公共部分
// baseURL: process.env.VUE_APP_CESOURCE_BASE_API,
//超时
timeout: 10000,
})
//发送json对象的拦截器
formRequest.interceptors.request.use(config => {
//是否需要设置 token
const isToken = (config.headers || {}).isToken === false
let curToken = getToken();
//curToken='eyJ0eXBlIjoidG9rZW4iLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC91LmJvZS5jb20iLCJpYXQiOjE2NzIzMTE2MTIsImV4cCI6MTY3MjMxODgxMiwiR2l2ZW5OYW1lIjoiYm9ldSIsInVzZXJJZCI6IjZCMDQ5RkFGLUMzMTQtN0NDRi0wRDI4LTBEMjNGNEM0MjUzMSIsInVJZCI6Ijk2NTM0MjAyNzQ5NzYwNzE2OCIsInBlcm1pc3Npb24iOiIifQ==.a4f41376e994c5fcd3ab537ce17572ef4c633863f87785cf7b6ffa353e2ed51c';
if (curToken && !isToken) {
config.headers[TokenName] = curToken // 让每个请求携带自定义token 请根据实际情况自行修改
}
return config
}, error => {
console.log(error)
Promise.reject(error)
});
formRequest.interceptors.response.use(res => {
//console.log(res);
const code = res.data.status || 200;
if (code === 200) {
return res.data
} else {
if (code === 401) {
// store.dispatch('LogOut').then(() => {
// location.href = this.webBaseUrl + ReLoginUrl;
// })
console.error('', res.data);
return Promise.reject(new Error('接口返回未登录'))
} else if (code === 403) {
var msg = '当前操作没有权限';
Message({message: msg, type: 'error'});
return Promise.reject(new Error(msg))
} else {
//Message({message: res.data.message, type: 'error'});
//console.log('err' + res.data.error);
return res.data
}
}
},
error => {
console.log('err', error)
let {message} = error;
if (message == "Network Error") {
message = "网络异常,请稍后重试";
} else if (message.includes("timeout")) {
message = "网络异常或接口错误,请求超时";
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
Message({
message: message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
/**
* request请求,可以自定义参数
*/
const request = formRequest.request;
/**
* get请求 ,只有url
*/
const get = function (baseURL, url) {
return request({
baseURL,
url: url,
method: 'get',
headers: {'Content-Type': 'application/json'}
})
}
/**
* post请求
* @param {Object} url
* @param {Object} postData
*/
const post = function (baseURL, url, postData) {
// if (postData) {
// postData = qs.stringify(postData);
// }
return request({
baseURL,
url: url,
method: 'post',
data: postData,
headers: {'Content-Type': 'application/json'}
})
}
//post请求
const postForm = function (baseURL, url, data) {
return request({
baseURL,
url,
data,
method: 'post',
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
}
// const postJson=jsonRequest.post;
const postJson = function (baseURL, url, postData) {
return request({
baseURL,
url: url,
method: 'post',
data: postData,
headers: {'Content-Type': 'application/json;charset=utf-8'},
})
}
// 导出文件请求定义
const postJsonToFile = function (baseURL, url, postData) {
return request({
baseURL,
url: url,
method: 'post',
data: postData,
headers: {'Content-Type': 'application/json;charset=utf-8'},
responseType: 'blob'
})
}
const getJsonToFile = function (baseURL, url, postData) {
return request({
baseURL,
url: url,
method: 'get',
data: postData,
headers: {'Content-Type': 'application/json;charset=utf-8'},
responseType: 'blob'
})
}
/**
* put请求
*/
const put = function (baseURL, url, data) {
if (data) {
data = qs.stringify(data);
}
return request({
baseURL,
url: url,
method: 'put',
data: data,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
}
const putJson = function (baseURL, url, data) {
return request({
baseURL,
url: url,
method: 'put',
data: data,
headers: {'Content-Type': 'application/json;charset=utf-8'},
})
}
export default {
tokenName: TokenName,
request,
get,
post,
postJson,
postJsonToFile,
put,
putJson,
getJsonToFile
}

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,7 @@ const pageList = function(data) {
/**
* 选择课件的查询,这里也是分页查询,只是返回的内容,字段会很少,用于课件制作那选择已有课件内容。
*
*
* @param {Object} data
* 查询参数如上面pageList方法
*/
@@ -47,7 +47,9 @@ const findList = function(data) {
}
*/
const saveUpload = function(data) {
return ajax.post('/xboe/m/course/file/upload/save', data);
return ajax.post('/xboe/m/course/file/upload/save', data, {
timeout: 60000
});
}
/**
@@ -88,4 +90,4 @@ export default {
batchUpdate,
detail,
delFile
}
}

View File

@@ -102,6 +102,24 @@ const courseSearch=function(query){
const detailStudy = function(courseId,aid) {
return ajax.get(`/xboe/m/course/portal/detail-study?courseId=${courseId}&aid=${aid}`);
}
/**
* 课程学习进度的详细信息-分页
* @param {Object} data
*/
const detailStudyPage = function(data) {
return ajax.get(`/xboe/m/course/portal/detail-study-page?courseId=${data.courseId}&aid=${data.aid}&pageIndex=${data.pageIndex}&pageSize=${data.pageSize}`);
}
/**
* 资源学习情况列列表-分页
* @param {Object} data
*/
const pageListResource=function(data){
return ajax.post('/xboe/school/study/course/pagelist-resource',data);
}
export default {
list,
pageList,
@@ -112,5 +130,7 @@ export default {
studyCounts,
courseSearch,
detailStudy,
detailPost
detailPost,
detailStudyPage,
pageListResource
}

View File

@@ -17,7 +17,7 @@ const hasSignup = function(courseId) {
* 课程报名,微课,录播课
* @param {Object} data
* {
courseId:
courseId:
courseName:
courseType 课程类型,对应微课,录播课
signType:1,后名方式默认是1自主报名可以不传
@@ -114,6 +114,10 @@ const studyVideoTime = function(data) {
return ajax.post('/xboe/school/study/course/study-video-time',data);
}
const updateStudyVideoTime = function(data) {
return ajax.post('/xboe/school/study/course/updateStudyVideoTime',data);
}
/**
* 获取上一次的学习内容
* @returns
@@ -161,7 +165,7 @@ const appendStudyTime = function(data) {
* name: 学习人的姓名
*/
const studyRecords = function(data) {
return ajax.post('/xboe/school/study/course/pagelist',data);
return ajax.post('/xboe/school/study/course/pagelistEx',data);
}
/**
@@ -185,7 +189,7 @@ const studyContentRecords = function(data) {
}
*/
const studyExport = function(data) {
return ajax.post('/xboe/school/study/course/export',data);
return ajax.post('/xboe/school/study/course/export',data, { responseType: 'blob' });
}
/**
@@ -363,6 +367,15 @@ const deleteSignUp=function(id,courseId){
return ajax.post(`/xboe/school/study/course/delete-signup?id=${id}&couserId=${courseId}`);
}
/*
删除课程学习记录
@param id 学习id
@param courseId 课程id 用于删除课程报名信息和修改课程学习人数
*/
const deleteNewSignUp=function(data){
return ajax.post(`/xboe/school/study/course/delete-signup`, data);
}
/**
* 二次查询 用于个人主页/他人主页
* {
@@ -398,16 +411,43 @@ const findByIds=function (ids){
return ajax.postJson('/xboe/school/study/es/list-by-ids',ids);
}
const exportSignup=function (data){
return ajax.post('/xboe/school/study/course/export-signup',data, { responseType: 'blob' });
}
// 作业导出
const exportHomework=function (data){
return ajax.post('/xboe/school/study/course/contents-homework-export',data, { responseType: 'blob' });
}
// 考试导出
const exportExam=function (data){
return ajax.post('/xboe/school/study/course/contents-exam-export',data, { responseType: 'blob' });
}
// 评估类型资源
const contentsAssess=function (data){
return ajax.post('/xboe/school/study/course/contents-assess',data);
}
// 考试类型资源
const contentsExam=function (data){
return ajax.post('/xboe/school/study/course/contents-exam',data);
}
export default {
hasSignup,
signup,
findSignup,
deleteSignup,
deleteNewSignUp,
importSignup,
countSignup,
studyIndex,
studyInfo,
studyVideoTime,
updateStudyVideoTime,
lastStudy,
studyContent,
appendStudyTime,
@@ -433,5 +473,10 @@ export default {
deleteSignUp,
ids,
followIds,
studyIndexPost
studyIndexPost,
exportSignup,
exportHomework,
exportExam,
contentsAssess,
contentsExam
}

View File

@@ -0,0 +1,64 @@
/**课程标签模块的相关处理*/
import ajax from '@/utils/xajax.js'
/**
* 分页查询:标签列表
* @param {Object} query
*/
const portalPageList = function(query) {
return ajax.post('/xboe/m/coursetag/page', query);
}
//改变标签的公共属性
const changeTagPublic = function (row){
// 返回 Promise 的 API 调用
return ajax.post('/xboe/m/coursetag/changePublicStatus', {
id: row.id,
isPublic: row.isPublic
});
}
//改变标签的热点属性
const changeTagHot = function (row){
// 返回 Promise 的 API 调用
return ajax.post('/xboe/m/coursetag/changeHotStatus', {
id: row.id,
isHot: row.isHot
});
}
//查询指定id的标签关联的所有课程
const showCourseByTag = function (query){
return ajax.post('/xboe/m/coursetag/showCourseByTag', query);
}
//解除指定id的课程和某个标签之间的关联关系
const unbindCourseTagRelation = function (params){
return ajax.post('/xboe/m/coursetag/unbind', params);
}
//编辑课程:标签模糊查询
const searchTags = function (params){
return ajax.post('/xboe/m/coursetag/searchTags', params);
}
//编辑课程:创建标签(与当前课程关联)
const createTag = function (params){
return ajax.post('/xboe/m/coursetag/createTag', params);
}
//获取最新前10个热点标签
const getHotTagList = function (params){
return ajax.post('/xboe/m/coursetag/getHotTagList', params);
}
export default {
portalPageList,
changeTagPublic,
changeTagHot,
showCourseByTag,
unbindCourseTagRelation,
searchTags,
createTag,
getHotTagList
}

View File

@@ -38,7 +38,7 @@ const detailTeacher=function (id){
* tlevelId级别
* salaryId发薪地
* tsystemId
* } query
* @returns
*/

View File

@@ -1,5 +1,7 @@
import ajax from '@/utils/xajax.js'
import http from '../unionAjax'
import httpAjax from '../httpAjax'
const baseURL = process.env.VUE_APP_MANAGER_API_PATH;
@@ -47,6 +49,18 @@ const articlelist=function (type){
const courselist=function (data){
return ajax.post('/xboe/portal/index/courselist',data);
}
// 精品课信息列表
const qualitylist=function (data){
return httpAjax.post(baseURL,'/quality/home/qualityItem',data);
}
// 精品课分页查询
export const qualityPageList=function (data){
return httpAjax.post(baseURL,'/quality/home/qualityPages',data);
}
// 课程精品课标记时间年份列表
export const qualityCourseTimeMark=function (){
return httpAjax.post(baseURL,'/quality/manage/qualityYearList',{});
}
/**
* 首页新课程推荐列表
*/
@@ -61,5 +75,7 @@ export default {
articlelist,
courselist,
newCases,
getRecommendList
getRecommendList,
qualitylist,
qualityPageList
}

View File

@@ -0,0 +1,37 @@
import ajax2 from "../unionAjax.js";
export const STUDENT_LIST = "/manageApi/admin/student/getStudent";
export const USER_LIST_PAGE = "/manageApi/admin/thirdApi/user/list";
export const ORG_LIST = "/manageApi/admin/thirdApi/org/list";
export const ORG_CHILD_LIST = "/manageApi/admin/thirdApi/org/info";
// 查询受众中的用户列表
export const AUDIENCE_LIST = "/userbasic/audience/memberList";
export const USER_AUDIENCES = "/manageApi/admin/thirdApi/audience/userAudiences";
export const fetchUserAudiences = (params) =>
ajax2.get1(USER_AUDIENCES, params);
// 保存学员信息(走 manageApiPOST
export const saveStu = (data) =>
ajax2.postJson("/manageApi", "/admin/student/addStudent", data);
// 获取项目学员列表(走 manageApiGET弃用
export const fetchProjectStudents = (params = {}) => {
return ajax2.get1(STUDENT_LIST, params);
};
// 快速学员搜索(走 manageApiPOST
export const fetchQuickStudents = (params) =>
ajax2.get1(USER_LIST_PAGE, params);
// 组织列表(走 manageApiPOST
export const fetchOrgList = (params) =>
ajax2.get1(ORG_LIST, params);
// 子组织列表(走 manageApiPOST
export const fetchOrgChildren = (params) =>
ajax2.get1(ORG_CHILD_LIST, params);
// 受众中的用户列表POSTapplication/json
export const fetchAudienceList = (data) =>
ajax2.postJson("", AUDIENCE_LIST, data);

View File

@@ -106,6 +106,15 @@ const get = function (baseURL, url) {
})
}
const get1= function (baseURL, params) {
return request({
baseURL,
method: 'get',
params: params,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
}
/**
* post请求
* @param {Object} url
@@ -199,6 +208,7 @@ export default {
tokenName: TokenName,
request,
get,
get1,
post,
postJson,
postJsonToFile,

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="14px" viewBox="0 0 12 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>新建课程</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理端列表页2版" transform="translate(-253, -258)" fill="#4284F7" fill-rule="nonzero">
<path d="M263.588235,258 C264.367931,258 265,258.600685 265,259.341667 L265,265.459375 C265,265.737243 264.762974,265.9625 264.470588,265.9625 C264.178202,265.9625 263.941176,265.737243 263.941176,265.459375 L263.941176,259.341667 C263.941176,259.252709 263.903992,259.167394 263.837802,259.104491 C263.771613,259.041588 263.681841,259.00625 263.588235,259.00625 L254.411765,259.00625 C254.318159,259.00625 254.228387,259.041588 254.162198,259.104491 C254.096008,259.167394 254.058824,259.252709 254.058824,259.341667 L254.058824,270.658333 C254.058824,270.747291 254.096008,270.832606 254.162198,270.895509 C254.228387,270.958412 254.318159,270.99375 254.411765,270.99375 L257.411765,270.99375 C257.704116,270.993797 257.941087,271.21904 257.941087,271.496875 C257.941087,271.77471 257.704116,272 257.411765,272 L254.411765,272 C253.632069,272 253,271.399315 253,270.658333 L253,259.341667 C253,258.600685 253.632069,258 254.411765,258 L263.588235,258 Z M261.812997,265.982255 C262.658243,265.982255 263.46887,266.299261 264.066549,266.863534 C264.664227,267.427807 265,268.193125 265,268.991128 C265,270.652882 263.57313,272 261.812997,272 C260.052864,272 258.625995,270.652882 258.625995,268.991128 C258.625995,267.329373 260.052864,265.982255 261.812997,265.982255 Z M261.812997,266.851485 C260.561347,266.851485 259.546684,267.809436 259.546684,268.991128 C259.546684,270.17282 260.561347,271.13077 261.812997,271.13077 C263.063839,271.128929 264.07736,270.172056 264.07931,268.991128 C264.07931,267.809436 263.064647,266.851485 261.812997,266.851485 Z M261.741379,267.495134 C261.93817,267.495134 262.097701,267.646158 262.097701,267.832455 L262.097701,268.675757 L262.988506,268.675757 C263.185297,268.675757 263.344828,268.826781 263.344828,269.013078 C263.344828,269.199375 263.185297,269.350399 262.988506,269.350399 L262.097701,269.350399 L262.097701,270.193701 C262.097701,270.379998 261.93817,270.531022 261.741379,270.531022 C261.544588,270.531022 261.385057,270.379998 261.385057,270.193701 L261.385057,269.350399 L260.494253,269.350399 C260.297462,269.350399 260.137931,269.199375 260.137931,269.013078 C260.137931,268.826781 260.297462,268.675757 260.494253,268.675757 L261.385057,268.675757 L261.385057,267.832455 C261.385057,267.646158 261.544588,267.495134 261.741379,267.495134 Z M259.157162,264.14695 C259.450517,264.14695 259.688329,264.37147 259.688329,264.648429 C259.688329,264.925388 259.450517,265.149908 259.157162,265.149908 L256.324271,265.149908 C256.030915,265.149908 255.793103,264.925388 255.793103,264.648429 C255.793103,264.37147 256.030915,264.14695 256.324271,264.14695 L259.157162,264.14695 Z M261.28183,261.138078 C261.575151,261.138125 261.812907,261.362631 261.812907,261.639557 C261.812907,261.916482 261.575151,262.140988 261.28183,262.141035 L256.324271,262.141035 C256.03095,262.140988 255.793193,261.916482 255.793193,261.639557 C255.793193,261.362631 256.03095,261.138125 256.324271,261.138078 L261.28183,261.138078 Z" id="新建课程"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="14px" viewBox="0 0 12 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>新建课程2</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理端列表页2版_展开" transform="translate(-253, -304)" fill="#FFFFFF" fill-rule="nonzero">
<path d="M263.588235,304 C264.367931,304 265,304.600685 265,305.341667 L265,311.459375 C265,311.737243 264.762974,311.9625 264.470588,311.9625 C264.178202,311.9625 263.941176,311.737243 263.941176,311.459375 L263.941176,305.341667 C263.941176,305.252709 263.903992,305.167394 263.837802,305.104491 C263.771613,305.041588 263.681841,305.00625 263.588235,305.00625 L254.411765,305.00625 C254.318159,305.00625 254.228387,305.041588 254.162198,305.104491 C254.096008,305.167394 254.058824,305.252709 254.058824,305.341667 L254.058824,316.658333 C254.058824,316.747291 254.096008,316.832606 254.162198,316.895509 C254.228387,316.958412 254.318159,316.99375 254.411765,316.99375 L257.411765,316.99375 C257.704116,316.993797 257.941087,317.21904 257.941087,317.496875 C257.941087,317.77471 257.704116,318 257.411765,318 L254.411765,318 C253.632069,318 253,317.399315 253,316.658333 L253,305.341667 C253,304.600685 253.632069,304 254.411765,304 L263.588235,304 Z M261.812997,311.982255 C262.658243,311.982255 263.46887,312.299261 264.066549,312.863534 C264.664227,313.427807 265,314.193125 265,314.991128 C265,316.652882 263.57313,318 261.812997,318 C260.052864,318 258.625995,316.652882 258.625995,314.991128 C258.625995,313.329373 260.052864,311.982255 261.812997,311.982255 Z M261.812997,312.851485 C260.561347,312.851485 259.546684,313.809436 259.546684,314.991128 C259.546684,316.17282 260.561347,317.13077 261.812997,317.13077 C263.063839,317.128929 264.07736,316.172056 264.07931,314.991128 C264.07931,313.809436 263.064647,312.851485 261.812997,312.851485 Z M261.741379,313.495134 C261.93817,313.495134 262.097701,313.646158 262.097701,313.832455 L262.097701,314.675757 L262.988506,314.675757 C263.185297,314.675757 263.344828,314.826781 263.344828,315.013078 C263.344828,315.199375 263.185297,315.350399 262.988506,315.350399 L262.097701,315.350399 L262.097701,316.193701 C262.097701,316.379998 261.93817,316.531022 261.741379,316.531022 C261.544588,316.531022 261.385057,316.379998 261.385057,316.193701 L261.385057,315.350399 L260.494253,315.350399 C260.297462,315.350399 260.137931,315.199375 260.137931,315.013078 C260.137931,314.826781 260.297462,314.675757 260.494253,314.675757 L261.385057,314.675757 L261.385057,313.832455 C261.385057,313.646158 261.544588,313.495134 261.741379,313.495134 Z M259.157162,310.14695 C259.450517,310.14695 259.688329,310.37147 259.688329,310.648429 C259.688329,310.925388 259.450517,311.149908 259.157162,311.149908 L256.324271,311.149908 C256.030915,311.149908 255.793103,310.925388 255.793103,310.648429 C255.793103,310.37147 256.030915,310.14695 256.324271,310.14695 L259.157162,310.14695 Z M261.28183,307.138078 C261.575151,307.138125 261.812907,307.362631 261.812907,307.639557 C261.812907,307.916482 261.575151,308.140988 261.28183,308.141035 L256.324271,308.141035 C256.03095,308.140988 255.793193,307.916482 255.793193,307.639557 C255.793193,307.362631 256.03095,307.138125 256.324271,307.138078 L261.28183,307.138078 Z" id="新建课程2"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>导出</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理端列表页2版" transform="translate(-406, -258)" fill="#999999" fill-rule="nonzero">
<path d="M407.8375,272 C407.3125,272 406.875,271.822785 406.525,271.468354 C406.175,271.113924 406,270.670886 406,270.139241 L406,267.56962 C406,267.392405 406.0875,267.21519 406.175,267.126582 C406.2625,267.037975 406.4375,266.949367 406.6125,266.949367 C406.7875,266.949367 406.9625,267.037975 407.05,267.126582 C407.1375,267.21519 407.225,267.392405 407.225,267.56962 L407.225,270.139241 C407.225,270.316456 407.3125,270.582278 407.4,270.670886 C407.4875,270.759494 407.6625,270.848101 407.925,270.848101 L418.075,270.848101 C418.25,270.848101 418.5125,270.759494 418.6,270.670886 C418.6875,270.582278 418.775,270.405063 418.775,270.139241 L418.775,267.56962 C418.775,267.392405 418.8625,267.21519 418.95,267.126582 C419.0375,267.037975 419.2125,266.949367 419.3875,266.949367 C419.5625,266.949367 419.7375,267.037975 419.825,267.126582 C419.9125,267.21519 420,267.392405 420,267.56962 L420,270.139241 C420,270.670886 419.825,271.113924 419.475,271.468354 C419.125,271.822785 418.6875,272 418.1625,272 L407.8375,272 Z M413,268.189873 C412.825,268.189873 412.65,268.101266 412.5625,268.012658 C412.475,267.924051 412.3875,267.746835 412.3875,267.56962 L412.3875,260.126582 C412.3875,260.126582 412.3875,260.037975 412.3,260.037975 L412.2125,260.037975 L410.2,262.253165 C410.1125,262.341772 409.85,262.43038 409.85,262.43038 C409.675,262.43038 409.5,262.341772 409.4125,262.253165 C409.2375,262.075949 409.15,261.987342 409.15,261.898734 C409.15,261.721519 409.2375,261.544304 409.325,261.455696 L412.475,258.265823 C412.65,258.088608 412.825,258 413,258 C413.175,258 413.35,258.088608 413.4375,258.177215 L416.5,261.455696 C416.5875,261.544304 416.675,261.721519 416.675,261.898734 C416.675,262.075949 416.5875,262.253165 416.5,262.341772 C416.4125,262.43038 416.2375,262.518987 416.0625,262.518987 C415.8875,262.518987 415.8,262.341772 415.7125,262.253165 L413.6125,260.037975 L413.525,260.037975 C413.525,260.037975 413.4375,260.037975 413.4375,260.126582 L413.4375,267.658228 C413.4375,267.835443 413.35,268.012658 413.2625,268.101266 C413.175,268.189873 413.0875,268.189873 413,268.189873 Z" id="导出"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>导出</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理端列表页2版_展开" transform="translate(-399, -295)">
<g id="导出" transform="translate(399, 295)">
<rect id="矩形" fill="#000000" opacity="0.05" x="0" y="0" width="32" height="32" rx="4"></rect>
<path d="M10.8375,23 C10.3125,23 9.875,22.8227848 9.525,22.4683544 C9.175,22.1139241 9,21.6708861 9,21.1392405 L9,18.5696203 C9,18.3924051 9.0875,18.2151899 9.175,18.1265823 C9.2625,18.0379747 9.4375,17.9493671 9.6125,17.9493671 C9.7875,17.9493671 9.9625,18.0379747 10.05,18.1265823 C10.1375,18.2151899 10.225,18.3924051 10.225,18.5696203 L10.225,21.1392405 C10.225,21.3164557 10.3125,21.5822785 10.4,21.6708861 C10.4875,21.7594937 10.6625,21.8481013 10.925,21.8481013 L21.075,21.8481013 C21.25,21.8481013 21.5125,21.7594937 21.6,21.6708861 C21.6875,21.5822785 21.775,21.4050633 21.775,21.1392405 L21.775,18.5696203 C21.775,18.3924051 21.8625,18.2151899 21.95,18.1265823 C22.0375,18.0379747 22.2125,17.9493671 22.3875,17.9493671 C22.5625,17.9493671 22.7375,18.0379747 22.825,18.1265823 C22.9125,18.2151899 23,18.3924051 23,18.5696203 L23,21.1392405 C23,21.6708861 22.825,22.1139241 22.475,22.4683544 C22.125,22.8227848 21.6875,23 21.1625,23 L10.8375,23 Z M16,19.1898734 C15.825,19.1898734 15.65,19.1012658 15.5625,19.0126582 C15.475,18.9240506 15.3875,18.7468354 15.3875,18.5696203 L15.3875,11.1265823 C15.3875,11.1265823 15.3875,11.0379747 15.3,11.0379747 L15.2125,11.0379747 L13.2,13.2531646 C13.1125,13.3417722 12.85,13.4303797 12.85,13.4303797 C12.675,13.4303797 12.5,13.3417722 12.4125,13.2531646 C12.2375,13.0759494 12.15,12.9873418 12.15,12.8987342 C12.15,12.721519 12.2375,12.5443038 12.325,12.4556962 L15.475,9.26582278 C15.65,9.08860759 15.825,9 16,9 C16.175,9 16.35,9.08860759 16.4375,9.17721519 L19.5,12.4556962 C19.5875,12.5443038 19.675,12.721519 19.675,12.8987342 C19.675,13.0759494 19.5875,13.2531646 19.5,13.3417722 C19.4125,13.4303797 19.2375,13.5189873 19.0625,13.5189873 C18.8875,13.5189873 18.8,13.3417722 18.7125,13.2531646 L16.6125,11.0379747 L16.525,11.0379747 C16.525,11.0379747 16.4375,11.0379747 16.4375,11.1265823 L16.4375,18.6582278 C16.4375,18.835443 16.35,19.0126582 16.2625,19.1012658 C16.175,19.1898734 16.0875,19.1898734 16,19.1898734 Z" id="形状" fill="#4284F7" fill-rule="nonzero"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="10px" height="14px" viewBox="0 0 10 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>置顶</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理端列表页2版" transform="translate(-370, -258)" fill="#999999" fill-rule="nonzero">
<path d="M379.893423,258.616603 C379.893423,258.957143 379.62302,259.233205 379.289461,259.233205 L370.613945,259.233205 C370.280386,259.233205 370.009984,258.957143 370.009984,258.616603 C370.009984,258.276062 370.280386,258 370.613945,258 L379.289461,258 C379.62302,258 379.893423,258.276062 379.893423,258.616603 Z M375.000061,260.909695 C374.666502,260.909695 374.3961,261.185758 374.3961,261.526298 L374.3961,271.383397 C374.3961,271.723938 374.666502,272 375.000061,272 C375.33362,272 375.604022,271.723938 375.604022,271.383397 L375.604022,261.526298 C375.604022,261.185758 375.33362,260.909695 375.000061,260.909695 Z M374.605006,260.423894 L370.155854,264.965705 C369.936707,265.189438 369.950361,265.566044 370.18612,265.806738 C370.422106,266.047663 370.790764,266.061371 371.009911,265.837637 L375.458835,261.295827 C375.677754,261.072094 375.664327,260.695487 375.428569,260.454794 C375.19281,260.214101 374.823925,260.200161 374.605006,260.423894 Z M374.571553,260.454794 C374.335794,260.695487 374.32214,261.072094 374.541287,261.295827 L378.990211,265.83787 C379.20913,266.061371 379.578015,266.047663 379.814002,265.806738 C380.049761,265.566044 380.063187,265.189438 379.844041,264.965705 L375.395344,260.423894 C375.176197,260.200161 374.807312,260.214101 374.571553,260.454794 Z" id="置顶"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>置顶</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理端列表页2版_展开" transform="translate(-359, -295)">
<g id="置顶" transform="translate(359, 295)">
<rect id="矩形" fill="#000000" opacity="0.05" x="0" y="0" width="32" height="32" rx="4"></rect>
<path d="M20.8934226,9.61660263 C20.8934226,9.95714285 20.6230199,10.2332053 20.2894612,10.2332053 L11.613945,10.2332053 C11.2803864,10.2332053 11.0099836,9.95714285 11.0099836,9.61660263 C11.0099836,9.2760624 11.2803864,9 11.613945,9 L20.2894612,9 C20.6230199,9 20.8934226,9.2760624 20.8934226,9.61660263 Z M16.000061,11.9096953 C15.6665023,11.9096953 15.3960996,12.1857577 15.3960996,12.5262979 L15.3960996,22.3833974 C15.3960996,22.7239376 15.6665023,23 16.000061,23 C16.3336196,23 16.6040224,22.7239376 16.6040224,22.3833974 L16.6040224,12.5262979 C16.6040224,12.1857577 16.3336196,11.9096953 16.000061,11.9096953 Z M15.6050056,11.4238942 L11.1558537,15.9657046 C10.9367072,16.1894379 10.9503612,16.5660441 11.1861201,16.8067376 C11.4221065,17.0476633 11.7907642,17.0613707 12.0099107,16.8376374 L16.458835,12.295827 C16.6777539,12.0720936 16.6643275,11.6954874 16.4285686,11.454794 C16.1928098,11.2141006 15.8239245,11.2001608 15.6050056,11.4238942 Z M15.5715533,11.454794 C15.3357945,11.6954874 15.3221405,12.0720936 15.541287,12.295827 L19.9902113,16.8378697 C20.2091302,17.0613707 20.5780155,17.0476633 20.8140019,16.8067376 C21.0497608,16.5660441 21.0631872,16.1894379 20.8440407,15.9657046 L16.3953439,11.4238942 C16.1761974,11.2001608 15.8073122,11.2141006 15.5715533,11.454794 Z" fill="#4284F7" fill-rule="nonzero"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="14px" viewBox="0 0 15 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>重置</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理端列表页2版" transform="translate(-1856, -184)" fill="#999999" fill-rule="nonzero">
<path d="M1869.71817,192.111106 C1869.4322,192.034115 1869.13954,192.209582 1869.06445,192.503055 C1868.40237,195.092745 1866.11453,196.901755 1863.50209,196.901755 C1861.15555,196.899152 1859.04494,195.436448 1858.16588,193.203628 L1859.21633,193.203628 L1857.5998,190.995338 L1856,193.203628 L1857.02588,193.203628 C1857.04017,193.247973 1857.05486,193.292079 1857.06996,193.335947 C1858.03525,196.131656 1860.61197,198.000082 1863.50209,198 C1866.60098,198 1869.31413,195.854292 1870.10009,192.781997 C1870.17511,192.488507 1870.00413,192.188163 1869.71817,192.111106 L1869.71817,192.111106 Z M1857.27782,189.936967 C1857.41541,189.973056 1857.56135,189.951488 1857.68343,189.877019 C1857.80551,189.802551 1857.89371,189.6813 1857.92858,189.540011 C1858.57704,186.92501 1860.8728,185.095707 1863.50209,185.098933 C1865.88559,185.098933 1867.97254,186.565167 1868.84057,188.800279 L1867.78367,188.800279 L1869.4002,191.008569 L1871,188.800279 L1869.97935,188.800279 C1869.02652,185.848952 1866.29164,183.895768 1863.26396,184.004305 C1860.23628,184.112842 1857.64087,186.257109 1856.89102,189.269473 C1856.81842,189.563384 1856.99152,189.8621 1857.27782,189.936967 Z" id="重置"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>zhongzhi-</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理端列表页2版_展开" transform="translate(-867, -217)">
<g id="zhongzhi-" transform="translate(867, 217)">
<rect id="矩形备份-12" fill="#000000" opacity="0.05" x="0" y="0" width="32" height="32" rx="6"></rect>
<path d="M22.7181736,17.1111055 C22.4321954,17.0341148 22.1395394,17.209582 22.0644543,17.5030548 C21.4023719,20.092745 19.1145286,21.9017553 16.5020908,21.9017553 C14.1555467,21.8991521 12.0449381,20.4364475 11.1658807,18.2036283 L12.2163267,18.2036283 L10.5998002,15.9953376 L9,18.2036283 L10.0258793,18.2036283 C10.0401663,18.2479729 10.0548599,18.2920791 10.06996,18.3359469 C11.0352515,21.1316558 13.6119724,23.0000823 16.5020908,23 C19.600985,23 22.3141291,20.8542924 23.1000906,17.7819967 C23.1751107,17.4885065 23.0041347,17.1881629 22.7181736,17.1111055 L22.7181736,17.1111055 Z M10.2778191,14.9369673 C10.4154149,14.9730564 10.5613478,14.951488 10.6834293,14.8770194 C10.8055109,14.8025508 10.8937114,14.6813 10.9285764,14.5400114 C11.5770444,11.9250098 13.8728029,10.0957074 16.5020908,10.0989331 C18.8855875,10.0989331 20.972541,11.5651666 21.8405659,13.8002787 L20.7836733,13.8002787 L22.4001998,16.0085694 L24,13.8002787 L22.9793477,13.8002787 C22.0265159,10.848952 19.2916412,8.89576768 16.2639616,9.00430498 C13.2362819,9.11284227 10.6408709,11.2571085 9.89102356,14.2694734 C9.8184212,14.5633845 9.9915194,14.8621004 10.2778191,14.9369673 Z" id="形状" fill="#999999" fill-rule="nonzero"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>sousuo</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="京东方_在线管理3版" transform="translate(-1496, -191)" fill="#FFFFFF" fill-rule="nonzero">
<g id="chaxun" transform="translate(1482, 179)">
<g id="sousuo" transform="translate(14, 12)">
<path d="M15.8180325,14.9374363 L12.4571361,11.5685482 C13.5099726,10.3025262 14.0854618,8.70594283 14.0830354,7.05780481 C14.0830354,3.15992486 10.9303387,0 7.04166051,0 C3.15269672,0 0,3.16021111 0,7.05780481 C0,10.9553985 3.15269672,14.1153234 7.04166051,14.1153234 C8.70394773,14.1177783 10.3130671,13.5283697 11.5820693,12.452205 L14.9398241,15.8176581 C15.0612025,15.9393148 15.219994,16 15.3790711,16 C15.6301938,16 15.8565501,15.8482487 15.952674,15.6157194 C16.048798,15.38319 15.9957782,15.1155246 15.8183181,14.9374363 L15.8180325,14.9374363 Z M7.04166051,12.8704224 C5.50312892,12.872373 4.0272712,12.2596195 2.94078432,11.1677968 C1.85145906,10.0788189 1.24010717,8.59957752 1.24205333,7.05751856 C1.24010717,5.51545961 1.85145906,4.0362182 2.94078432,2.94724036 C4.02736505,1.8556276 5.50321116,1.24308494 7.04166051,1.24518646 C8.5801921,1.2432366 10.0560498,1.85599012 11.1425367,2.94781286 C12.2316602,4.03678569 12.8428963,5.51589252 12.8409821,7.05780481 C12.8429283,8.59986377 12.2315764,10.0791052 11.1422511,11.168083 C10.0557872,12.2597304 8.58005203,12.8723727 7.04166051,12.8704224 L7.04166051,12.8704224 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>chaxun</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="管理端列表页2版" transform="translate(-1807, -175)">
<g id="chaxun" transform="translate(1807, 175)">
<rect id="矩形备份-11" fill="#4284F7" x="0" y="0" width="32" height="32" rx="6"></rect>
<path d="M23.8180325,22.9374363 L20.4571361,19.5685482 C21.5099726,18.3025262 22.0854618,16.7059428 22.0830354,15.0578048 C22.0830354,11.1599249 18.9303387,8 15.0416605,8 C11.1526967,8 8,11.1602111 8,15.0578048 C8,18.9553985 11.1526967,22.1153234 15.0416605,22.1153234 C16.7039477,22.1177783 18.3130671,21.5283697 19.5820693,20.452205 L22.9398241,23.8176581 C23.0612025,23.9393148 23.219994,24 23.3790711,24 C23.6301938,24 23.8565501,23.8482487 23.952674,23.6157194 C24.048798,23.38319 23.9957782,23.1155246 23.8183181,22.9374363 L23.8180325,22.9374363 Z M15.0416605,20.8704224 C13.5031289,20.872373 12.0272712,20.2596195 10.9407843,19.1677968 C9.85145906,18.0788189 9.24010717,16.5995775 9.24205333,15.0575186 C9.24010717,13.5154596 9.85145906,12.0362182 10.9407843,10.9472404 C12.0273651,9.8556276 13.5032112,9.24308494 15.0416605,9.24518646 C16.5801921,9.2432366 18.0560498,9.85599012 19.1425367,10.9478129 C20.2316602,12.0367857 20.8428963,13.5158925 20.8409821,15.0578048 C20.8429283,16.5998638 20.2315764,18.0791052 19.1422511,19.168083 C18.0557872,20.2597304 16.580052,20.8723727 15.0416605,20.8704224 L15.0416605,20.8704224 Z" id="搜索" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="10px" height="6px" viewBox="0 0 10 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>收起</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="京东方_在线管理_展开" transform="translate(-864, -257)" fill="#4284F7" fill-rule="nonzero">
<g id="收起" transform="translate(869, 260) scale(-1, -1) rotate(-270) translate(-869, -260)translate(866, 255)">
<path d="M0.828204731,0.121981959 C0.622033338,-0.0563083543 0.311020892,-0.036938598 0.12859169,0.165553637 C-0.0538375124,0.368045871 -0.040602445,0.679202183 0.158363572,0.865490299 L4.75263287,4.99731525 L0.186899406,9.12914019 C-0.000258078139,9.29809982 -0.0324364247,9.57982078 0.111805105,9.78658969 L0.151855399,9.83562322 C0.337423297,10.0402931 0.653830189,10.05597 0.85874308,9.87064716 L5.83549268,5.36756839 C5.94042055,5.2725631 6.00019036,5.13759575 6,4.99609231 C5.99980873,4.85458886 5.93967513,4.71978301 5.83449142,4.62506073 L0.828204731,0.121981959 Z" id="路径"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -392,3 +392,274 @@ li{
}
}
.custom-confirm-dialog {
max-width: 692px;
min-width: 600px;
min-height: 222px !important;
padding: 0px 0px 0px;
border-radius: 10px;
height: auto !important;
.el-message-box__header {
// padding: 0 0 16px 0;
padding: 8px 8px 2px 16px;
display: block;
.el-message-box__title {
font-size: 16px;
color: #000;
line-height: 32px;
}
.el-message-box__headerbtn {
top: 14px;
right: 10px;
.el-message-box__close {
font-size: 22px;
color: #b2b2b2;
}
}
}
.el-message-box__content {
margin-top: 0;
padding: 50px 0;
.el-message-box__status {
margin-right: 14px;
font-size: 24px;
color: #e32e2e;
// display: block;
}
.el-message-box__message {
margin-left: 0;
color: #000;
font-size: 16px;
line-height: 32px;
font-weight: normal;
display: flex;
align-items: center;
justify-content: center;
padding: 0 20px;
p{
display: flex;
align-items: baseline;
justify-content: center;
text-align: left;
.el-icon-warning-outline{
margin-right: 6px;
font-size: 18px;
color: #e32e2e;
}
}
}
}
.el-message-box__btns {
padding: 0;
display: flex;
justify-content: flex-end;
padding-right: 20px;
margin-top: 8px;
.el-button {
width: 78px;
height: 32px;
font-size: 14px;
border-radius: 6px;
padding: 0 18px;
&:nth-child(2){
margin-left: 10px !important;
}
}
.el-button--default {
color: rgba(0, 0, 0, .3);
border-color: rgba(0, 0, 0, .3);
background-color: #FFFFFF;
}
.el-button--primary {
background-color: #3b7cff;
border-color: #3b7cff;
color: #fff;
}
}
}
.common-course-dialog {
.el-dialog__footer {
padding: 10px 20px 16px;
.el-button {
width: 78px;
height: 32px;
font-size: 14px;
border-radius: 6px;
padding: 0 18px;
&:nth-child(2){
margin-left: 10px !important;
}
}
.el-button--default {
color: rgba(0, 0, 0, .3);
border-color: rgba(0, 0, 0, .3);
background-color: #FFFFFF;
}
.el-button--primary {
background-color: #3b7cff;
border-color: #3b7cff;
color: #fff;
}
}
}
.use-table {
td.el-table__cell {
border-bottom: 1px solid rgba(0, 0, 0, .1);
}
th.el-table__cell {
background: rgba(66, 132, 247, 0.1);
// padding: 3px 0;
.cell {
font-weight: bold;
font-size: 14px;
color: #60769D;
}
.caret-wrapper {
.sort-caret {
border: 4px solid transparent;
&.ascending {
border-bottom-color: #C0C4CC;
top: 8px;
}
&.descending {
border-top-color: #C0C4CC;
bottom: 8px;
}
}
}
&.ascending .sort-caret.ascending {
border-bottom-color: #409EFF;
}
&.descending .sort-caret.descending{
border-top-color: #409EFF;
}
&.el-table--medium .el-table__cell {
padding: 5px 0;
}
}
.course-name {
font-weight: 400;
font-size: 14px;
color: #000000;
line-height: 20px;
}
.common-cell {
font-weight: 400;
font-size: 14px;
color: #000000;
}
.common-cell-right {
padding-right: 20px;
}
.single-line-ellipsis {
display: inline-block;
max-width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
}
::v-deep .el-table--medium .el-table__cell {
padding: 5px 0;
}
}
.pagination {
text-align: right;
padding-top: 20px;
.el-pagination {
.el-pagination__total {
font-size: 14px;
color: #000000;
}
.el-pagination__sizes {
margin-right: 4px;
.el-input{
margin: 0;
width: 89px;
}
.el-input__inner {
width: 89px;
background: #F5F9FF;
border-radius: 4px;
border: 1px solid #DFDFDF;
height: 28px;
font-size: 14px;
color: #000000;
}
}
.btn-prev, .btn-next {
width: 28px;
height: 28px;
background: #F5F9FF;
border-radius: 4px;
border: 1px solid #DFDFDF;
// &:hover {
// background: #4284F7;
// color: #FFFFFF;
// }
}
.btn-quicknext{
background-color: transparent !important;
border: none;
line-height: 44px;
&:before {
content: '......';
}
}
.el-pager {
.number {
min-width: 28px;
height: 28px;
background: #F5F9FF;
border-radius: 4px;
border: 1px solid #DFDFDF;
font-weight: normal;
color: #000000;
margin: 0 4px;
&.active {
background-color: #4284F7 !important;
color: #FFFFFF;
border: none;
}
}
}
.el-pagination__jump {
font-size: 14px;
color: #000000;
margin-left: 4px;
.el-input__inner {
width: 28px;
height: 28px;
background: #F5F9FF;
border-radius: 4px;
border: 1px solid #DFDFDF;
font-size: 14px;
color: #000000;
}
}
}
}

View File

@@ -432,6 +432,64 @@
color: #333333;
}
}
.el-message.new-message {
box-shadow: none !important;
background-color: #edf2fc !important;
min-width: 240px !important;
height: 52px !important;
border-radius: 12px !important;
top: 236px !important;
font-size: 20px !important;
font-weight: bold !important;
border: none !important;
}
.el-message--success.new-message {
box-shadow: none !important;
background-color: rgba($color: #4CB967, $alpha: 0.1) !important;
min-width: 240px !important;
height: 52px !important;
border-radius: 12px !important;
top: 236px !important;
font-size: 22px !important;
border: none !important;
.el-message__content {
color: #189B39 !important;
font-size: 20px !important;
font-weight: bold !important;
}
}
.el-message--error.new-message {
box-shadow: none !important;
background-color: rgba($color: #FF3636 , $alpha: 0.1) !important;
min-width: 240px !important;
height: 52px !important;
border-radius: 12px !important;
top: 236px !important;
font-size: 22px !important;
font-weight: bold !important;
border: none !important;
.el-message__content {
color: #CF1717 !important;
font-size: 20px !important;
font-weight: bold !important;
}
}
.el-message--warning.new-message {
box-shadow: none !important;
background-color: #fdf6ec !important;
min-width: 240px !important;
height: 52px !important;
border-radius: 12px !important;
top: 236px !important;
font-size: 20px !important;
font-weight: bold !important;
border: none !important;
}
.el-badge__content{// badge去掉白色边框
border:1px solid #f56c6c;
}

View File

@@ -0,0 +1,314 @@
<template>
<el-dialog
class="common-course-dialog"
title="置顶排序"
:visible.sync="dialogVisible"
width="820px"
:close-on-click-modal="false"
@closed="handleClosed"
append-to-body
>
<div class="top-course-sorter" v-loading="loading">
<el-table
v-if="topList.length"
ref="sortTable"
:data="topList"
class="top-course-sorter__table use-table"
row-key="id"
:row-class-name="getRowClassName"
>
<el-table-column width="60" align="center">
<template slot-scope="scope">
<div class="drag-handle">
<i class="el-icon-s-operation"></i>
</div>
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="80" align="left">
<template slot-scope="scope">
<span class="common-cell">{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column prop="name" label="课程名称" min-width="200">
<template slot-scope="scope">
<el-tooltip :content="scope.row.name" placement="top" :disabled="!scope.row.name">
<div class="cell-text common-cell">{{ scope.row.name }}</div>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="teacherName" label="授课教师" :min-width="teacherColumnWidth" align="center">
<template slot-scope="scope">
<span class="common-cell">{{ scope.row.teacherName || '-' }}</span>
</template>
</el-table-column>
</el-table>
<el-empty v-else-if="!loading" description="暂无置顶课程"></el-empty>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" :disabled="!topList.length" :loading="saving" @click="handleSave">确定</el-button>
</span>
</el-dialog>
</template>
<script>
import apiCourse from '@/api/modules/course.js';
export default {
name: 'TopCourseSorter',
computed: {
// 动态计算"授课教师"列的最小宽度
teacherColumnWidth() {
return this.calcColumnWidth('授课教师', 'teacherName');
},
},
data() {
return {
dialogVisible: false,
loading: false,
saving: false,
topList: [],
draggingIndex: null,
};
},
watch: {
topList: {
handler(newVal, oldVal) {
// 只在列表长度变化或首次加载时初始化拖拽事件
if (!oldVal || newVal.length !== oldVal.length) {
this.$nextTick(() => {
this.initDragEvents();
});
}
},
immediate: false,
},
},
methods: {
open() {
this.dialogVisible = true;
this.fetchTopList();
},
async fetchTopList() {
this.loading = true;
try {
const res = await apiCourse.fetchTopCourseList();
if (res.status === 200) {
this.topList = res.result.map(item=>{
return {
...item,
// teacherName: '对对对柳在一、李玉冰、李国鑫、张添瑞、张子峰、 柳在一、李玉冰、李国鑫、张添瑞、张子峰'
}
})
} else {
this.$message.error(res.message || '获取置顶课程失败');
this.topList = [];
}
} catch (error) {
this.$message.error(error.message || '获取置顶课程失败');
this.topList = [];
} finally {
this.loading = false;
}
},
getRowClassName({ row, rowIndex }) {
if (this.draggingIndex === rowIndex) {
return 'is-dragging';
}
return '';
},
initDragEvents() {
if (!this.$refs.sortTable) return;
const tableBody = this.$refs.sortTable.$el.querySelector('.el-table__body-wrapper tbody');
if (!tableBody) return;
const rows = tableBody.querySelectorAll('tr');
rows.forEach((row, index) => {
// 移除旧的事件监听器
row.removeEventListener('dragstart', this.handleDragStart);
row.removeEventListener('dragover', this.handleDragOver);
row.removeEventListener('drop', this.handleDrop);
row.removeEventListener('dragend', this.handleDragEnd);
// 设置可拖拽
row.draggable = true;
row.setAttribute('data-index', index);
// 添加新的事件监听器
row.addEventListener('dragstart', (e) => this.handleDragStart(index, e));
row.addEventListener('dragover', (e) => this.handleDragOver(index, e));
row.addEventListener('drop', (e) => this.handleDrop(index, e));
row.addEventListener('dragend', () => this.handleDragEnd());
});
},
handleDragStart(index, event) {
this.draggingIndex = index;
if (event && event.dataTransfer) {
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.setData('text/plain', index);
}
},
handleDragOver(index, event) {
event.preventDefault();
if (this.draggingIndex !== null && this.draggingIndex !== index) {
const tableBody = this.$refs.sortTable.$el.querySelector('.el-table__body-wrapper tbody');
if (tableBody) {
const rows = tableBody.querySelectorAll('tr');
rows.forEach((row, idx) => {
if (idx === index) {
row.classList.add('drag-over');
} else {
row.classList.remove('drag-over');
}
});
}
}
},
handleDrop(targetIndex, event) {
event.preventDefault();
if (this.draggingIndex === null || this.draggingIndex === targetIndex) {
return;
}
const movingItem = this.topList.splice(this.draggingIndex, 1)[0];
this.topList.splice(targetIndex, 0, movingItem);
this.draggingIndex = targetIndex;
// 清除拖拽样式
const tableBody = this.$refs.sortTable.$el.querySelector('.el-table__body-wrapper tbody');
if (tableBody) {
const rows = tableBody.querySelectorAll('tr');
rows.forEach((row) => {
row.classList.remove('drag-over');
});
}
// 重新初始化拖拽事件,因为 DOM 顺序已改变
this.$nextTick(() => {
this.initDragEvents();
});
},
handleDragEnd() {
this.draggingIndex = null;
// 清除所有拖拽样式
if (this.$refs.sortTable) {
const tableBody = this.$refs.sortTable.$el.querySelector('.el-table__body-wrapper tbody');
if (tableBody) {
const rows = tableBody.querySelectorAll('tr');
rows.forEach((row) => {
row.classList.remove('drag-over');
});
}
}
},
async handleSave() {
if (!this.topList.length) {
this.$message.warning('暂无需要保存的排序');
return;
}
const payload = this.topList.map((item, index) => ({
id: item.id,
sortWeight: index,
}));
this.saving = true;
try {
const res = await apiCourse.updateTopCourseSort(payload);
if (res.status === 200) {
this.$message.success('排序更新成功');
this.$emit('sorted');
this.dialogVisible = false;
} else {
throw new Error(res.message || '排序更新失败');
}
} catch (error) {
this.$message.error(error.message || '排序更新失败');
} finally {
this.saving = false;
}
},
handleClosed() {
this.topList = [];
this.draggingIndex = null;
this.loading = false;
this.saving = false;
},
// 计算文本宽度(通过隐藏 span 获取实际宽度)
getTextWidth(text = '') {
if (typeof document === 'undefined') return 0;
const span = document.createElement('span');
span.innerText = text;
span.style.cssText = 'position:absolute;visibility:hidden;font-size:14px;font-family:inherit;white-space:nowrap;';
document.body.appendChild(span);
const { width } = span.getBoundingClientRect();
document.body.removeChild(span);
return Math.ceil(width);
},
// 计算列宽(头+内容取最大值,加 padding并控制最小值
calcColumnWidth(label, prop, padding = 24, min = 130, max = Infinity) {
const contents = (this.topList || []).map(row => this.getTextWidth((row && row[prop]) || '-'));
const maxContentWidth = contents.length ? Math.max(...contents) : 0;
const labelWidth = this.getTextWidth(label || '');
const baseWidth = Math.max(maxContentWidth, labelWidth) + padding;
const clamped = Math.max(min, Math.min(baseWidth, max));
return `${clamped}px`;
},
},
};
</script>
<style lang="scss" scoped>
.top-course-sorter {
min-height: 200px;
padding-top: 8px;
}
::v-deep .el-dialog__body {
padding: 10px 20px 20px;
}
.drag-handle {
display: flex;
align-items: center;
justify-content: center;
cursor: move;
width: 100%;
height: 100%;
padding: 0 16px;
i {
font-size: 20px;
color: #c0c4cc;
}
&:hover i {
color: #409eff;
}
}
.cell-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
}
.common-cell {
font-weight: 400;
font-size: 14px;
color: #000000;
}
.dialog-footer {
text-align: right;
}
</style>

View File

@@ -50,7 +50,7 @@
<el-input-number v-model="duration" size="mini" :min="1" :max="100"></el-input-number>
</span>
</div>
<el-upload class="upload-demo" :headers="headers" :data="data" drag :action="uploadFileUrl" :on-success="handleUploadSuccess" :before-upload="handleBeforeUpload">
<el-upload ref="uploadRef" class="upload-demo" :headers="headers" :data="data" drag :action="uploadFileUrl" :on-success="handleUploadSuccess" :before-upload="handleBeforeUpload">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">文件大小限制{{curComType.maxSizeName}},支持的文件类型{{curComType.fileTypes.join(',')}}</div>
@@ -195,6 +195,7 @@
// this.cware.content.content=result.filePath;
}else{
this.$message.error(rs.message);
this.$refs.uploadRef.clearFiles();
}
});
}else{

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,400 @@
<template>
<div class="tag-container" @click="handleContainerClick">
<el-select style="width: 100%;"
v-model="selectedTags"
multiple
filterable
value-key="id"
remote
reserve-keyword
:remote-method="debouncedSearch"
:loading="loading"
:placeholder="'回车创建新标签'"
:no-data-text="'无此标签,按回车键创建'"
@remove-tag="handleTagRemove"
@change="handleSelectionChange"
@keyup.enter.native="handleEnterKey"
@keyup.delete.native="handleDeleteKey"
@focus="handleFocus"
ref="tagSelect"
>
<el-option
v-for="item in searchResults"
:key="item.id"
:label="item.tagName"
:value="item"
:disabled="isTagDisabled(item)"
/>
</el-select>
<!-- 添加标签计数显示 -->
<div class="tag-count">
{{ selectedTags.length }}/5
</div>
</div>
</template>
<script>
import { debounce } from 'lodash'
import apiCourseTag from '@/api/modules/courseTag.js'
import { mapGetters } from 'vuex';
export default {
props: {
courseId:{
type:String,
require:true,
},
sysTypeList:{
type:Array,
require:true,
default: []
},
maxTags: {
type: Number,
default: 5
},
// 添加接收初始标签数据的props
initialTags: {
type: Array,
default: () => []
}
},
data() {
return {
selectedTags: [],
searchResults: [],
loading: false,
tagMap: new Map(),
inputBuffer: '',
params: {},
tag: {},
// 添加临时存储用于回滚
previousTags: []
}
},
computed: {
...mapGetters(['userInfo']),
displayTags() {
return this.selectedTags.map(tag =>
typeof tag === 'object' ? tag : this.tagMap.get(tag)
).filter(Boolean)
}
},
created() {
this.debouncedSearch = debounce(this.doSearch, 500)
console.log("----------sysTypeList.length---------->"+this.sysTypeList.length)
console.log("----------sysTypeList.length---------->"+(this.sysTypeList.length===0))
},
// 添加:挂载时初始化标签数据
mounted() {
if (this.initialTags && this.initialTags.length > 0) {
this.selectedTags = this.initialTags;
this.searchResults = this.initialTags;
// 将初始标签添加到tagMap中确保删除功能正常
this.initialTags.forEach(tag => {
if (tag.id) {
this.tagMap.set(tag.id, tag);
}
});
}
},
watch: {
// 监听课程ID变化重置所有状态
courseId(newVal) {
this.resetTagState();
},
// 监听初始标签变化,重新加载
initialTags(newVal) {
this.selectedTags = newVal || [];
this.searchResults = newVal || [];
this.tagMap.clear(); // 清空旧缓存
newVal.forEach(tag => {
if (tag.id) this.tagMap.set(tag.id, tag);
});
},
// 监听分类变化,重新加载搜索结果
sysTypeList: {
handler() {
// 只有在已选择分类且有焦点时才重新加载
if (this.sysTypeList.length > 0 && this.$refs.tagSelect && this.$refs.tagSelect.visible) {
this.doSearch('');
}
},
deep: true
}
},
methods: {
// 新增:检查标签是否应该被禁用
isTagDisabled(tag) {
// 如果标签已经被选中,不应该禁用(允许取消选择)
const isSelected = this.selectedTags.some(selectedTag => selectedTag.id === tag.id);
if (isSelected) {
return false;
}
// 如果标签未被选中且已达到最大数量,则禁用
return this.selectedTags.length >= this.maxTags;
},
// 新增:处理输入框获得焦点事件
async handleFocus() {
this.previousTags = [...this.selectedTags];
// 当输入框获得焦点时,加载默认的搜索结果
if (this.sysTypeList.length > 0) {
await this.doSearch('');
}
this.$emit('focus');
},
handleContainerClick() {
// 容器点击时也触发焦点事件
this.$emit('focus');
},
// 新增:重置标签状态的方法
resetTagState() {
this.selectedTags = [];
this.searchResults = [];
this.tagMap.clear();
this.loading = false;
this.params = {};
},
handleTagRemove(tagId) {
this.selectedTags = this.selectedTags.filter(id => id !== tagId)
this.$emit('change', this.displayTags)
this.clearInput();
},
removeTag(tagId) {
this.handleTagRemove(tagId)
},
// 新增:处理删除键事件
handleDeleteKey(event) {
// 如果输入框内容为空,不执行任何搜索
if (!event.target.value.trim()) {
this.searchResults = []
}
},
//按回车键,创建新标签
handleEnterKey(event) {
const inputVal = event.target.value?.trim()
if (!inputVal) return;
// 检查是否与已选择的标签重复
const isDuplicate = this.selectedTags.some(tag => tag.tagName === inputVal);
if (isDuplicate) {
this.$message.warning('该标签已存在,无需重复创建');
event.target.value = '';
return;
}
if (!isDuplicate && inputVal && this.selectedTags.length < this.maxTags) {
this.createNewTag(event.target.value.trim())
this.clearInput();
} else if (this.selectedTags.length >= this.maxTags) {
this.$message.warning('最多只能添加5个标签')
this.clearInput();
} else {
this.clearInput();
}
},
// 新增:处理选择变化事件
handleSelectionChange(newValues) {
// 检查每个标签对象是否完整
newValues.forEach((tag, index) => {
if (!tag.tagName) {
console.error(`${index}个标签缺少tagName:`, tag);
}
});
// 检查数量限制
if (newValues.length > this.maxTags) {
this.$message.warning(`最多只能选择${this.maxTags}个标签`);
// 回滚到之前的状态
this.selectedTags = [...this.previousTags];
return;
}
// 更新前保存当前状态
this.previousTags = [...newValues];
this.$emit('change', this.displayTags);
this.clearInput();
this.$nextTick(() => {
this.$refs.tagSelect.visible = false;
});
},
clearInput() {
if (this.$refs.tagSelect) {
const input = this.$refs.tagSelect.$refs.input;
if (input) {
input.value = '';
}
}
},
//创建新标签
async createNewTag(tagName) {
// 标签不能超过八个字
if (tagName.length > 8) {
this.$message.error('标签不能超过8个字')
return;
}
// 检查标签是否在下拉框中已存在
const isExistInSearch = this.searchResults.some(tag => tag.tagName === tagName);
if (isExistInSearch) {
this.$message.warning('已存在此标签,请选择');
return;
}
// 首先检查是否与已选择的标签重复
const isDuplicate = this.selectedTags.some(tag => tag.tagName === tagName);
if (isDuplicate) {
this.$message.warning('该标签已存在,无需重复创建');
return;
}
// 标签格式验证:仅支持中文、英文、数字、下划线、中横线
const tagPattern = /^[\u4e00-\u9fa5a-zA-Z0-9_-]+$/;
if (!tagPattern.test(tagName)) {
this.$message.error('标签名称仅支持中文、英文、数字、下划线(_)和中横线(-),不支持空格、点和特殊字符');
return;
}
// 添加标签数量限制检查
if (this.selectedTags.length >= this.maxTags) {
this.$message.warning('最多只能添加5个标签')
return;
}
this.loading = true
try {
this.params.courseId = this.courseId;
this.params.tagName = tagName;
// 分类
if (this.sysTypeList.length > 0) {
this.params.sysType1 = this.sysTypeList[0]; //一级的id
}
if (this.sysTypeList.length > 1) {
this.params.sysType2 = this.sysTypeList[1]; //二级的id
}
if (this.sysTypeList.length > 2) {
this.params.sysType3 = this.sysTypeList[2]; //三级的id
}
const {result:newTag} = await apiCourseTag.createTag(this.params)
this.$message.success('标签创建成功',newTag);
this.selectedTags = [...this.selectedTags, newTag];
// 更新搜索结果的逻辑保持不变
this.searchResults = [newTag, ...this.searchResults];
this.tagMap.set(newTag.id, newTag)
this.$emit('change', this.displayTags)
this.$nextTick(() => {
// 强制重新设置selectedTags来触发更新
const tempTags = [...this.selectedTags];
this.selectedTags = [];
this.$nextTick(() => {
this.selectedTags = tempTags;
});
this.$refs.tagSelect.visible = false;
});
} finally {
this.loading = false
}
},
// 修改doSearch方法添加搜索结果为空时的提示
async doSearch(query) {
// 不再在空查询时清空搜索结果
// if (!query.trim()) {
// this.searchResults = []
// return
// }
console.log("---- doSearch ------ query = " + query )
this.loading = true
try {
// 获取 typeId取 sysTypeList 最后一个有效的值
const typeId = this.sysTypeList.length > 2 ? this.sysTypeList[2] :
this.sysTypeList.length > 1 ? this.sysTypeList[1] :
this.sysTypeList.length > 0 ? this.sysTypeList[0] : null;
console.log("---- doSearch searchTags ------ query = " + query + " , typeId = " + typeId )
const {result:tags} = await apiCourseTag.searchTags({tagName:query,typeId:typeId})
console.log("-- searchTags 查询结果 tags = " + tags )
tags.forEach(item => {
this.tagMap.set(item.id, item)
})
this.searchResults = tags
// 当搜索结果为空时,提示用户可以按回车键创建标签
if (tags.length === 0) {
// this.$message.info('无此标签,按回车键创建')
}
} finally {
this.loading = false
}
}
}
}
</script>
<style scoped>
.tag-container {
position: relative;
}
.tag-preview {
margin-top: 8px;
}
.el-tag {
margin-right: 6px;
margin-bottom: 6px;
}
/* 添加标签计数样式 */
.tag-count {
position: absolute;
right: 10px;
top: 47%;
transform: translateY(-40%);
font-size: 12px;
color: #999;
background: white;
padding: 0 5px;
pointer-events: none;
/* 添加高度限制 */
height: 25px;
line-height: 25px; /* 垂直居中文字 */
box-sizing: border-box; /* 确保padding包含在height内 */
}
::v-deep(.el-select__tags) {
display: flex;
flex-wrap: wrap;
align-items: center;
}
/*
::v-deep(.el-tag) {
flex: 0 0 calc(50% - 8px);
max-width: calc(50% - 8px);
box-sizing: border-box;
margin-right: 8px;
margin-bottom: 4px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}*/
::v-deep(.el-tag) {
flex: 1 1 auto; /* 自动调整宽度 */
min-width: 30%; /* 设置最小宽度 */
max-width: 48%; /* 设置最大宽度,留出边距 */
box-sizing: border-box;
margin-right: 8px;
margin-bottom: 4px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
justify-content: center;
text-align: center;
}
::v-deep(.el-select__input) {
flex: 1;
min-width: 60px;
}
</style>

View File

@@ -109,7 +109,7 @@ export default {
if(res.status==200){
this.info=res.result;
//检查是否过期
if(res.result.deadTime!=''){
if(res.result.deadTime!='' && res.result.deadTime != null){
var d = new Date(res.result.deadTime);
var now=new Date();
if(now.getTime() > d.getTime()){

View File

@@ -0,0 +1,142 @@
<template>
<div id="NameFilterSelect">
<el-select @clear="handleClose" style="width:100%" @change="handleChange" clearable multiple v-model="aids"
filterable placeholder="姓名" v-limit-input="50" remote reserve-keyword :remote-method="initNameList"
:multiple-limit="5" :loading="nameListLoading">
<el-option v-for="item in nameList" :key="item.userId" :label="item.name" :value="item.userId">
<span>{{ item.name }}</span>
<span v-if="item.code" class="option-code">{{ item.code }}</span>
</el-option>
</el-select>
</div>
</template>
<script>
import apiUserbasic from "@/api/boe/userbasic.js";
export default {
data() {
return {
aids: [],
nameListLoading: false,
nameList: [],
};
},
props: {},
methods: {
handleChange() {
console.log("handleChange", this.aids);
this.$emit("handleNameChange", this.aids);
},
handleClose() {
this.$set(this, 'nameList', [])
console.log("handleClose", this.aids);
this.$emit("handleClose");
},
handleReset() {
this.aids = [];
this.nameList = [];
},
async initNameList(keyword) {
console.log("initNameList", keyword);
if (!keyword) {
return;
}
this.nameListLoading = true;
try {
const res = await apiUserbasic.selectUser(keyword);
this.nameListLoading = false;
if (res && res.status === 200) {
const resultList = res.result || [];
this.nameList = resultList
.map((item) => this.formatCreatorItem(item))
.filter((item) => item.userId);
} else {
this.creatorOptions = [];
}
} catch (error) {
this.nameList = [];
this.nameListLoading = false;
} finally {
this.nameListLoading = false;
}
},
formatCreatorItem(item = {}) {
return {
userId: item.id,
name: item.realName,
code: item.userNo,
};
},
},
watch: {},
};
</script>
<style scoped lang="scss">
::v-deep .el-upload-dragger {
width: 100% !important;
height: 100% !important;
}
.image-upload {
width: 410px;
height: 168px;
}
.image-card .el-upload--picture-card,
.image-card .el-upload-list--picture-card .el-upload-list__item {
background-color: #fbfdff;
border: 1px dashed #c0ccda;
border-radius: 6px;
box-sizing: border-box;
vertical-align: top;
}
.el-upload--picture-card {
background-color: #fbfdff;
border: 1px dashed #c0ccda;
border-radius: 6px;
box-sizing: border-box;
vertical-align: top;
line-height: 100%;
}
.image-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
image-uploader .el-upload--picture-card {
width: 100%;
}
image-uploader .el-upload:hover {
border-color: #409eff;
}
.image-uploader-icon {
font-size: 28px;
color: #8c939d;
text-align: center;
margin-top: 50px;
display: block;
}
.icon-text {
font-size: 14px;
display: block;
height: 30px;
line-height: 35px;
}
.image {
position: relative;
.mask {
opacity: 0;
position: absolute;
top: 0;
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
transition: all 0.3s;
}
&:hover .mask {
opacity: 1;
}
}
</style>

View File

@@ -44,7 +44,7 @@
<!-- <svg-icon v-else style="margin-right: 0;" :style="{'font-size':(size+2)+'px'}" :icon-class="isFavorite?'scactive2':'xihuan'"></svg-icon> -->
<div v-else class="is_favorite" :class="isFavorite?'is_favorite_a':'is_favorite'"></div>
</el-tooltip>
<span v-if="!courseExclusive" class="interact-bar-value"> {{ data.favorites? data.favorites:0}}</span>
<span v-if="!courseExclusive" class="interact-bar-value"> {{ data.favorites? data.favorites:data.hasCollect?number(data.hasCollect):1}}</span>
</div>
<div v-if="shares" @click="addShare()" :style="`min-width: ${nodeWidth};`" class="interact-bar-btn" :class="{cursor:!readonly}">
<el-tooltip effect="light" content="分享" placement="top" :visible-arrow="false" popper-class="text-tooltip">
@@ -114,6 +114,8 @@ export default {
shares:0,
praises:0,
views:0,
courseId:'',
courseName:''
}
}
},
@@ -234,7 +236,7 @@ export default {
created(){
},
mounted() {
if(this.data && this.data.id && !this.readonly){
if(this.data && (this.data.id||this.data.courseId) && !this.readonly){
this.checkHas();
}
@@ -308,7 +310,7 @@ export default {
}
let msgPageParams=this.pageParams;
if(!msgPageParams){
msgPageParams=this.data.id;
msgPageParams=this.data.id ?this.data.id: this.data.courseId;
}
let message={
content,
@@ -331,9 +333,9 @@ export default {
})
},
checkHas(){
if(this.type>0 && !this.readonly && this.data.id){
if(this.type>0 && !this.readonly && (this.data.id||this.data.courseId)){
if(this.favorites){
apiFavorites.has(this.type,this.data.id).then(rs=>{
apiFavorites.has(this.type,(this.data.id || this.data.courseId)).then(rs=>{
if(rs.status==200 && rs.result){
this.isFavorite=true;
}else{
@@ -506,9 +508,11 @@ export default {
return;
}
//需要判断是否已点赞,已点赞的不再加
console.log(this.data,'---------------');
let postData={
objType:this.type,
objId:this.data.id,
objId:this.data.id ?this.data.id: this.data.courseId,
title:'',
}
if(this.loading) {
@@ -516,7 +520,7 @@ export default {
}
this.loading=true;
if(this.type==1){
postData.title=this.data.name;
postData.title=this.data.name?this.data.name:this.data.courseName;
}else if(this.type==60){
postData.title=this.data.content;
} else if(this.type==5){
@@ -525,7 +529,7 @@ export default {
postData.title=this.data.title;
}
if(this.isFavorite) {// 已经收藏,再次点击取消收藏
apiFavorites.remove(this.type,this.data.id).then(res=>{
apiFavorites.remove(this.type,this.data.id ?this.data.id: this.data.courseId).then(res=>{
this.loading=false;
if(res.status==200){
this.isFavorite=false;
@@ -554,7 +558,7 @@ export default {
this.$store.dispatch("unicomFavorites",true)
}
//if(this.type===2||this.type===4){
this.messageSave(this.data.id,this.data.title,this.userInfo.name,this.data.sysCreateBy,this.data.sysCreateAid,'收藏了我发布的');
this.messageSave(this.data.id ?this.data.id: this.data.courseId,this.data.title,this.userInfo.name,this.data.sysCreateBy,this.data.sysCreateAid,'收藏了我发布的');
//}
this.$message({message:'已加入收藏',type:'success'});
//this.$emit('addFavorite',res.result);//添加收藏,如果是true代表添加成功false代表已存在

View File

@@ -13,9 +13,9 @@
</router-link>
</div>
<div class="top-nav" :style="{color:textColor}" :class="current == 'course' ? activeNav : ''">
<router-link to="/course">课程
<a @click="handleChangeCourse">课程
<div :class="current == 'course' ? 'nav-bottbor' : ''"></div>
</router-link>
</a>
</div>
<div class="top-nav" :style="{color:textColor}" :class="current == 'case' ? activeNav : ''">
<router-link to="/case">案例
@@ -214,6 +214,12 @@ export default {
//this.loadPopupConfig();
},
methods: {
handleChangeCourse() {
const paths = ["/course","/qualityCourse"]
// 如果是 课程 和 精品课程, 那么就不再重定向
const needReload = paths.findIndex(e=> e === this.$route.path) === -1
if (needReload) this.$router.push({path: paths[0]})
},
setCurIdentity(iden){
this.$store.dispatch('SetCurIdentity',iden);

View File

@@ -0,0 +1,87 @@
<template>
<div>
<el-dialog width="40%" class="simple-message-box" :title="title" :visible.sync="visible" append-to-body>
<div class="message-box-content"><svg-icon style="margin-right: 5px;font-size:16px"
icon-class="jingti"></svg-icon>{{message}}</div>
<span slot="footer" class="dialog-footer">
<el-button class="cancel" @click="cancel">{{cancelButtonText}}</el-button>
<el-button class="confirm" type="primary" @click="confirm">{{confirmButtonText}}</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name: "SimpleMessageBox",
data() {
return {
visible: false,
title: "",
message: "",
confirmButtonText: "确 认",
cancelButtonText: "取 消",
handleConfirm: null,
handleCancel: null,
};
},
methods: {
open() {
this.visible = true;
},
cancel() {
this.visible = false;
this.handleCancel();
},
confirm() {
this.visible = false;
this.handleConfirm();
},
},
};
</script>
<style lang="scss" scoped>
.simple-message-box {
::v-deep .el-dialog {
border-radius: 12px;
}
::v-deep .el-dialog__title {
font-size: 16px;
color: #000000;
}
.message-box-content {
display: flex;
justify-content: center;
font-size: 16px;
align-items: center;
color: #000000;
}
.cancel {
width: 120px;
height: 40px;
background: rgba(#4284f7,0.1);
border-radius: 8px;
margin-right: 8px;
border: none;
span {
font-weight: bold;
font-size: 14px;
color: #4284f7;
line-height: 40px;
text-align: center;
}
}
.confirm {
width: 120px;
height: 40px;
background: #4284f7;
border-radius: 8px;
span {
font-weight: bold;
font-size: 14px;
color: #ffffff;
line-height: 40px;
}
}
}
</style>

View File

@@ -242,17 +242,20 @@
<svg-icon :icon-class="activeMenu == '/user/medal'?'myxunzhang-active':'myxunzhang'"></svg-icon>
<span slot="title">我的勋章</span>
</el-menu-item>
<el-submenu index="myGrowth" v-show="curIdentity == 1">
<template slot="title">
<!-- <i class="el-icon-s-grid"></i> -->
<img src="../../assets/images/myGrowth.jpg" style="width: 1em;height: 1em;margin-right: 8px;"></img>
<span>我的必修</span>
</template>
<el-menu-item index="/growth/growthPage">
<!-- <i class="el-icon-menu"></i> -->
<span slot="title" class="study textl">专业力必修</span>
</el-menu-item>
</el-submenu>
<template v-if="showGrowthNav">
<el-submenu index="myGrowth" v-show="curIdentity == 1">
<template slot="title">
<!-- <i class="el-icon-s-grid"></i> -->
<img src="../../assets/images/myGrowth.jpg" style="width: 1em;height: 1em;margin-right: 8px;"></img>
<span>我的必修</span>
</template>
<el-menu-item index="/growth/growthPage">
<!-- <i class="el-icon-menu"></i> -->
<span slot="title" class="study textl">专业力必修</span>
</el-menu-item>
</el-submenu>
</template>
<el-submenu index="mystudy" v-show="curIdentity == 1">
<template slot="title">
<!-- <i class="el-icon-s-grid"></i> -->
@@ -396,6 +399,7 @@ import { mapGetters } from 'vuex';
import apicourseStudy from "../../api/modules/courseStudy.js"
import {pageList} from "@/api/modules/lecturer"
import courseImage from "@/components/Course/courseImage.vue"
import { listData } from "@/api/growth/growthpath"
import testUser from '@/utils/testUsers.js'
export default {
name: 'UcMenu',
@@ -410,6 +414,11 @@ export default {
if(meta.title == '添加受众' || meta.title == '查看受众'){
meta.activeMenu = '/manage/ugroups'
}
if(route.path == '/course/coursemanage'){
console.log('进入课程管理');
meta.activeMenu = '/need/course'
}
if (meta.activeMenu) {
return meta.activeMenu;
}
@@ -424,7 +433,8 @@ export default {
isCollapse: false,
lastStudy:{},
overlayShow: false,
instructor:0
instructor:0,
showGrowthNav: false
};
},
created() {
@@ -434,6 +444,10 @@ export default {
//获取讲师认证中条数
this.instructorCertification()
console.log(this.userInfo,'userInfouserInfo')
//如果专业力必修没有学习任务则隐藏“我的必修按钮”
listData().then(res => {
this.showGrowthNav = !!res.data.length
})
},
mounted() {
//console.log(this.userInfo.loginName,'this.userInfo.loginName');

View File

@@ -317,7 +317,7 @@ export default {
}
setInterval(() => {
//console.log('this.currentProgress::',this.currentProgress,this.isDrag,this.videoDom.currentTime , this.videoDom.duration)
console.log('当前状态:',this.currentProgress,this.isDrag,this.videoDom.currentTime , this.videoDom.duration)
// 视频播放时本地记录视频实时播放时长,视频设置了禁止拖动时执行
if(!this.isDrag){
var time = localStorage.getItem('videoProgressData')
@@ -364,6 +364,11 @@ export default {
}
// 根据视频的readyState判断下一帧是否已加载并控制loading的显示
this.isShowLoading = this.videoDom.readyState < 3;
console.log("当前缓存:"+this.videoDom.readyState)
if (this.videoDom.readyState < 3){
console.log("详细信息",this.videoDom)
console.log("卡了",this.videoDom.readyState)
}
//if()
//console.log(this.videoDom.readyState,'this.videoDom.readyState');
}, 1000);
@@ -512,6 +517,7 @@ export default {
this.currentProgress = progressVideo;
this.barrageTimelineStart = newCurrentTime;
this.videoDom.currentTime = newCurrentTime;
this.updateProgressText();
},
/* 提高视频音量
*/

View File

@@ -37,7 +37,6 @@ export default {
},
isDrag:{
type: Boolean,
default: true,
},
blobId:{
type: String,

View File

@@ -1,4 +1,4 @@
<script setup>
<script>
import {getCertificationProcess} from "@/api/modules/lecturer";
export default {

View File

@@ -0,0 +1,289 @@
<template>
<el-dialog title="添加报名" class="common-course-dialog" :visible.sync="visibleSync" width="1000px" top="8vh" append-to-body @close="handleClose">
<el-tabs v-model="activeTab">
<el-tab-pane label="从受众中选择" name="quick">
</el-tab-pane>
</el-tabs>
<div class="tab-search">
<el-select
class="member-select"
ref="memberSelect"
v-model="memberSelected"
multiple
filterable
remote
clearable
reserve-keyword
placeholder="姓名"
:multiple-limit="5"
:remote-method="remoteSearchMember"
:loading="memberLoading"
@input.native="limitMemberInput"
@visible-change="handleMemberVisibleChange"
@change="handleMemberChange"
@clear="handleMemberClear"
size="small"
>
<el-option
v-for="item in memberOptions"
:key="item.userId"
:label="item.name"
:value="item.userId"
>
<span>{{ item.name }}</span>
<span v-if="item.code" class="option-code">{{ item.code }}</span>
</el-option>
</el-select>
<el-button type="primary" size="small" @click="onSearch" style="margin-left: 8px;">查询</el-button>
<el-button size="small" @click="onReset" style="margin-left: 4px;">重置</el-button>
</div>
<el-table
class="use-table"
border
v-loading="loading"
:data="tableData"
@selection-change="onSelectionChange"
:row-key="row => row.id"
max-height="420"
>
<el-table-column type="selection" width="50" />
<el-table-column prop="userName" label="姓名" min-width="220" show-overflow-tooltip />
<el-table-column prop="workNum" label="工号" width="120" />
<el-table-column prop="departName" label="部门" width="120" />
<el-table-column prop="orgPath" label="组织路径" min-width="200" show-overflow-tooltip />
</el-table>
<div class="pagination">
<el-pagination
background
layout="total, prev, pager, next, jumper"
:pager-count="5"
:page-size="pageSize"
:current-page="pageNo"
:total="total"
@current-change="onPageChange"
/>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="handleClose">取 消</el-button>
<el-button type="primary" @click="handleConfirm">确 定</el-button>
</span>
</el-dialog>
</template>
<script>
import { fetchAudienceList, saveStu } from "@/api/signup/commonStudent";
import apiUserbasic from "@/api/boe/userbasic.js";
export default {
name: "AudienceModal",
props: {
visible: { type: Boolean, default: false },
pageSize: { type: Number, default: 10 },
// 从课程详情中传入的受众ID列表
audienceIds: {
type: Array,
default: () => [],
},
},
data() {
return {
activeTab: 'quick',
courseDetail: JSON.parse(sessionStorage.getItem("courseDetail") || "{}"),
visibleSync: this.visible,
loading: false,
keyword: "",
tableData: [],
total: 0,
pageNo: 1,
selectedRows: [],
// 成员远程搜索多选
memberSelected: [],
memberOptions: [],
memberLoading: false,
};
},
watch: {
visible(val) {
this.visibleSync = val;
if (val) {
this.resetAndFetch();
}
},
visibleSync(val) {
this.$emit("update:visible", val);
},
},
methods: {
resetAndFetch() {
this.pageNo = 1;
this.selectedRows = [];
this.keyword = "";
this.memberSelected = [];
this.memberOptions = [];
this.fetchList();
},
fetchList() {
this.loading = true;
fetchAudienceList({
// memberList 为多选成员 ID 列表
memberList: this.memberSelected || [],
pageNo: this.pageNo,
pageSize: this.pageSize,
audienceIdList: this.audienceIds || [],
})
.then((res) => {
const data = res.data || res.result || res || {};
this.tableData = data.list || [];
this.total = data.total || 0;
})
.finally(() => {
this.loading = false;
});
},
onSearch() {
this.pageNo = 1;
this.fetchList();
},
onReset() {
this.keyword = "";
this.memberSelected = [];
this.memberOptions = [];
this.onSearch();
},
onPageChange(page) {
this.pageNo = page;
this.fetchList();
},
onSelectionChange(list) {
this.selectedRows = list;
},
// ===== 成员远程搜索,多选逻辑(参考 ManageListRemote.vue 的创建人筛选) =====
async remoteSearchMember(keyword) {
const limited = (keyword || "").slice(0, 50);
if (this.$refs.memberSelect && this.$refs.memberSelect.query !== limited) {
this.$refs.memberSelect.query = limited;
this.$nextTick(() => {
if (
this.$refs.memberSelect &&
this.$refs.memberSelect.$refs &&
this.$refs.memberSelect.$refs.input
) {
this.$refs.memberSelect.$refs.input.value = limited;
}
});
}
const query = limited.trim();
if (!query || query.length <= 1) {
this.memberOptions = [];
return;
}
this.memberLoading = true;
try {
const res = await apiUserbasic.selectUser(query);
if (res && res.status === 200) {
const resultList = res.result || [];
this.memberOptions = resultList
.map((item) => this.formatMemberItem(item))
.filter((item) => item.userId);
} else {
this.memberOptions = [];
}
} catch (error) {
this.memberOptions = [];
} finally {
this.memberLoading = false;
}
},
formatMemberItem(item = {}) {
return {
userId: item.id,
name: item.realName,
code: item.userNo,
};
},
handleMemberChange(value = []) {
// 限制最多 5 个,保持与 ManageListRemote 中创建人筛选一致
this.memberSelected = (value || []).slice(0, 5);
},
handleMemberClear() {
this.memberSelected = [];
this.memberOptions = [];
},
handleMemberVisibleChange(visible) {
if (!visible) return;
const select = this.$refs.memberSelect;
const query = (select && select.query) || "";
if (!query) {
this.memberOptions = [];
}
},
limitMemberInput(event) {
const limited =
(event && event.target && event.target.value
? event.target.value
: ""
).slice(0, 50);
if (event && event.target && event.target.value !== limited) {
event.target.value = limited;
}
if (this.$refs.memberSelect) {
this.$refs.memberSelect.query = limited;
}
},
handleClose() {
this.visibleSync = false;
},
handleConfirm() {
const targetId = this.courseDetail?.id;
if(!this.selectedRows.length) {
this.$showMessage('请添加学员', 'error');
return
}
saveStu({
targetId,
type: 13,
deptIds: [],
groupIds: [],
studentList: this.selectedRows.map((e) => ({ id: e.userId })),
}).then(() => {
this.$showMessage("添加成功", 'success');
this.$emit("confirm", this.selectedRows);
this.handleClose();
});
},
},
};
</script>
<style lang="scss" scoped>
.tab-search {
display: flex;
align-items: center;
margin-bottom: 12px;
.label {
margin-right: 8px;
color: #666;
}
.input {
width: 240px;
margin-right: 12px;
}
}
::v-deep .el-dialog__body {
padding: 0 20px 30px 20px;
}
::v-deep .el-tabs__nav {
.el-tabs__item {
color: #3b7cff;
}
.el-tabs__active-bar {
width: 60px !important;
height: 1px;
left: 12px;
}
}
</style>

View File

@@ -0,0 +1,884 @@
<template>
<div v-if="visible">
<el-dialog class="signup-dialog common-course-dialog" :visible="visible" :title="dialogTitle" width="1200px" top="8vh" append-to-body destroy-on-close
@close="handleClose">
<div class="signup-wrap">
<el-tabs v-model="activeTab">
<!-- <el-tab-pane v-if="infoType" label="项目内学员" name="project">
<div class="tab-search">
<span class="label">姓名</span>
<el-input v-model="projectParams.studentName" placeholder="请输入姓名" size="small" clearable class="input" />
<el-button type="primary" size="small" @click="getProjectStu">
搜索
</el-button>
<el-button size="small" @click="resetProjectStu">重置</el-button>
</div>
<el-table height="360" border :data="projectStu.list" style="width: 100%"
@selection-change="onProjectSelectionChange">
<el-table-column type="selection" width="50" />
<el-table-column prop="studentName" label="姓名" width="120" />
<el-table-column prop="studentUserNo" label="工号" width="140" />
<el-table-column prop="studentOrgName" label="归属组织" show-overflow-tooltip />
<el-table-column prop="studentDepartName" label="部门" />
</el-table>
<div class="pager">
<el-pagination background layout="total, prev, pager, next, jumper" :page-size="projectStu.pageSize"
:current-page="projectStu.pageNo" :total="projectStu.total" @current-change="onProjectPageChange" />
</div>
</el-tab-pane> -->
<el-tab-pane label="快速选人" name="quick">
<div class="tab2">
<div class="tab-search">
<span class="label">姓名</span>
<el-input v-model="nameSearch.keyword" placeholder="请输入姓名" size="small" clearable class="input" />
<el-button type="primary" size="small" @click="onSearchStu">
搜索
</el-button>
<el-button size="small" @click="resetStu">重置</el-button>
</div>
<div class="split">
<div class="left-tree">
<el-tree :data="treeData" :props="treeProps" node-key="id" highlight-current lazy :load="loadOrgNode"
@node-click="onOrgSelect" />
</div>
<div class="table-area">
<el-table
ref="stuTable"
class="use-table"
border
:data="stuTable.list"
@selection-change="onStuSelectionChange"
:row-key="row => row.id || row.userId"
:reserve-selection="true"
>
<el-table-column type="selection" width="50" />
<el-table-column prop="realName" label="姓名" width="120" />
<el-table-column prop="userNo" label="工号" width="120" />
<el-table-column prop="orgName" label="归属组织" min-width="160" show-overflow-tooltip />
<el-table-column prop="departName" label="部门" min-width="140" />
</el-table>
<div class="pager pagination">
<el-pagination background :pager-count="5" layout="total, prev, pager, next, jumper" :page-size="stuTable.pageSize"
:current-page="stuTable.pageNo" :total="stuTable.total" @current-change="onStuPageChange" />
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane v-if="!selectStu" label="添加组织" name="org">
<div class="tab-search">
<span class="label">组织:</span>
<el-input v-model="searchOrgName.keyword" placeholder="请输入组织" size="small" clearable class="input"
@change="onOrgKeywordChange" />
<el-button type="primary" size="small" @click="searchOrg">
搜索
</el-button>
<el-button size="small" @click="resetOrg">重置</el-button>
</div>
<el-tree
ref="orgTree"
class="org-tree"
show-checkbox
node-key="id"
:data="orgList"
:props="orgTreeProps"
lazy
:load="loadOrgNodeFull" @check-change="onOrgCheckChange" :default-checked-keys="selectedOrgKeys" />
</el-tab-pane>
<el-tab-pane v-if="!selectStu" label="受众关联" name="audience">
<div class="tab-search">
<span class="label">受众名称:</span>
<el-input v-model="audienceName.keyword" placeholder="请输入受众名称" size="small" clearable class="input" />
<el-button type="primary" size="small" @click="searchAudience">
搜索
</el-button>
<el-button size="small" @click="resetAudienceInfo">重置</el-button>
</div>
<el-table
ref="audienceTable"
class="use-table"
border
:data="audienceTable.list"
@selection-change="onAudienceSelectionChange"
:row-key="row => row.id"
:reserve-selection="true"
>
<el-table-column type="selection" width="50" />
<el-table-column prop="audienceName" label="受众名称" min-width="220" />
<el-table-column prop="totalMember" label="总人数" width="100" />
<el-table-column prop="workMember" label="在职人数" width="120" />
</el-table>
<div class="pager pagination">
<el-pagination background :pager-count="5" layout="total, prev, pager, next, jumper" :page-size="audienceTable.pageSize"
:current-page="audienceTable.pageNo" :total="audienceTable.total"
@current-change="onAudiencePageChange" />
</div>
</el-tab-pane>
</el-tabs>
<div class="right1">
<div class="onerow">
<div class="onleft">
<div class="already">已选</div>
</div>
</div>
<div class="selected-area" :style="{ 'max-height': screenHeight - 235 + 'px' }" style="overflow-y: auto">
<div class="selecteds" v-if="infoType">
<div class="person">项目内学员</div>
<div v-for="(item, i) in projectSelectRows" :key="item.id || item.studentId">
<div v-if="i < 11">
<div class="chose">
{{ item.studentName }}
<div class="ch" @click="removeProject(item)"></div>
</div>
</div>
<div v-else>
<div v-if="member">
<div class="chose">
{{ item.studentName }}
<div class="ch" @click="removeProject(item)"></div>
</div>
</div>
</div>
</div>
<div v-if="!member && projectSelectRows.length > 10" class="ifsw">
<div @click="member = !member" class="sw">查看更多></div>
</div>
<div v-if="member && projectSelectRows.length > 10" class="ifsw">
<div @click="member = !member" class="sw">收起&lt;</div>
</div>
</div>
<div class="selecteds">
<div class="person">快速选人</div>
<div v-for="(item, i) in stuSelectRows" :key="item.id || item.userId">
<div v-if="i < 11">
<div class="chose">
{{ item.realName }}
<div class="ch" @click="removeStu(item)"></div>
</div>
</div>
<div v-else>
<div v-if="person">
<div class="chose">
{{ item.realName }}
<div class="ch" @click="removeStu(item)"></div>
</div>
</div>
</div>
</div>
<div v-if="!person && stuSelectRows.length > 10" class="ifsw">
<div @click="person = !person" class="sw">查看更多></div>
</div>
<div v-if="person && stuSelectRows.length > 10" class="ifsw">
<div @click="person = !person" class="sw">收起&lt;</div>
</div>
</div>
<div v-if="!selectStu" class="selecteds">
<div class="dept">添加组织</div>
<div v-for="(item, i) in deptList" :key="item.id">
<div v-if="i < 11">
<div class="chose1">
<div class="span">{{ item.name }}</div>
<div class="ch1" @click="removeOrg(item)" style="cursor: pointer;"></div>
</div>
</div>
<div v-else>
<div v-if="dept">
<div class="chose1">
<div class="span">{{ item.name }}</div>
<div class="ch1" @click="removeOrg(item)"></div>
</div>
</div>
</div>
</div>
<div v-if="!dept && deptList.length > 10" class="ifsw">
<div @click="dept = !dept" class="sw">查看更多></div>
</div>
<div v-if="dept && deptList.length > 10" class="ifsw">
<div @click="dept = !dept" class="sw">收起&lt;</div>
</div>
</div>
<div v-if="!selectStu" class="selecteds">
<div class="group">受众关联</div>
<div v-for="(item, i) in auditSelectRows" :key="item.id">
<div v-if="i < 11">
<div class="chose2">
<div class="span">{{ item.audienceName }}</div>
<div class="ch2" @click="removeAudience(item)"></div>
</div>
</div>
<div v-else>
<div v-if="group">
<div class="chose2">
<div class="span">{{ item.audienceName }}</div>
<div class="ch2" @click="removeAudience(item)"></div>
</div>
</div>
</div>
</div>
<div v-if="!group && auditSelectRows.length > 10" class="ifsw">
<div @click="group = !group" class="sw">查看更多></div>
</div>
<div v-if="group && auditSelectRows.length > 10" class="ifsw">
<div @click="group = !group" class="sw">收起&lt;</div>
</div>
</div>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="handleClose">取 消</el-button>
<el-button type="primary" @click="submitAuth">确 定</el-button>
</span>
<el-dialog :visible.sync="stageVisible" title="选择阶段" width="420px" append-to-body center>
<div class="stage-body">
<el-select v-model="stageId" placeholder="选择阶段" filterable style="width:100%">
<el-option v-for="item in stageIds" :key="item.id" :label="item.name || '默认'" :value="item.id" />
</el-select>
<div class="tip">已在其他关卡的学员,不会被添加到该关卡</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="stageVisible = false">取 消</el-button>
<el-button type="primary" @click="handleDialogOk">确 定</el-button>
</span>
</el-dialog>
</el-dialog>
</div>
</template>
<script>
import {
fetchOrgChildren,
fetchOrgList,
fetchProjectStudents,
fetchQuickStudents,
fetchUserAudiences,
saveStu,
} from "@/api/signup/commonStudent";
export default {
name: "SignupModal",
props: {
visible: { type: Boolean, default: false },
mode: { type: String, default: "plain" },
type: Number,
infoType: Number,
infoId: Number,
id: String,
title: { type: String, default: "" },
clear: { type: Boolean, default: false },
selectStu: { type: Boolean, default: false },
selectOne: { type: Boolean, default: false },
stage: { type: Array, default: () => [] },
isGroup: { type: Boolean, default: false },
projectId: { type: Number, default: null },
groupId: { type: Number, default: null },
groupName: { type: String, default: null },
groupMemberCount: { type: Number, default: null },
groupMemberNumber: { type: Number, default: null },
activeKey1: { type: String, default: null },
},
data() {
return {
courseDetail: JSON.parse(sessionStorage.getItem("courseDetail") || "{}"),
activeTab: this.infoType ? "project" : "quick",
stageVisible: false,
stageId: undefined,
projectParams: {
pid: this.infoId,
type: this.infoType,
studentName: "",
},
projectStu: { list: [], pageNo: 1, pageSize: 10, total: 0 },
stuTable: { list: [], pageNo: 1, pageSize: 10, total: 0 },
audienceTable: { list: [], pageNo: 1, pageSize: 10, total: 0 },
treeData: [],
orgList: [],
treeProps: { children: "treeChildList", label: "name" },
orgTreeProps: { children: "directChildList", label: "name" },
nameSearch: { keyword: "", departId: "" },
audienceName: { keyword: "" },
searchOrgName: { keyword: "", pageNo: 1, pageSize: 200 },
projectSelectRows: [],
stuSelectRows: [],
auditSelectRows: [],
deptList: [],
selectedOrgKeys: [],
// 右侧“已选”区域展开/收起控制,与 CommonStudent.vue 保持一致
member: false,
dept: false,
person: false,
group: false,
screenHeight: document.body.clientHeight,
};
},
computed: {
dialogTitle() {
return { 1: "添加学员", 2: "添加学员", 3: "添加学员" }[this.type] || this.title || "添加学员";
},
stageIds() {
return this.stage || [];
},
},
watch: {
visible(val) {
if (val) {
this.initData();
} else {
this.resetState();
}
},
},
mounted() {
if (this.visible) {
this.initData();
}
},
methods: {
// 参考 CommonStudent.vue在关闭弹窗时清空各种选中与搜索条件
resetState() {
this.projectParams.studentName = "";
this.nameSearch = { keyword: "", departId: "" };
this.audienceName = { keyword: "" };
this.searchOrgName = { keyword: "", pageNo: 1, pageSize: 200 };
this.projectSelectRows = [];
this.stuSelectRows = [];
this.auditSelectRows = [];
this.deptList = [];
this.selectedOrgKeys = [];
this.member = false;
this.dept = false;
this.person = false;
this.group = false;
// 清空表格勾选
if (this.$refs.stuTable && this.$refs.stuTable.clearSelection) {
this.$refs.stuTable.clearSelection();
}
if (this.$refs.audienceTable && this.$refs.audienceTable.clearSelection) {
this.$refs.audienceTable.clearSelection();
}
},
initData() {
this.courseDetail = JSON.parse(sessionStorage.getItem("courseDetail") || "{}");
this.projectParams = {
pid: this.infoId,
type: this.infoType,
studentName: "",
};
this.nameSearch = { keyword: "", departId: "" };
this.audienceName = { keyword: "" };
this.searchOrgName = { keyword: "", pageNo: 1, pageSize: 200 };
this.projectSelectRows = [];
this.stuSelectRows = [];
this.auditSelectRows = [];
this.deptList = [];
this.selectedOrgKeys = [];
this.activeTab = this.infoType ? "project" : "quick";
// this.getProjectStu();
this.fetchOrgTree();
this.onSearchStu();
this.searchAudience();
this.searchOrg();
},
handleClose() {
// 通过父组件的 :visible.sync 控制关闭
this.$emit("update:visible", false);
},
getProjectStu() {
fetchProjectStudents({
...this.projectParams,
pageNo: this.projectStu.pageNo,
pageSize: this.projectStu.pageSize,
}).then((res) => {
this.projectStu.list = res.data?.list || [];
this.projectStu.total = res.data?.total || 0;
});
},
onProjectPageChange(page) {
this.projectStu.pageNo = page;
this.getProjectStu();
},
onProjectSelectionChange(list) {
this.projectSelectRows = list;
},
resetProjectStu() {
this.projectParams.studentName = "";
this.getProjectStu();
},
onSearchStu() {
fetchQuickStudents({
...this.nameSearch,
pageNo: this.stuTable.pageNo,
pageSize: this.stuTable.pageSize,
}).then((res) => {
console.log("res", res);
this.stuTable.list = res.data?.list || [];
this.stuTable.total = res.data?.total || 0;
// 根据右侧已选,恢复当前页的勾选状态
this.$nextTick(() => {
this.syncStuTableSelection();
});
});
},
onStuPageChange(page) {
this.stuTable.pageNo = page;
this.onSearchStu();
},
onStuSelectionChange(list) {
// Element 表格在翻页时会把当前页的 selection 通过 list 传进来
// 为了保留其他页已选,这里做合并而不是直接覆盖
const currentPageIds = this.stuTable.list.map((r) => r.id || r.userId);
// 先保留非当前页的已选
const otherPageSelected = this.stuSelectRows.filter(
(r) => !currentPageIds.includes(r.id || r.userId)
);
const merged = [...otherPageSelected, ...list];
// 根据 id/userId 去重
const seen = new Set();
this.stuSelectRows = merged.filter((r) => {
const key = r.id || r.userId;
if (!key || seen.has(key)) return false;
seen.add(key);
return true;
});
},
resetStu() {
this.nameSearch = { keyword: "", departId: "" };
this.onSearchStu();
},
fetchOrgTree() {
fetchOrgList({ keyword: "" }).then((res) => {
this.treeData = res.data || res.result || res || [];
});
},
loadOrgNode(node, resolve) {
if (node.level === 0) {
return resolve(this.treeData);
}
fetchOrgChildren({ orgId: node.data.id, keyword: "" }).then((res) => {
resolve(res.data || res.result || res || []);
});
},
onOrgSelect(node) {
this.nameSearch.departId = node.id;
this.onSearchStu();
},
searchOrg() {
fetchOrgList(this.searchOrgName).then((res) => {
this.orgList = res.data || res.result || res || [];
});
},
resetOrg() {
// 重置组织搜索条件并刷新组织树
this.searchOrgName = { keyword: "", pageNo: 1, pageSize: 200 };
this.searchOrg();
},
onOrgKeywordChange() {
this.searchOrg();
},
loadOrgNodeFull(node, resolve) {
if (node.level === 0) {
return resolve(this.orgList);
}
fetchOrgChildren({ orgId: node.data.id, keyword: "" }).then((res) => {
resolve(res.data || res.result || res || []);
});
},
onOrgCheckChange(data, checked) {
if (checked) {
if (!this.deptList.find((d) => d.id === data.id)) {
this.deptList.push(data);
}
} else {
this.deptList = this.deptList.filter((d) => d.id !== data.id);
}
this.selectedOrgKeys = this.deptList.map((d) => d.id);
},
searchAudience() {
fetchUserAudiences({
...this.audienceName,
pageNo: this.audienceTable.pageNo,
pageSize: this.audienceTable.pageSize,
}).then((res) => {
console.log('searchAudience', res);
this.audienceTable.list = res.data?.list || [];
this.audienceTable.total = res.data?.total || 0;
// 根据右侧已选,恢复当前页的受众勾选状态
this.$nextTick(() => {
this.syncAudienceTableSelection();
});
});
},
onAudiencePageChange(page) {
this.audienceTable.pageNo = page;
this.searchAudience();
},
onAudienceSelectionChange(list) {
const currentPageIds = this.audienceTable.list.map((r) => r.id);
const otherPageSelected = this.auditSelectRows.filter(
(r) => !currentPageIds.includes(r.id)
);
const merged = [...otherPageSelected, ...list];
const seen = new Set();
this.auditSelectRows = merged.filter((r) => {
const key = r.id;
if (!key || seen.has(key)) return false;
seen.add(key);
return true;
});
},
// 根据 stuSelectRows 恢复当前页表格里的勾选
syncStuTableSelection() {
if (!this.$refs.stuTable) return;
const table = this.$refs.stuTable;
if (!table.clearSelection || !table.toggleRowSelection) return;
const selectedMap = new Set(
(this.stuSelectRows || []).map((r) => r.id || r.userId)
);
table.clearSelection();
this.stuTable.list.forEach((row) => {
const key = row.id || row.userId;
if (key && selectedMap.has(key)) {
table.toggleRowSelection(row, true);
}
});
},
// 根据 auditSelectRows 恢复当前页受众表格里的勾选
syncAudienceTableSelection() {
if (!this.$refs.audienceTable) return;
const table = this.$refs.audienceTable;
if (!table.clearSelection || !table.toggleRowSelection) return;
const selectedMap = new Set(
(this.auditSelectRows || []).map((r) => r.id)
);
table.clearSelection();
this.audienceTable.list.forEach((row) => {
const key = row.id;
if (key && selectedMap.has(key)) {
table.toggleRowSelection(row, true);
}
});
},
resetAudienceInfo() {
this.audienceName.keyword = "";
this.searchAudience();
},
onOrgSelectChange() { },
removeProject(item) {
this.projectSelectRows = this.projectSelectRows.filter(
(i) => (i.id || i.studentId) !== (item.id || item.studentId)
);
},
removeStu(item) {
this.stuSelectRows = this.stuSelectRows.filter(
(i) => (i.id || i.userId) !== (item.id || item.userId)
);
// 同步左侧快速选人表格的勾选状态
this.$nextTick(() => {
this.syncStuTableSelection();
});
},
removeOrg(item) {
this.deptList = this.deptList.filter((i) => i.id !== item.id);
this.selectedOrgKeys = this.deptList.map((d) => d.id);
// 同步左侧组织树的勾选状态
if (this.$refs.orgTree && this.$refs.orgTree.setCheckedKeys) {
this.$refs.orgTree.setCheckedKeys(this.selectedOrgKeys);
}
},
removeAudience(item) {
this.auditSelectRows = this.auditSelectRows.filter((i) => i.id !== item.id);
// 同步左侧受众表格的勾选状态
this.$nextTick(() => {
this.syncAudienceTableSelection();
});
},
submitAuth() {
if (this.type === 2) {
this.stageVisible = true;
} else {
this.handleDialogOk();
}
},
handleDialogOk() {
if (
this.type === 1 &&
this.groupId &&
this.groupMemberCount &&
this.groupMemberNumber &&
this.groupMemberCount < this.groupMemberNumber + this.projectSelectRows.length + this.stuSelectRows.length
) {
return this.$showMessage("添加小组学员超过最大值", 'error');
}
saveStu({
targetId: this.courseDetail?.id || this.id,
type: 13,
deptIds: this.deptList.map((e) => e.id),
groupIds: this.auditSelectRows.map((e) => e.id),
studentList: this.stuSelectRows.map((e) => ({id: e.id})),
}).then((res) => {
console.log('res', res);
this.$showMessage("添加成功", 'success');
this.$emit("confirm");
this.handleClose();
});
},
},
};
</script>
<style lang="scss" scoped>
.signup-dialog ::v-deep .el-dialog__body {
padding-top: 10px;
padding: 10px 20px 30px 20px;
}
::v-deep .el-tabs__nav {
.el-tabs__item {
color: #3b7cff;
}
.el-tabs__active-bar {
// width: 60px !important;
height: 1px;
background-color: #3b7cff;
}
}
.signup-wrap {
display: flex;
gap: 16px;
}
.el-tabs {
flex: 1;
}
.tab-search {
display: flex;
align-items: center;
margin-bottom: 12px;
.label {
margin-right: 8px;
color: #666;
}
.input {
width: 240px;
margin-right: 12px;
}
}
.split {
display: grid;
grid-template-columns: 250px minmax(0, 660px);
gap: 12px;
}
.left-tree {
height: 100%;
border: 1px solid #f0f0f0;
padding: 8px;
overflow: auto;
}
.table-area {
}
.pager {
margin-top: 10px;
text-align: right;
}
.right1 {
border-left: 1px solid #f2f6fe;
margin-left: 20px;
width: 200px;
.selected-area {
&::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: #4284F7;
}
&::-webkit-scrollbar {
width: 6px;
height: 6px;
background-color:rgba(0, 0, 0, .1);
border-radius: 4px;
}
&::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: #4284F7
}
}
.onerow {
display: flex;
justify-content: space-between;
align-items: center;
margin-right: 40px;
flex-wrap: wrap;
width: 100%;
.onleft {
display: flex;
text-align: center;
.already {
color: rgba(51, 51, 51, 1);
font-size: 16px;
font-weight: 500;
margin-left: 32px;
white-space: nowrap;
}
}
}
.selecteds {
display: flex;
flex-wrap: wrap;
margin-left: 32px;
.person {
width: 100%;
margin-top: 20px;
border-top: 1px solid #f2f6fe;
}
.chose {
width: 64px;
height: 24px;
margin-top: 25px;
margin-right: 18px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 2px;
border: 1px solid rgba(56, 139, 225, 1);
color: rgba(56, 139, 225, 1);
font-size: 12px;
position: relative;
.ch {
position: absolute;
width: 18px;
height: 18px;
background-image: url(../../assets/images/basicinfo/ch.png);
background-size: 100%;
right: -8px;
top: -8px;
}
}
.ifsw {
display: flex;
align-items: end;
justify-content: center;
color: #4ea6ff;
}
.sw {
display: flex;
align-items: center;
justify-content: center;
text-align: justify;
color: #4ea6ff;
margin-top: 23px;
margin-left: 10px;
cursor: pointer;
}
.dept {
width: 100%;
margin-top: 30px;
border-top: 1px solid #f2f6fe;
}
.chose1 {
height: 24px;
margin-top: 25px;
margin-right: 25px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 2px;
border: 1px solid rgba(56, 139, 225, 1);
color: rgba(56, 139, 225, 1);
font-size: 12px;
position: relative;
.span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ch1 {
position: absolute;
width: 18px;
height: 18px;
background-image: url(../../assets/images/basicinfo/ch.png);
background-size: 100%;
right: -8px;
top: -8px;
}
}
.group {
width: 100%;
margin-top: 30px;
border-top: 1px solid #f2f6fe;
}
.chose2 {
height: 24px;
margin-top: 25px;
margin-right: 25px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 2px;
border: 1px solid rgba(56, 139, 225, 1);
color: rgba(56, 139, 225, 1);
font-size: 12px;
position: relative;
.span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ch2 {
position: absolute;
width: 18px;
height: 18px;
background-image: url(../../assets/images/basicinfo/ch.png);
background-size: 100%;
right: -8px;
top: -8px;
}
}
}
}
.org-tree {
max-height: 520px;
overflow: auto;
padding: 8px 12px;
border: 1px solid #f0f0f0;
}
.stage-body {
.tip {
margin-top: 12px;
color: #999;
font-size: 12px;
}
}
</style>

View File

@@ -29,6 +29,9 @@ export const pages=[
{title:'课程首页',path:'index',component:'course/Index',hidden:true},
{title:'课程建设',path:'mylist',component:'course/TeacherList',hidden:true},
{title:'课程管理',path:'manage',component:'course/ManageList',hidden:false},
{title:'课程管理',path:'coursemanage',component:'course/CourseManage',hidden:true},
{title:'课程管理新版',path:'manage-remote',component:'course/ManageListRemote',hidden:false},
{title:'课程管理新版',path:'coursemanage-remote',component:'course/CourseManageRemote',hidden:true},
{title:'课程统计',path:'stat',component:'course/StatIndex',hidden:false},
{title:'课件管理',path:'courseware',component:'course/Courseware',hidden:false},
{title:'报名管理',path:'msignup',component:'study/ManageSignup',hidden:true},
@@ -117,6 +120,8 @@ export const iframes=[
{title:'嵌入测试', path:'/iframe/index',hidden:false,component:'portal/iframe'},
{title:'课件管理', path:'/iframe/course/coursewares',hidden:false,component:'course/Courseware'},
{title:'课程管理', path:'/iframe/course/manages',hidden:false,component:'course/ManageList'},
{title:'课程管理新版', path:'/iframe/course/manage-remote',hidden:false,component:'course/ManageListRemote'},
{title:'课程管理新版', path:'/iframe/course/coursemanage-remote',hidden:false,component:'course/CourseManageRemote'},
{title:'考试试题管理', path:'/iframe/exam/questions',hidden:false,component:'exam/Question'},
{title:'查看答卷', path:'/iframe/exam/viewanswer',hidden:false,component:'exam/viewAnswer'},
{title:'考试试卷管理', path:'/iframe/exam/papers',hidden:false,component:'exam/TestPaper'},
@@ -128,7 +133,8 @@ export const iframes=[
{title:'查看受众', path:'/iframe/ugroup/view',hidden:false,component:'manage/AudienceView'},
{title:'问答管理', path:'/iframe/qa/manages',hidden:false,component:'qa/ManageList'},
{title:'待审核课程', path:'/iframe/course/noapproved',hidden:false,component:'examine/NotApproved'},
{title:'已审核课程', path:'/iframe/course/reviewed',hidden:false,component:'examine/Reviewed'}
{title:'已审核课程', path:'/iframe/course/reviewed',hidden:false,component:'examine/Reviewed'},
{title:'标签管理', path:'/iframe/tag/manages',hidden:false,component:'tag/TagManageList'},
]

11
src/icons/svg/check.svg Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="10px" height="10px" viewBox="0 0 10 10" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>check 2</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon" transform="translate(-178, -894)" fill="#000000" fill-rule="nonzero">
<g id="check" transform="translate(178, 894)">
<path d="M1.04597978,8.4501514 L8.95402022,8.4501514 C9.18512277,8.4501514 9.40057776,8.37277111 9.56186808,8.23258944 C9.72556572,8.09128631 9.81584015,7.90063923 9.81584015,7.69653471 L9.81584015,6.30368958 C9.81584015,5.89548054 9.42103996,5.55007289 8.95402022,5.55007289 L6.73206548,5.55007289 L6.50096293,4.29068072 C7.27250843,3.88247168 7.74915744,3.13334081 7.74915744,2.32253 C7.74915744,2.01300886 7.67693789,1.71021644 7.53490611,1.42424582 C7.39768897,1.14836829 7.2026962,0.89940563 6.95474242,0.68520803 C6.44198363,0.243355389 5.76793452,0 5.05416466,0 C4.32956187,0 3.6482908,0.241112482 3.13553202,0.677357856 C2.62156957,1.11584614 2.33750602,1.70012336 2.33750602,2.32253 C2.33750602,3.13334081 2.81415503,3.88135023 3.58570053,4.29068072 L3.35459798,5.55007289 L1.04597978,5.55007289 C0.814877227,5.55007289 0.599422244,5.62745318 0.438131921,5.76763485 C0.27443428,5.90893798 0.184159846,6.09958506 0.184159846,6.30368958 L0.184159846,7.69653471 C0.184159846,8.10474375 0.578960039,8.4501514 1.04597978,8.4501514 Z M1.14106885,6.43041382 L3.45450169,6.43041382 C3.87578238,6.43041382 4.24289841,6.13098576 4.29345209,5.74857015 L4.5907559,4.35908938 L4.59195956,4.35460357 C4.64010592,4.04396097 4.47400096,3.754626 4.15984593,3.59874397 C3.64347617,3.3430526 3.33533943,2.87316362 3.33533943,2.34159471 C3.33533943,1.52405518 4.10568127,0.860154761 5.052961,0.860154761 C6.00024073,0.860154761 6.77058257,1.516205 6.77058257,2.32253 C6.77058257,2.85409891 6.46244584,3.32398789 5.94607607,3.57967926 C5.63914299,3.73219693 5.46461242,4.04283952 5.51396245,4.35460357 L5.51396245,4.35684647 L5.81246991,5.74857015 C5.86302359,6.13098576 6.23134328,6.43041382 6.65262398,6.43041382 L8.86013481,6.43041382 L8.86013481,7.58999664 L1.14106885,7.58999664 L1.14106885,6.43041382 Z M9.51612903,9.09835146 L0.483870968,9.09835146 C0.217862301,9.09835146 0,9.30133453 0,9.54917573 C0,9.79701693 0.217862301,10 0.483870968,10 L9.51612903,10 C9.7821377,10 10,9.79701693 10,9.54917573 C10,9.30133453 9.78334136,9.09835146 9.51612903,9.09835146 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="10px" height="10px" viewBox="0 0 10 10" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>check</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon" transform="translate(-178, -920)" fill="#4284F7" fill-rule="nonzero">
<g id="check" transform="translate(178, 920)">
<path d="M1.04597978,8.4501514 L8.95402022,8.4501514 C9.18512277,8.4501514 9.40057776,8.37277111 9.56186808,8.23258944 C9.72556572,8.09128631 9.81584015,7.90063923 9.81584015,7.69653471 L9.81584015,6.30368958 C9.81584015,5.89548054 9.42103996,5.55007289 8.95402022,5.55007289 L6.73206548,5.55007289 L6.50096293,4.29068072 C7.27250843,3.88247168 7.74915744,3.13334081 7.74915744,2.32253 C7.74915744,2.01300886 7.67693789,1.71021644 7.53490611,1.42424582 C7.39768897,1.14836829 7.2026962,0.89940563 6.95474242,0.68520803 C6.44198363,0.243355389 5.76793452,0 5.05416466,0 C4.32956187,0 3.6482908,0.241112482 3.13553202,0.677357856 C2.62156957,1.11584614 2.33750602,1.70012336 2.33750602,2.32253 C2.33750602,3.13334081 2.81415503,3.88135023 3.58570053,4.29068072 L3.35459798,5.55007289 L1.04597978,5.55007289 C0.814877227,5.55007289 0.599422244,5.62745318 0.438131921,5.76763485 C0.27443428,5.90893798 0.184159846,6.09958506 0.184159846,6.30368958 L0.184159846,7.69653471 C0.184159846,8.10474375 0.578960039,8.4501514 1.04597978,8.4501514 Z M1.14106885,6.43041382 L3.45450169,6.43041382 C3.87578238,6.43041382 4.24289841,6.13098576 4.29345209,5.74857015 L4.5907559,4.35908938 L4.59195956,4.35460357 C4.64010592,4.04396097 4.47400096,3.754626 4.15984593,3.59874397 C3.64347617,3.3430526 3.33533943,2.87316362 3.33533943,2.34159471 C3.33533943,1.52405518 4.10568127,0.860154761 5.052961,0.860154761 C6.00024073,0.860154761 6.77058257,1.516205 6.77058257,2.32253 C6.77058257,2.85409891 6.46244584,3.32398789 5.94607607,3.57967926 C5.63914299,3.73219693 5.46461242,4.04283952 5.51396245,4.35460357 L5.51396245,4.35684647 L5.81246991,5.74857015 C5.86302359,6.13098576 6.23134328,6.43041382 6.65262398,6.43041382 L8.86013481,6.43041382 L8.86013481,7.58999664 L1.14106885,7.58999664 L1.14106885,6.43041382 Z M9.51612903,9.09835146 L0.483870968,9.09835146 C0.217862301,9.09835146 0,9.30133453 0,9.54917573 C0,9.79701693 0.217862301,10 0.483870968,10 L9.51612903,10 C9.7821377,10 10,9.79701693 10,9.54917573 C10,9.30133453 9.78334136,9.09835146 9.51612903,9.09835146 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

14
src/icons/svg/del.svg Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="11px" height="12px" viewBox="0 0 11 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>shanchu</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon" transform="translate(-436, -918)" fill="#FF1818" fill-rule="nonzero">
<g id="shanchu" transform="translate(436, 918)">
<path d="M10.4999537,3.19289906 L0.500046316,3.19289906 C0.223878361,3.19289906 0,2.97107081 0,2.6974318 C0,2.42379279 0.223878361,2.20196454 0.500046316,2.20196454 L10.4999537,2.20196454 C10.7761216,2.20196454 11,2.42379279 11,2.6974318 C11,2.97107081 10.7761216,3.19289906 10.4999537,3.19289906 Z" id="路径"></path>
<path d="M8.27763883,12 L2.72210644,12 C1.83281125,11.9990263 1.11214015,11.2849546 1.11115743,10.4038029 L1.11115743,2.6974318 C1.11115743,2.42379279 1.33503579,2.20196454 1.61120374,2.20196454 C1.8873717,2.20196454 2.11125006,2.42379279 2.11125006,2.6974318 L2.11125006,10.4038029 C2.11125006,10.738359 2.38496787,11.0095703 2.7226159,11.0095703 L8.2781483,11.0095703 C8.61579634,11.0095703 8.88951415,10.738359 8.88951415,10.4038029 L8.88951415,2.6974318 C8.88951415,2.42379279 9.11339251,2.20196454 9.38956046,2.20196454 C9.66572842,2.20196454 9.88960678,2.42379279 9.88960678,2.6974318 L9.88960678,10.4038029 C9.88862317,11.2853484 9.16733192,11.9995828 8.27763883,12 Z M7.72206011,3.19289906 C7.4459504,3.1927598 7.22215435,2.9710131 7.22201381,2.6974318 L7.22201381,1.59619712 C7.22201381,1.43553761 7.15760223,1.2814583 7.04294889,1.16785488 C6.92829555,1.05425145 6.77279226,0.990429712 6.61064795,0.990429715 L4.3890973,0.990429715 C4.05144927,0.990429715 3.77773146,1.26164102 3.77773146,1.59619712 L3.77773146,2.6974318 C3.77773146,2.97107081 3.5538531,3.19289906 3.27768515,3.19289906 C3.00151719,3.19289906 2.77763883,2.97107081 2.77763883,2.6974318 L2.77763883,1.59619712 C2.77862156,0.715045435 3.49929265,0.000973720991 4.38858784,0 L6.6109027,0 C7.50019788,0.000973727448 8.22086897,0.71504544 8.2218517,1.59619712 L8.2218517,2.6974318 C8.22171131,2.97091464 7.99807034,3.19262061 7.72206011,3.19289906 L7.72206011,3.19289906 Z" id="形状"></path>
<path d="M4.3890973,9.2475444 C4.11292935,9.2475444 3.88905099,9.02571608 3.88905099,8.75207707 L3.88905099,5.44938266 C3.88902352,5.27235111 3.9843258,5.10875556 4.13905195,5.02023193 C4.2937781,4.93170829 4.48441652,4.93170829 4.63914267,5.02023193 C4.79386882,5.10875556 4.8891711,5.27235111 4.88914369,5.44938266 L4.88914369,8.75207707 C4.88921124,8.88350369 4.83654966,9.00956666 4.74275812,9.10249932 C4.64896658,9.19543199 4.52173855,9.24761133 4.3890973,9.2475444 L4.3890973,9.2475444 Z" id="路径"></path>
<path d="M6.61115743,9.24754433 C6.33498947,9.24754433 6.11111111,9.02571608 6.11111111,8.75207707 L6.11111111,5.44938266 C6.11111111,5.17574365 6.33498947,4.9539154 6.61115743,4.9539154 C6.88732538,4.9539154 7.11120374,5.17574365 7.11120374,5.44938266 L7.11120374,8.75207707 C7.11120374,9.02571608 6.88732538,9.24754433 6.61115743,9.24754433 L6.61115743,9.24754433 Z" id="路径"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

11
src/icons/svg/detail.svg Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>chakan</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon" transform="translate(-326, -920)" fill="#4284F7" fill-rule="nonzero">
<g id="chakan" transform="translate(326, 920)">
<path d="M8.94642857,0 C9.61213393,0 10.1517857,0.539651786 10.1517857,1.20535714 L10.1517857,3.16071429 L11.0625,3.16071429 C11.5750848,3.16071429 11.9915893,3.57208929 11.9998661,4.08270536 L12,4.09821429 L12,10.7946429 C12,11.453692 11.4710759,11.989192 10.8145714,11.9998393 L10.7946429,12 L1.20535714,12 C0.546308036,12 0.0108080357,11.4710759 0.000160714286,10.8145714 L0,10.7946429 L0,4.09821429 C0,3.58562946 0.411375,3.169125 0.921991071,3.16084821 L0.9375,3.16071429 L1.84821429,3.16071429 L1.84821429,1.20535714 C1.84821429,0.546308036 2.37713839,0.0108080357 3.03364286,0.000160714286 L3.05357143,0 L8.94642857,0 Z M11.1964286,8.83928571 L0.803571429,8.83928571 L0.803571429,10.7946429 C0.803571429,11.0143259 0.979875,11.1928259 1.19871429,11.196375 L1.20535714,11.1964286 L10.7946429,11.1964286 C11.0143259,11.1964286 11.1928259,11.020125 11.1964286,10.8012857 L11.1964286,10.7946429 L11.1964286,8.83928571 Z M1.84821429,3.96428571 L0.9375,3.96428571 C0.864776786,3.96428571 0.805607143,4.02223661 0.803625,4.09446429 L0.803571429,4.09821429 L0.803571429,8.03571429 L1.84821429,8.03571429 L1.84821429,3.96428571 Z M11.0625,3.96428571 L10.1517857,3.96428571 L10.1517857,8.03571429 L11.1964286,8.03571429 L11.1964286,4.09821429 C11.1964286,4.02549107 11.1384777,3.96632143 11.06625,3.96433929 L11.0625,3.96428571 Z M8.95307143,0.803571429 L3.05357143,0.803571429 C2.83166518,0.803571429 2.65178571,0.983450893 2.65178571,1.20535714 L2.65178571,8.03571429 L9.34821429,8.03571429 L9.34821429,1.20535714 C9.34821429,0.985674107 9.17191071,0.807174107 8.95307143,0.803571429 Z M5.69866071,1.47321429 C7.1595,1.47321429 8.34375,2.65746429 8.34375,4.11830357 C8.34375,4.70375893 8.15354464,5.24479018 7.83155357,5.68297768 L8.65222768,6.50366518 C8.80913839,6.6605625 8.80913839,6.91495982 8.65222768,7.07187054 C8.49531696,7.22878125 8.24093304,7.22878125 8.08402232,7.07187054 L7.26333482,6.25119643 C6.82513393,6.5731875 6.28411607,6.76339286 5.69866071,6.76339286 C4.23782143,6.76339286 3.05357143,5.57914286 3.05357143,4.11830357 C3.05357143,2.65746429 4.23782143,1.47321429 5.69866071,1.47321429 Z M5.69866071,2.27678571 C4.68160714,2.27678571 3.85714286,3.10125 3.85714286,4.11830357 C3.85714286,5.13535714 4.68160714,5.95982143 5.69866071,5.95982143 C6.71571429,5.95982143 7.54017857,5.13535714 7.54017857,4.11830357 C7.54017857,3.10125 6.71571429,2.27678571 5.69866071,2.27678571 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

11
src/icons/svg/edit.svg Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>a-zidingyipoppy_icon_zidinyi2备份 11 2</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon" transform="translate(-64, -893)" fill="#000000" fill-rule="nonzero">
<g id="a-zidingyipoppy_icon_zidinyi2备份-11" transform="translate(64, 893)">
<path d="M9.824,2.11948459 L7.938,0.198782456 C7.67766676,-0.0662608185 7.25566656,-0.0662608185 6.99533333,0.198782456 L1.11533333,6.18697362 L0.123333328,9.21908947 C0.0430921896,9.46316182 0.105275196,9.73245695 0.28391775,9.91453032 C0.462560305,10.0966037 0.726940747,10.1601436 0.966666672,10.0786189 L3.944,9.06768735 L9.824,3.08017513 C10.0842546,2.8150518 10.0842546,2.38528686 9.824,2.12016352 L9.824,2.11948459 Z M8.88266667,2.60016932 L3.46133333,8.12193334 L1.32933333,8.84974978 L2.04666667,6.68123702 L7.46866667,1.16015192 L8.88266667,2.60016932 L8.88266667,2.60016932 Z M0,10.9816001 L12,10.9816001 L12,12 L0,12 L0,10.9816001 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>a-zidingyipoppy_icon_zidinyi2备份 11</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon" transform="translate(-64, -919)" fill="#4284F7" fill-rule="nonzero">
<g id="a-zidingyipoppy_icon_zidinyi2备份-11" transform="translate(64, 919)">
<path d="M9.824,2.11948459 L7.938,0.198782456 C7.67766676,-0.0662608185 7.25566656,-0.0662608185 6.99533333,0.198782456 L1.11533333,6.18697362 L0.123333328,9.21908947 C0.0430921896,9.46316182 0.105275196,9.73245695 0.28391775,9.91453032 C0.462560305,10.0966037 0.726940747,10.1601436 0.966666672,10.0786189 L3.944,9.06768735 L9.824,3.08017513 C10.0842546,2.8150518 10.0842546,2.38528686 9.824,2.12016352 L9.824,2.11948459 Z M8.88266667,2.60016932 L3.46133333,8.12193334 L1.32933333,8.84974978 L2.04666667,6.68123702 L7.46866667,1.16015192 L8.88266667,2.60016932 L8.88266667,2.60016932 Z M0,10.9816001 L12,10.9816001 L12,12 L0,12 L0,10.9816001 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

11
src/icons/svg/ercode.svg Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>erweima 2</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon" transform="translate(-258, -893)" fill="#000000" fill-rule="nonzero">
<g id="erweima" transform="translate(258, 893)">
<path d="M4,6.66666667 L1.33333333,6.66666667 C0.6,6.66666667 0,7.26666667 0,8 L0,10.6666667 C0,11.4 0.6,12 1.33333333,12 L4,12 C4.73333333,12 5.33333333,11.4 5.33333333,10.6666667 L5.33333333,8 C5.33333333,7.26666667 4.73333333,6.66666667 4,6.66666667 Z M4.44444444,10.6666667 C4.44444444,10.9111111 4.24444444,11.1111111 4,11.1111111 L1.33333333,11.1111111 C1.08888889,11.1111111 0.888888889,10.9111111 0.888888889,10.6666667 L0.888888889,8 C0.888888889,7.75555556 1.08888889,7.55555556 1.33333333,7.55555556 L4,7.55555556 C4.24444444,7.55555556 4.44444444,7.75555556 4.44444444,8 L4.44444444,10.6666667 Z M4,0 L1.33333333,0 C0.6,0 0,0.6 0,1.33333333 L0,4 C0,4.73333333 0.6,5.33333333 1.33333333,5.33333333 L4,5.33333333 C4.73333333,5.33333333 5.33333333,4.73333333 5.33333333,4 L5.33333333,1.33333333 C5.33333333,0.6 4.73333333,0 4,0 Z M4.44444444,4 C4.44444444,4.24444444 4.24444444,4.44444444 4,4.44444444 L1.33333333,4.44444444 C1.08888889,4.44444444 0.888888889,4.24444444 0.888888889,4 L0.888888889,1.33333333 C0.888888889,1.08888889 1.08888889,0.888888889 1.33333333,0.888888889 L4,0.888888889 C4.24444444,0.888888889 4.44444444,1.08888889 4.44444444,1.33333333 L4.44444444,4 Z M11.3333333,6.66666667 C11.0888889,6.66666667 10.8888889,6.86666667 10.8888889,7.11111111 L10.8888889,11.5555556 C10.8888889,11.8 11.0888889,12 11.3333333,12 C11.5777778,12 11.7777778,11.8 11.7777778,11.5555556 L11.7777778,7.11111111 C11.7777778,6.86666667 11.5777778,6.66666667 11.3333333,6.66666667 Z M10.6666667,0 L8,0 C7.26666667,0 6.66666667,0.6 6.66666667,1.33333333 L6.66666667,4 C6.66666667,4.73333333 7.26666667,5.33333333 8,5.33333333 L10.6666667,5.33333333 C11.4,5.33333333 12,4.73333333 12,4 L12,1.33333333 C12,0.6 11.4,0 10.6666667,0 Z M11.1111111,4 C11.1111111,4.24444444 10.9111111,4.44444444 10.6666667,4.44444444 L8,4.44444444 C7.75555556,4.44444444 7.55555556,4.24444444 7.55555556,4 L7.55555556,1.33333333 C7.55555556,1.08888889 7.75555556,0.888888889 8,0.888888889 L10.6666667,0.888888889 C10.9111111,0.888888889 11.1111111,1.08888889 11.1111111,1.33333333 L11.1111111,4 Z M7.33333333,7.33333333 C7.08888889,7.33333333 6.88888889,7.53333333 6.88888889,7.77777778 L6.88888889,11.5555556 C6.88888889,11.8 7.08888889,12 7.33333333,12 C7.57777778,12 7.77777778,11.8 7.77777778,11.5555556 L7.77777778,7.77777778 C7.77777778,7.53333333 7.57777778,7.33333333 7.33333333,7.33333333 Z M9.33333333,8.66666667 C9.08888889,8.66666667 8.88888889,8.86666667 8.88888889,9.11111111 L8.88888889,11.5555556 C8.88888889,11.8 9.08888889,12 9.33333333,12 C9.57777778,12 9.77777778,11.8 9.77777778,11.5555556 L9.77777778,9.11111111 C9.77777778,8.86666667 9.57777778,8.66666667 9.33333333,8.66666667 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>erweima</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon" transform="translate(-258, -919)" fill="#4284F7" fill-rule="nonzero">
<g id="erweima" transform="translate(258, 919)">
<path d="M4,6.66666667 L1.33333333,6.66666667 C0.6,6.66666667 0,7.26666667 0,8 L0,10.6666667 C0,11.4 0.6,12 1.33333333,12 L4,12 C4.73333333,12 5.33333333,11.4 5.33333333,10.6666667 L5.33333333,8 C5.33333333,7.26666667 4.73333333,6.66666667 4,6.66666667 Z M4.44444444,10.6666667 C4.44444444,10.9111111 4.24444444,11.1111111 4,11.1111111 L1.33333333,11.1111111 C1.08888889,11.1111111 0.888888889,10.9111111 0.888888889,10.6666667 L0.888888889,8 C0.888888889,7.75555556 1.08888889,7.55555556 1.33333333,7.55555556 L4,7.55555556 C4.24444444,7.55555556 4.44444444,7.75555556 4.44444444,8 L4.44444444,10.6666667 Z M4,0 L1.33333333,0 C0.6,0 0,0.6 0,1.33333333 L0,4 C0,4.73333333 0.6,5.33333333 1.33333333,5.33333333 L4,5.33333333 C4.73333333,5.33333333 5.33333333,4.73333333 5.33333333,4 L5.33333333,1.33333333 C5.33333333,0.6 4.73333333,0 4,0 Z M4.44444444,4 C4.44444444,4.24444444 4.24444444,4.44444444 4,4.44444444 L1.33333333,4.44444444 C1.08888889,4.44444444 0.888888889,4.24444444 0.888888889,4 L0.888888889,1.33333333 C0.888888889,1.08888889 1.08888889,0.888888889 1.33333333,0.888888889 L4,0.888888889 C4.24444444,0.888888889 4.44444444,1.08888889 4.44444444,1.33333333 L4.44444444,4 Z M11.3333333,6.66666667 C11.0888889,6.66666667 10.8888889,6.86666667 10.8888889,7.11111111 L10.8888889,11.5555556 C10.8888889,11.8 11.0888889,12 11.3333333,12 C11.5777778,12 11.7777778,11.8 11.7777778,11.5555556 L11.7777778,7.11111111 C11.7777778,6.86666667 11.5777778,6.66666667 11.3333333,6.66666667 Z M10.6666667,0 L8,0 C7.26666667,0 6.66666667,0.6 6.66666667,1.33333333 L6.66666667,4 C6.66666667,4.73333333 7.26666667,5.33333333 8,5.33333333 L10.6666667,5.33333333 C11.4,5.33333333 12,4.73333333 12,4 L12,1.33333333 C12,0.6 11.4,0 10.6666667,0 Z M11.1111111,4 C11.1111111,4.24444444 10.9111111,4.44444444 10.6666667,4.44444444 L8,4.44444444 C7.75555556,4.44444444 7.55555556,4.24444444 7.55555556,4 L7.55555556,1.33333333 C7.55555556,1.08888889 7.75555556,0.888888889 8,0.888888889 L10.6666667,0.888888889 C10.9111111,0.888888889 11.1111111,1.08888889 11.1111111,1.33333333 L11.1111111,4 Z M7.33333333,7.33333333 C7.08888889,7.33333333 6.88888889,7.53333333 6.88888889,7.77777778 L6.88888889,11.5555556 C6.88888889,11.8 7.08888889,12 7.33333333,12 C7.57777778,12 7.77777778,11.8 7.77777778,11.5555556 L7.77777778,7.77777778 C7.77777778,7.53333333 7.57777778,7.33333333 7.33333333,7.33333333 Z M9.33333333,8.66666667 C9.08888889,8.66666667 8.88888889,8.86666667 8.88888889,9.11111111 L8.88888889,11.5555556 C8.88888889,11.8 9.08888889,12 9.33333333,12 C9.57777778,12 9.77777778,11.8 9.77777778,11.5555556 L9.77777778,9.11111111 C9.77777778,8.86666667 9.57777778,8.66666667 9.33333333,8.66666667 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

11
src/icons/svg/jingti.svg Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>jingti-copy</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="删除_弹框" transform="translate(-806, -410)" fill="#FB2727" fill-rule="nonzero">
<g id="jingti-copy" transform="translate(806, 410)">
<path d="M8,1.125 C8.928125,1.125 9.828125,1.30625 10.675,1.6640625 C11.49375,2.0109375 12.228125,2.50625 12.8609375,3.1375 C13.4921875,3.76875 13.9890625,4.5046875 14.334375,5.3234375 C14.69375,6.171875 14.875,7.071875 14.875,8 C14.875,8.928125 14.69375,9.828125 14.3359375,10.675 C13.9890625,11.49375 13.49375,12.228125 12.8625,12.8609375 C12.23125,13.4921875 11.4953125,13.9890625 10.6765625,14.334375 C9.828125,14.69375 8.928125,14.875 8,14.875 C7.071875,14.875 6.171875,14.69375 5.325,14.3359375 C4.50625,13.9890625 3.771875,13.49375 3.1390625,12.8625 C2.5078125,12.23125 2.0109375,11.4953125 1.665625,10.6765625 C1.30625,9.828125 1.125,8.928125 1.125,8 C1.125,7.071875 1.30625,6.171875 1.6640625,5.325 C2.0109375,4.50625 2.50625,3.771875 3.1375,3.1390625 C3.76875,2.5078125 4.5046875,2.0109375 5.3234375,1.665625 C6.171875,1.30625 7.071875,1.125 8,1.125 Z M8,0 C3.58125,0 0,3.58125 0,8 C0,12.41875 3.58125,16 8,16 C12.41875,16 16,12.41875 16,8 C16,3.58125 12.41875,0 8,0 Z M8,10 C7.6546875,10 7.375,9.7203125 7.375,9.375 L7.375,3.609375 C7.375,3.2640625 7.6546875,2.984375 8,2.984375 C8.3453125,2.984375 8.625,3.2640625 8.625,3.609375 L8.625,9.375 C8.625,9.7203125 8.3453125,10 8,10 Z M7.296875,11.703125 C7.296875,12.0914531 7.61167187,12.40625 8,12.40625 C8.38832813,12.40625 8.703125,12.0914531 8.703125,11.703125 C8.703125,11.3147969 8.38832812,11 8,11 C7.61167188,11 7.296875,11.3147969 7.296875,11.703125 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

11
src/icons/svg/manage.svg Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>guanli 2</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon" transform="translate(-124, -894)" fill="#000000" fill-rule="nonzero">
<g id="guanli" transform="translate(124, 894)">
<path d="M4.49064449,5.50676379 L0.997920994,5.50676379 C0.449064449,5.50676379 0,5.05723205 0,4.50780437 L0,1.01144641 C0,0.462018737 0.449064449,0.0124869995 0.997920994,0.0124869995 L4.49064449,0.0124869995 C5.03950104,0.0124869995 5.48856549,0.462018737 5.48856549,1.01144641 L5.48856549,4.50780437 C5.48856549,5.05723205 5.03950104,5.50676379 4.49064449,5.50676379 Z M4.5347973,4.50780437 L4.5347973,5.00728409 L4.5347973,4.50780437 Z M0.997920994,1.01144641 L0.997920994,4.50780437 L4.49064449,4.50780437 L4.49064449,1.01144641 L0.997920994,1.01144641 Z M9.00623701,6.0062435 C8.75675676,6.0062435 8.53222453,5.90634756 8.35758836,5.73152966 L6.28690229,3.65868887 C6.11226612,3.48387098 6.01247401,3.25910511 6.01247401,3.00936525 C6.01247401,2.75962539 6.11226611,2.53485953 6.28690229,2.36004162 L8.35758836,0.26222685 C8.70686072,-0.0874089499 9.30561332,-0.0874089499 9.65488566,0.26222685 L11.7255717,2.36004162 C11.9002079,2.53485952 12,2.75962539 12,3.00936525 C12,3.25910511 11.9002079,3.48387097 11.7255717,3.65868887 L9.65488566,5.73152966 C9.48024949,5.90634755 9.25571726,6.0062435 9.00623701,6.0062435 L9.00623701,6.0062435 Z M7.06029106,3.00936525 L9.03118504,4.98231009 L10.977131,3.00936525 L9.00623701,1.03642041 L7.06029106,3.00936525 Z M4.49064449,12 L0.997920994,12 C0.449064449,12 0,11.5504683 0,11.0010406 L0,7.50468262 C0,6.95525495 0.449064449,6.50572321 0.997920994,6.50572321 L4.49064449,6.50572321 C5.03950104,6.50572321 5.48856549,6.95525495 5.48856549,7.50468262 L5.48856549,11.0010406 C5.48856549,11.5504683 5.03950104,12 4.49064449,12 Z M4.5347973,11.0010406 L4.5347973,11.5005203 L4.5347973,11.0010406 Z M0.997920994,7.50468262 L0.997920994,11.0010406 L4.49064449,11.0010406 L4.49064449,7.50468262 L0.997920994,7.50468262 Z M11.002079,12 L7.50935551,12 C6.96049896,12 6.51143451,11.5504683 6.51143451,11.0010406 L6.51143451,7.50468262 C6.51143451,6.95525495 6.96049896,6.50572321 7.50935551,6.50572321 L11.002079,6.50572321 C11.5509356,6.50572321 12,6.95525495 12,7.50468262 L12,11.0010406 C12,11.5504683 11.5509356,12 11.002079,12 Z M11.0462318,11.0010406 L11.0462318,11.5005203 L11.0462318,11.0010406 Z M7.50935551,7.50468262 L7.50935551,11.0010406 L11.002079,11.0010406 L11.002079,7.50468262 L7.50935551,7.50468262 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>guanli</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon" transform="translate(-124, -920)" fill="#4284F7" fill-rule="nonzero">
<g id="guanli" transform="translate(124, 920)">
<path d="M4.49064449,5.50676379 L0.997920994,5.50676379 C0.449064449,5.50676379 0,5.05723205 0,4.50780437 L0,1.01144641 C0,0.462018737 0.449064449,0.0124869995 0.997920994,0.0124869995 L4.49064449,0.0124869995 C5.03950104,0.0124869995 5.48856549,0.462018737 5.48856549,1.01144641 L5.48856549,4.50780437 C5.48856549,5.05723205 5.03950104,5.50676379 4.49064449,5.50676379 Z M4.5347973,4.50780437 L4.5347973,5.00728409 L4.5347973,4.50780437 Z M0.997920994,1.01144641 L0.997920994,4.50780437 L4.49064449,4.50780437 L4.49064449,1.01144641 L0.997920994,1.01144641 Z M9.00623701,6.0062435 C8.75675676,6.0062435 8.53222453,5.90634756 8.35758836,5.73152966 L6.28690229,3.65868887 C6.11226612,3.48387098 6.01247401,3.25910511 6.01247401,3.00936525 C6.01247401,2.75962539 6.11226611,2.53485953 6.28690229,2.36004162 L8.35758836,0.26222685 C8.70686072,-0.0874089499 9.30561332,-0.0874089499 9.65488566,0.26222685 L11.7255717,2.36004162 C11.9002079,2.53485952 12,2.75962539 12,3.00936525 C12,3.25910511 11.9002079,3.48387097 11.7255717,3.65868887 L9.65488566,5.73152966 C9.48024949,5.90634755 9.25571726,6.0062435 9.00623701,6.0062435 L9.00623701,6.0062435 Z M7.06029106,3.00936525 L9.03118504,4.98231009 L10.977131,3.00936525 L9.00623701,1.03642041 L7.06029106,3.00936525 Z M4.49064449,12 L0.997920994,12 C0.449064449,12 0,11.5504683 0,11.0010406 L0,7.50468262 C0,6.95525495 0.449064449,6.50572321 0.997920994,6.50572321 L4.49064449,6.50572321 C5.03950104,6.50572321 5.48856549,6.95525495 5.48856549,7.50468262 L5.48856549,11.0010406 C5.48856549,11.5504683 5.03950104,12 4.49064449,12 Z M4.5347973,11.0010406 L4.5347973,11.5005203 L4.5347973,11.0010406 Z M0.997920994,7.50468262 L0.997920994,11.0010406 L4.49064449,11.0010406 L4.49064449,7.50468262 L0.997920994,7.50468262 Z M11.002079,12 L7.50935551,12 C6.96049896,12 6.51143451,11.5504683 6.51143451,11.0010406 L6.51143451,7.50468262 C6.51143451,6.95525495 6.96049896,6.50572321 7.50935551,6.50572321 L11.002079,6.50572321 C11.5509356,6.50572321 12,6.95525495 12,7.50468262 L12,11.0010406 C12,11.5504683 11.5509356,12 11.002079,12 Z M11.0462318,11.0010406 L11.0462318,11.5005203 L11.0462318,11.0010406 Z M7.50935551,7.50468262 L7.50935551,11.0010406 L11.002079,11.0010406 L11.002079,7.50468262 L7.50935551,7.50468262 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -3,6 +3,40 @@ import App from './App.vue'
import router from './router'
import store from './store'
import vueKatexEs from "vue-katex";
import "katex/dist/katex.min.css"
Vue.use(vueKatexEs,{
globalOptions:{
delimiters:[
{left:"$$",right:"$$",display:true},
{left:"$",right:"$",display:false},
{left:"\\[",right:"\\]",display:true},
{left:"\\(",right:"\\)",display:false}
],
throwOnError:true
}
})
Vue.directive('limit-input', {
bind: function (el, binding) {
const max = binding.value || 50;
// 找到input元素
const input = el.querySelector('input');
if (input) {
// 监听input事件在输入时限制长度
input.addEventListener('input', function () {
if (input.value.length > max) {
input.value = input.value.substring(0, max);
// 触发input事件让element-ui的内部处理更新
input.dispatchEvent(new Event('input', { bubbles: true }));
}
});
}
}
});
//import './mock/index'
import xpage from '@/utils/xpage'
@@ -25,6 +59,14 @@ import 'swiper/dist/css/swiper.css';
Vue.use(VueAwesomeSwiper)
import watermark from './utils/warterMark.js'
import Bus from './utils/bus.js'
import {showMessage} from './utils/index.js'
import MessageBoxService from './utils/simpleMessageBox.js'
Vue.use(MessageBoxService)
Vue.prototype.$showMessage = showMessage
Vue.prototype.$bus = Bus

View File

@@ -2,7 +2,6 @@ import Vue from 'vue'
import VueRouter from 'vue-router'
/* Layout */
import Layout from '@/layout/index'
import LayoutPortal from '@/layout/portal'
import Grateful from '@/views/grateful'
Vue.use(VueRouter)
@@ -341,6 +340,13 @@ export const constantRoutes = [{
name: 'hotforum',
meta: {title: '热点论坛', icon: 'dashboard', noCache: true, affix: true},
},
{
path: '/lexiang',
hidden: true,
component: (resolve) => require(['@/views/sso/lexiang'], resolve),
name: 'lexiang',
meta: {title: '单点登录', icon: 'dashboard', noCache: true, affix: true},
},
{
path: '/404',
component: (resolve) => require(['@/views/error/404'], resolve),
@@ -355,7 +361,15 @@ export const constantRoutes = [{
path: '/500',
component: (resolve) => require(['@/views/error/500'], resolve),
hidden: true
},
{
path: '/qualityCourse',
hidden: true,
component: (resolve) => require(['@/views/portal/course/qualityCourse'], resolve),
name: 'qualityCourse',
meta: {title: '精品课课程', keepAlive: true, icon: 'dashboard', noCache: true, affix: false},
}
]
const router = new VueRouter({

View File

@@ -7,7 +7,11 @@ const state = {
withoutAnimation: false
},
device: 'desktop',//默认是桌面以后会有android,ios,minapp
size: Cookies.get('size') || 'medium' //字段大小
size: Cookies.get('size') || 'medium', //字段大小
// 添加AI Call组件显示控制状态
showAICall: false,
// 控制AI Call最小化窗口在特定路由下显示的状态
showAICallMinimized: false
}
const mutations = {
@@ -34,6 +38,14 @@ const mutations = {
SET_SIZE: (state, size) => {
state.size = size
Cookies.set('size', size)
},
// 添加控制AI Call组件显示的mutation
SET_SHOW_AI_CALL: (state, show) => {
state.showAICall = show
},
// 控制AI Call最小化窗口显示的mutation
SET_SHOW_AI_CALL_MINIMIZED: (state, show) => {
state.showAICallMinimized = show
}
}
@@ -49,6 +61,14 @@ const actions = {
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
},
// 添加控制AI Call组件显示的action
setShowAICall({ commit }, show) {
commit('SET_SHOW_AI_CALL', show)
},
// 控制AI Call最小化窗口显示的action
setShowAICallMinimized({ commit }, show) {
commit('SET_SHOW_AI_CALL_MINIMIZED', show)
}
}
@@ -57,4 +77,4 @@ export default {
state,
mutations,
actions
}
}

View File

@@ -455,4 +455,13 @@ export function resOwnerListMap(source) {
})
let name = resOwnerList.get('GC005001')
return name;
}
export function showMessage(message, status) {
this.$message({
message: message,
type: status,
duration: 5000,
customClass: 'new-message'
});
}

View File

@@ -0,0 +1,50 @@
import Vue from 'vue'
import MessageBox from '@/components/SimpleMessageBox/index.vue'
// 创建 MessageBox 构造器
const MessageBoxConstructor = Vue.extend(MessageBox)
let messageBoxInstance = null
const MessageBoxService = {
open(options = {}) {
// 如果已有实例,先销毁
if (messageBoxInstance) {
messageBoxInstance.$destroy()
const el = messageBoxInstance.$el
if (el && el.parentNode) {
el.parentNode.removeChild(el)
}
}
// 创建新实例
messageBoxInstance = new MessageBoxConstructor({
el: document.createElement('div'),
data: options
})
// 挂载到 body
document.body.appendChild(messageBoxInstance.$el)
// 显示并返回 Promise
return messageBoxInstance.open(options)
},
cancel() {
messageBoxInstance.cancel()
},
confirm(options) {
return this.open({
...options
})
},
}
// 添加到 Vue 原型
MessageBoxService.install = function (Vue) {
Vue.prototype.$messageBox = MessageBoxService
}
// 导出
export default MessageBoxService

83
src/utils/sseHelper.js Normal file
View File

@@ -0,0 +1,83 @@
/**
* SSE流式数据处理工具
*/
/**
* 处理SSE响应数据
* @param {String} data - SSE响应数据
* @param {Function} onMessage - 处理消息的回调函数
* @param {Function} onComplete - 完成时的回调函数
* @param {Function} onError - 错误处理回调函数
*/
export function processSSEData(data, onMessage, onComplete, onError) {
try {
const lines = data.split('\n')
for (const line of lines) {
if (line.startsWith('data: ')) {
const jsonData = JSON.parse(line.substring(6))
onMessage(jsonData)
// 如果状态为4表示对话结束
if (jsonData.data && jsonData.data.status === 4) {
onComplete()
}
}
}
} catch (error) {
console.error('处理SSE数据时出错:', error)
if (onError) {
onError(error)
}
}
}
/**
* 创建SSE连接
* @param {String} url - 请求地址
* @param {Object} data - 请求数据
* @param {Function} onMessage - 消息处理回调
* @param {Function} onComplete - 完成回调
* @param {Function} onError - 错误回调
* @returns {Promise} - 返回fetch Promise
*/
export function createSSEConnection(url, data, onMessage, onComplete, onError) {
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const reader = response.body.getReader()
const decoder = new TextDecoder('utf-8')
let buffer = ''
function read() {
reader.read().then(({ done, value }) => {
if (done) {
if (onComplete) onComplete()
return
}
buffer += decoder.decode(value, { stream: true })
processSSEData(buffer, onMessage, onComplete, onError)
// 继续读取
read()
}).catch(error => {
console.error('SSE读取错误:', error)
if (onError) onError(error)
})
}
// 开始读取数据
read()
}).catch(error => {
console.error('SSE连接错误:', error)
if (onError) onError(error)
})
}

View File

@@ -266,6 +266,17 @@ export function testType(type) { //此方法移到tools中
}
return judgment;
}
export function newToScore(score) {
if (!score) {
return '0.0';
}
if((''+score).indexOf('.')>-1){
return score.toFixed(1);
}else{
return score+'.0';
}
}
export function toScore(score) {
if (!score) {
return '0';

View File

@@ -153,9 +153,85 @@
</div>
</div>
<div class="xindex-content">
<!-- 推荐课程 -->
<div class="modules xcontent2">
<!-- <div class="xcontent2-main"> -->
<!--内容块-->
<!-- </div> -->
<!-- 精品课模块 -->
<div class="xcontent2-main">
<div class="modules-title xindex-main" v-if="this.qusisityList.list.length > 0">
<!-- <span class="modules-text" style="color: #3D86F4;">精品课</span> -->
<span class="quyer-tag" style="margin-left: 0px;">
<!-- <img src="../assets/images/tutoring1.pn" alt=""> -->
<img class="modules-text" style="height: 28px;" src="../assets/images/course/courseTitle.png" alt="">
</span>
<span class="more">
<router-link to="/qualityCourse">查看更多>></router-link>
</span>
</div>
<div
v-for="(course, eIndex) in exquisiteList"
:key="'cc' + eIndex"
class="xindex-course courseBg"
style="position: relative;margin-top: 20px;"
>
<div style="position: absolute; right: 25px; bottom: 72px">
<interactBar
nodeWidth="20px"
:courseExclusive="true"
:type="1"
:data="course"
:comments="false"
:praises="false"
:shares="false"
:views="false"
>
</interactBar>
<!-- <svg-icon style="font-size: 32px;margin-top: -5px;" icon-class="collectedCourse"></svg-icon> -->
</div>
<a @click="toCourseDetail(course)">
<div class="xindex-course-image">
<course-image :course="course"></course-image>
<!-- <span v-if="course.type == 20 || 10" class="course-type"
>录播课</span
> -->
<img v-if="course.type == 20 || 10" src="../assets/images/course/courseTag.png" class="course-type" style="background: none;" alt="">
</div>
<div
style="width: 80%"
:title="course.courseName"
class="course-title portal-title-tow two-line-ellipsis"
>
{{ course.courseName }}
</div>
<div class="course-author">
<div class="course-author-left">
{{ course.authorInfo.name }}
<span class="study-num"
>{{ formatNum(course.studyNum) }}人学习</span
>
</div>
<div style="display: flex">
<div v-if="course.courseScore">
<span class="course-score-value" style="margin-left: 10px"
>{{ toScore(course.courseScore) }}</span
>
</div>
<div v-else class="course-score-no">未评分</div>
</div>
</div>
</a>
</div>
<!--内容块-->
<div class="modules-title xindex-main">
<span class="modules-text">推荐课程</span>
@@ -1137,6 +1213,9 @@ export default {
orderType: 2,
list: [],
},
qusisityList: {
list: [],
},
// 推荐课程
recommendedList:{
list: [],
@@ -1164,6 +1243,7 @@ export default {
},
mounted() {
this.getCourseData(1);
this.getEsqusiteList();
this.getRecommendList();
this.getPositive()
this.getCaseData();
@@ -1227,6 +1307,10 @@ export default {
courseComputedTwoList(){
return this.courseList.list.slice(3)
},
// 精品课展示
exquisiteList() {
return this.qusisityList.list.slice(0,3)
},
},
methods: {
getPositive() {
@@ -1421,21 +1505,27 @@ export default {
//二期调整,直接改成一个地址
//return this.webBaseUrl + '/course/detail?id=' + item.id;
let $this = this;
let cId = "";
if (item.id) {
cId = item.id;
} else {
cId = item.courseId;
}
if (item.type == 10) {
//return this.webBaseUrl + "/course/studyindex?id=" + item.id;
//console.log("直接进入学习页面");
this.$router.push("/course/studyindex?id=" + item.id);
this.$router.push("/course/studyindex?id=" + cId);
} else if (item.type == 20) {
apiCourseStudy.hasSignup(item.id).then((rs) => {
apiCourseStudy.hasSignup(cId).then((rs) => {
if (rs.status == 200) {
//return $this.webBaseUrl + "/course/studyindex?id=" + item.id;
this.$router.push("/course/studyindex?id=" + item.id);
//return $this.webBaseUrl + "/course/studyindex?id=" + cId;
this.$router.push("/course/studyindex?id=" + cId);
} else {
//return $this.webBaseUrl + "/course/detail?id=" + item.id;
this.$router.push("/course/detail?id=" + item.id);
//return $this.webBaseUrl + "/course/detail?id=" + cId;
this.$router.push("/course/detail?id=" + cId);
}
});
//return $this.webBaseUrl + "/course/detail?id=" + item.id;
//return $this.webBaseUrl + "/course/detail?id=" + cId;
}
},
orderTypeFilter(val) {
@@ -1472,6 +1562,29 @@ export default {
}
})
},
//精品课展示
getEsqusiteList(){
let course = {
aid: this.userInfo.aid,
}
apiIndex.qualitylist(course).then((res) => {
let courseIds = [];
res.data.result.forEach((item) => {
item.authorInfo = {
aid: "",
name: "",
orgInfo: "",
avatar: "",
code: "",
sex: null,
};
courseIds.push(item.courseId);
});
this.loadCouserTeacher(res.data.result, courseIds);
console.log(res.data.result,'--------------------------');
this.qusisityList.list = res.data.result;
})
},
getCourseData(pageIndex) {
this.isNext = false;
let { orderType, num } = this.courseList;
@@ -1671,7 +1784,7 @@ export default {
let userIds = [];
list.forEach((item, index) => {
cres.result.some((courseTeahcer) => {
if (courseTeahcer.courseId == item.id) {
if (courseTeahcer.courseId == (item.id||item.courseId)) {
if (courseTeahcer.teacherIds) {
userIds.push(courseTeahcer.teacherIds[0]);
item.authorInfo.aid = courseTeahcer.teacherIds[0];
@@ -2661,6 +2774,7 @@ export default {
// padding-bottom: 10px;
display: flex;
justify-content: space-between;
margin-bottom: 20px;
.course-author-left {
font-size: 14px;
@@ -3009,4 +3123,17 @@ export default {
}
}
}
.courseBg{
// width: 332px;
// height: 323px;
// background: url("../assets/images/course/courseBackground.png") no-repeat;
// background-size: 100% 100%; /* 或 use 'contain' */
// background-position: center;
// border: none;
border-radius: 12px;
background: linear-gradient(135deg, #e6f7ff, #f0f8ff, #ffffff);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
border: 1px solid #d9edf7;
//overflow: hidden;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
<template>
<section class="app-main xuc-content">
<div class="main-body">
<CourseManage :show-signup-actions="true" />
</div>
</section>
</template>
<script>
import CourseManage from './CourseManage.vue';
export default {
name: 'RemoteCourseManage',
components: { CourseManage },
};
</script>
<style lang="scss" scoped>
.app-main {
// padding-top: 20px;
}
.xuc-content {
margin: 0 auto;
}
.main-body {
background-color: #fff;
padding: 30px 20px;
}
</style>

View File

@@ -483,8 +483,11 @@ export default {
} else if (this.form.device2 === true) {
this.form.device = 2;
}
//时长,秒与分钟的转化
//if(this.form.)
// 时长,秒与分钟的转化
if (this.form.minute) {
this.form.duration = this.form.minute * 60;
}
try {
const { status,message} = await coueseFile.batchUpdate([this.form]);
if (status === 200) {

File diff suppressed because it is too large Load Diff

View File

@@ -1,206 +1,276 @@
<template>
<div style="padding: 12px 32px 10px 12px;">
<div style="display: flex;justify-content: flex-start;">
<div style="display: flex;justify-content: flex-start;">
<div><el-input v-model="keyword" placeholder="输入课程名称搜索" clearable></el-input></div>
<div style="padding-left: 10px;"><el-button @click="recordList()" type="primary" icon="el-icon-search">搜索</el-button></div>
<div style="padding: 0px 5px;"><el-button icon="el-icon-refresh-right" @click="keyword = ''" type="primary" >重置</el-button></div>
<div style="padding: 0px 5px;"><el-button type="primary" @click="exportFile()" icon="el-icon-search" size="small" round>导出</el-button></div>
<div style="padding: 0px 5px;"><el-button type="primary" @click="exportStudentOfTearcher()" icon="el-icon-search" size="small" round>导出学员信息</el-button></div>
</div>
<div class="Export">
<!-- <div style="padding-left: 10px;"><el-button type="primary" @click="exportFile()" icon="el-icon-search" size="small" round>导出</el-button></div> -->
<!-- <div style="padding: 0px 5px;"><el-button icon="el-icon-refresh-right" type="primary" size="small" round>导出学员信息</el-button></div> -->
</div>
<div style="margin-top:20px;">
<el-table :data="pageData" border stripe>
<el-table-column
label="课程时间"
prop="courseTime"
width="200px">
</el-table-column>
<el-table-column
label="课程名称"
prop="courseName"
width="200px">
</el-table-column>
<el-table-column
label="开课场地"
prop="address"
width="240px">
</el-table-column>
<el-table-column
label="所属课程"
prop="parentCourse"
width="120px">
</el-table-column>
<el-table-column
label="所属项目"
prop="parentProject"
></el-table-column>
<el-table-column
label="所属路径"
prop="parentRoute"
width="200px"
></el-table-column>
<el-table-column
label="学习总人数"
prop="studentNumber"
width="100px"
></el-table-column>
<el-table-column
label="时长(分钟)"
width="100px"
prop="period"
></el-table-column>
<el-table-column
label="评分"
width="100px"
prop="score"
></el-table-column>
<el-table-column
label="操作"
align="center"
width="150px"
prop="cz"
fixed="right"
>
<div>
<el-input v-model="keyword" placeholder="输入课程名称搜索" clearable></el-input>
</div>
<div style="padding-left: 10px;">
<el-button @click="recordList()" type="primary" icon="el-icon-search">搜索</el-button>
</div>
<div style="padding: 0px 5px;">
<el-button icon="el-icon-refresh-right" @click="keyword = ''" type="primary">重置</el-button>
</div>
<div style="padding: 0px 5px;">
<el-button type="primary" @click="exportFile()" icon="el-icon-search" size="small" round>导出</el-button>
</div>
<!-- <div style="padding: 0px 5px;">-->
<!-- <el-button type="primary" @click="exportStudentOfTearcher()" icon="el-icon-search" size="small" round>-->
<!-- 导出学员信息-->
<!-- </el-button>-->
<!-- </div>-->
</div>
<div class="Export">
<!-- <div style="padding-left: 10px;"><el-button type="primary" @click="exportFile()" icon="el-icon-search" size="small" round>导出</el-button></div> -->
<!-- <div style="padding: 0px 5px;"><el-button icon="el-icon-refresh-right" type="primary" size="small" round>导出学员信息</el-button></div> -->
</div>
<div style="margin-top:20px;">
<el-table :data="pageData" border stripe>
<el-table-column
label="序号"
prop="index"
width="100px">
<template v-slot="scope">
<el-button type="text" @click="exportStudentOfCourse(scope.row.courseId)" size="small">导出学员信息</el-button>
</template>
</el-table-column>
</el-table>
</div>
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column
label="讲师工号"
prop="userNo"
width="100px">
</el-table-column>
<el-table-column
label="讲师姓名"
prop="teacherName"
width="200px">
</el-table-column>
<el-table-column
label="课程名称"
prop="courseName"
width="200px">
</el-table-column>
<el-table-column
label="培训发生组织"
prop="trainOrgName"
width="200px">
</el-table-column>
<el-table-column label="课程类型" prop="type" width="120px">
<template v-slot="scope">
<span>{{
{
"0": "在线课",
"1": "面授课",
"2": "课程开发",
"3": "作业员入模培训",
"4": "其他",
}[scope.row.type + '']
}}</span>
</template>
</el-table-column>
<el-table-column
label="授课/课程日期"
prop="teachingDate"
width="200px">
</el-table-column>
<div style="text-align: center; margin-top:57px">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageInfo.page"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageInfo.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageInfo.total"
></el-pagination>
</div>
<el-table-column
label="内容分类"
prop="courseTypeName"
width="200px">
</el-table-column>
<el-table-column label="开课状态" width="100px" prop="courseStatus">
<template v-slot="scope">
<span>{{
{
"0": "未开课",
"1": "已开课",
}[scope.row.courseStatus + '']
}}</span>
</template>
</el-table-column>
<el-table-column
label="授课时长(分钟)"
prop="teaching"
width="120px"
></el-table-column>
<el-table-column
label="参训人数"
prop="studys"
width="120px"
></el-table-column>
<el-table-column
label="评分"
prop="score"
width="100px"
></el-table-column>
<el-table-column
label="是否生成讲师费"
prop="createdFee"
width="100px"
>
<template v-slot="scope">
<span>{{
{
"0": "否",
"1": "是",
}[scope.row.createdFee + '']
}}</span>
</template>
</el-table-column>
<el-table-column
label="备注"
width="200px"
prop="remark"
></el-table-column>
<el-table-column
label="操作"
align="center"
width="150px"
prop="cz"
fixed="right"
>
<template v-slot="scope">
<el-button type="text" @click="exportStudentOfCourse(scope.row.courseId, scope.row.type)"
size="small">导出学员信息
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div style="text-align: center; margin-top:57px">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageInfo.page"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageInfo.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageInfo.total"
></el-pagination>
</div>
</div>
</template>
<script>
import apiCourse from '../../api/boe/courseRecord.js';
import { mapGetters } from 'vuex';
import {mapGetters} from 'vuex';
export default {
data(){
return {
pageData:[],
keyword:'',
pageInfo:{},
}
},
data() {
return {
pageData: [],
keyword: '',
pageInfo: {
pageIndex:1,
pageSize:10,
},
}
},
mounted() {
this.recordList();
},
computed: {
...mapGetters(['userInfo'])
},
methods: {
// 导出所有记录
exportFile() {
// let req = {
// }
// apiCourse.courseRecordExport2(req).then(res => {
// const link = document.createElement('a');// 创建a标签
// let blob = new Blob([res.data], {type: 'application/vnd.ms-excel'}); // 设置文件类型
// link.style.display = "none";
// link.href = URL.createObjectURL(blob); // 创建URL
// link.setAttribute("download", "授课记录.xls");
// document.body.appendChild(link);
// link.click();
// document.body.removeChild(link);
// })
// 取pageData记录第一条
if (this.pageData.length > 0) {
let teacherId = this.pageData[0].teacherId;
window.open(
`/manageApi/admin/export/exportInTeacherRecord?teacherId=${teacherId}`
);
}
},
mounted() {
this.recordList(1);
// 导出课程下的学员信息
exportStudentOfCourse(courseId, courseType) {
// apiCourse.exportStudentOfCourse2(courseId, courseType).then(res => {
// const link = document.createElement('a');// 创建a标签
// let blob = new Blob([res.data], {type: 'application/vnd.ms-excel'}); // 设置文件类型
// link.style.display = "none";
// link.href = URL.createObjectURL(blob); // 创建URL
// link.setAttribute("download", "授课记录.xls");
// document.body.appendChild(link);
// link.click();
// document.body.removeChild(link);
// })
},
computed: {
...mapGetters(['userInfo'])
},
window.open(
`/manageApi/admin/export/exportTeacherRecordStudentInfo?courseId=${courseId}&courseType=${courseType}`
);
},
methods: {
// 导出教师下的所有授课记录下的学员信息
exportStudentOfTearcher() {
let userId = this.userInfo.sysId;
apiCourse.exportStudentOfTearcher2(userId).then(res => {
const link = document.createElement('a');// 创建a标签
let blob = new Blob([res.data], {type: 'application/vnd.ms-excel'}); // 设置文件类型
link.style.display = "none";
link.href = URL.createObjectURL(blob); // 创建URL
link.setAttribute("download", "授课记录.xls");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
},
// 导出所有记录
exportFile(){
let req = {
userId: this.userInfo.sysId
// userId:"70F80F4E-34BA-10AB-894A-8FA812B19637"
}
apiCourse.courseRecordExport(req).then(res=>{
const link = document.createElement('a');// 创建a标签
let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'}); // 设置文件类型
link.style.display = "none";
link.href = URL.createObjectURL(blob); // 创建URL
link.setAttribute("download", "授课记录.xls");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
},
// 导出课程下的学员信息
exportStudentOfCourse(courseId){
let userId = this.userInfo.sysId;
apiCourse.exportStudentOfCourse(userId,courseId).then(res=>{
const link = document.createElement('a');// 创建a标签
let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'}); // 设置文件类型
link.style.display = "none";
link.href = URL.createObjectURL(blob); // 创建URL
link.setAttribute("download", "授课记录.xls");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
},
// 导出教师下的所有授课记录下的学员信息
exportStudentOfTearcher(){
let userId = this.userInfo.sysId;
// let userId = '5D36C207-64F4-C512-312D-C9598257695C';
apiCourse.exportStudentOfTearcher(userId).then(res=>{
const link = document.createElement('a');// 创建a标签
let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'}); // 设置文件类型
link.style.display = "none";
link.href = URL.createObjectURL(blob); // 创建URL
link.setAttribute("download", "授课记录.xls");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
},
recordList(pageIndex){
let req = {
//     userId:"6B049FAF-C314-7CCF-0D28-0D23F4C42531",
userId: this.userInfo.sysId,
keyword:this.keyword,
    page:pageIndex,
    pageSize:10
}
apiCourse.courseRecordList(req).then(res=>{
if(res.status == 200) {
this.pageData = res.result.list;
this.pageInfo = res.result.pageInfo;
} else {
recordList() {
let req = {
courseName: this.keyword,
pageNo: this.pageInfo.pageIndex,
pageSize: this.pageInfo.pageSize
}
apiCourse.getListByToken(req).then(res => {
if (res.status == 200) {
this.pageData = res.data.records;
this.pageInfo.pageSize = Number(res.data.size);
this.pageInfo.total = Number(res.data.total);
this.pageInfo.page = Number(res.data.current);
} else {
this.$message({
type: 'error',
message: res.message
});
}
})
},
// 每页显示的条数事件
handleSizeChange(val){
this.pageInfo.pageSize = val;
this.recordList(1);
},
// 显示制定页的数据
handleCurrentChange(val){
this.pageInfo.pageIndex = val;
this.recordList(this.pageInfo.pageIndex);
},
},
type: 'error',
message: res.message
});
}
})
},
// 每页显示的条数事件
handleSizeChange(val) {
this.pageInfo.pageIndex = 1;
this.pageInfo.pageSize = val;
this.recordList();
},
// 显示制定页的数据
handleCurrentChange(val) {
this.pageInfo.pageIndex = val;
this.recordList(this.pageInfo.pageIndex);
},
},
}
</script>
<style lang="scss" scoped>
.Export{
display: flex;
padding-top: 10px;
.Export {
display: flex;
padding-top: 10px;
}
</style>

View File

@@ -6,32 +6,56 @@
3.建设课程邀请人流程提交审核流程都需要讨论 <br/>
4.有哪种几状态和哪几种操作需要讨论定一下 在哪种状态下可以有哪些操作<br/>
</Remark> -->
<div style="display: flex;justify-content:space-between;position: relative;">
<div style="display: flex;justify-content: flex-start; padding: 12px 32px 10px 12px;">
<!-- <div style="padding-left: 10px;">
<el-select style="width: 120px;" v-model="params.type" clearable placeholder="课程类型">
<el-option label="全部" :value="null"></el-option>
<el-option label="微课" :value="10"></el-option>
<el-option label="在线课" :value="20"></el-option>
</el-select>
</div> -->
<div style="padding-left: 10px;">
<el-select style="width: 120px;" v-model="params.status" clearable placeholder="状态">
<el-option label="全部" :value="null"></el-option>
<el-option label="草稿" :value="1"></el-option>
<el-option label="待审核" :value="2"></el-option>
<el-option label="已审核" :value="5"></el-option>
<el-row style="margin: 0 20px 20px 15px;" :gutter="8">
<el-col :span="7">
<div class="grid-content bg-purple"><el-input :maxlength="50" v-model="params.name" clearable
placeholder="课程名称" /></div>
</el-col>
<el-col :span="3">
<div class="grid-content bg-purple">
<el-select v-model="params.publish" placeholder="发布状态" clearable>
<el-option label="未发布" :value="false"></el-option>
<el-option label="已发布" :value="true"></el-option>
</el-select>
</div>
<div style="margin-left:10px"><el-input v-model="params.keyword" placeholder="名称关键字" clearable></el-input></div>
<div style="padding-left: 10px;"><el-button type="primary" icon="el-icon-search" @click="findList()">搜索</el-button></div>
<div style="padding: 0px 5px;"><el-button icon="el-icon-refresh-right" type="primary" @click="reset">重置</el-button></div>
</el-col>
<el-col :span="3">
<div class="grid-content bg-purple">
<el-select v-model="params.enabled" placeholder="启停用状态" clearable>
<el-option label="停用" :value="false"></el-option>
<el-option label="启用" :value="true"></el-option>
</el-select>
</div>
</el-col>
<el-col :span="3">
<div class="grid-content bg-purple">
<el-select v-model="params.status" placeholder="审核状态" clearable>
<el-option label="-" :value="1"></el-option>
<el-option label="审核中" :value="2"></el-option>
<el-option label="审核驳回" :value="3"></el-option>
<el-option label="审核通过" :value="5"></el-option>
</el-select>
</div>
</el-col>
<el-col :span="5">
<div class="grid-content bg-purple">
<el-button type="primary" @click="findList"> </el-button>
<el-button @click="reset"> </el-button>
</div>
</el-col>
<el-col :span="3" >
<div class="grid-content bg-purple" style="text-align: right;">
<el-button type="primary" icon="el-icon-plus" @click="addNewCourse">开发新课程</el-button>
</div>
</el-col>
</el-row>
<div class="Create-coures"><el-button type="primary" @click="addNewCourse()" icon="el-icon-plus">新建课程</el-button></div>
</div>
</div>
<!--课程列表内容-->
<div style="">
<div v-infinite-scroll="load" style="overflow:auto;height:1000px" infinite-scroll-distance="50"
:infinite-scroll-immediate="false" :infinite-scroll-disabled="disabled">
<div class="uc-course" v-for="(item, idx) in couresList" :key="idx" @click="jumpRouter(item)">
<div class="uc-course-img" style="width: 212px;height:119px">
<course-image :course="item"></course-image>
@@ -39,34 +63,38 @@
</div>
<div class="uc-course-info">
<div class="uc-course-name">
<!-- <span class="uc-course-type1">{{courseType(item.type)}}</span> -->
<span v-if="item.type == 10" class="uc-course-type1">录播</span>
<span v-if="item.type == 20" class="uc-course-type1">录播</span>
<span class="caogao" v-if="item.status == 1">草稿</span>
<span class="daishenhe" v-if="item.status == 2">待审核</span>
<span class="weitongguo" v-if="item.status == 3">审核未通过</span>
<span class="yishenhe" v-if="item.status == 5">已审核</span>
<!-- <a :href="`${webBaseUrl}/course/detail?id=${item.id}`" target="_blank"> {{item.name}}</a> -->
<span style="font-size:18px;color:#333">{{ item.name }}</span>
<el-tooltip class="item" effect="dark" :content="item.name" placement="top-start">
<span style="font-size:18px;color:#333">{{ item.name }}</span>
</el-tooltip>
</div>
<div class="summary-item">
<div>{{ item.summary }}</div>
</div>
<div class="uc-course-text">
<div class="uc-course-item">
上次修改时间{{ item.sysUpdateTime }}
<span type="text" style="margin-left:10px;font-size:14px;cursor: pointer;color:#666" @click.stop="toExamine(item)">查看审核记录</span>
</div>
</div>
<div class="uc-course-btns" style="line-height: 30px;">
<el-link style="display:block" :underline="false" @click.stop="examine(item)" type="primary" v-if="item.status == 1" icon="el-icon-document-checked">提交审核</el-link>
<el-link style="display:block" :underline="false" @click.stop="editCourse(item)" v-if="item.status == 3 || item.status == 4" type="primary" icon="el-icon-edit">编辑</el-link>
<el-link style="display:block" :underline="false" @click.stop="editCourse(item)" v-if="item.status == 1" type="primary" icon="el-icon-edit">去开发</el-link>
<el-link style="display:block" :underline="false" @click.stop="delItem(item)" v-if="item.status == 1" type="danger" icon="el-icon-delete">删除</el-link>
<el-link style="display:block" :underline="false" @click.stop="withdraw(item)" v-if="item.status == 2" type="info" icon="el-icon-delete">撤回</el-link>
<div class="uc-course-item">
<div class="status-item">发布状态{{ item.published ? '发布' : '未发布' }}</div>
<div class="status-item">启停用状态{{ item.enabled ? '启用' : '停用' }}</div>
<div class="status-item">审核状态<el-link :type="getStatusLabel(item.status).type" @click.stop=""
:underline="false">{{getStatusLabel(item.status).label}}</el-link></div>
</div>
<div class="btn-container">
<el-link class="btn-item" @mouseenter.native="$set(hoverStates, it.uniqueKey, true )"
@mouseleave.native="$set(hoverStates, it.uniqueKey, false )"
:style="{color: it.labelColor ? it.labelColor : (hoverStates[it.uniqueKey] ? '#4284F7' : '#000000')}"
v-for="(it, idx) in availableActions(item)" :key="idx" :underline="false" type="primary"
@click.stop="it.handler(item)"><svg-icon
style="margin-right: 5px;font-size:19px;padding-top: 4px;color:#000000"
:icon-class="hoverStates[it.uniqueKey] ? it.hoverIcon : it.icon"></svg-icon>{{it.label}}</el-link>
</div>
</div>
</div>
<p v-if="loading" class="page-tip">加载中...</p>
<div v-if="couresList.length == 0 && !loading">
<div v-if="isSearh" class="zan-wu">没有查询到相关内容</div>
<div v-else class="zan-wu">暂无数据</div>
</div>
<p v-else-if="noMore" class="page-tip">没有更多了</p>
</div>
<div v-if="couresList.length > 0" style="text-align: center; margin-top:57px;">
<!-- <div v-if="couresList.length > 0" style="text-align: center; margin-top:57px;">
<el-pagination
background
@size-change="handleSizeChange"
@@ -79,48 +107,146 @@
></el-pagination>
</div>
<div v-else>
<div v-if="couresList.length == 0">
<div v-if="isSearh" class="zan-wu">没有查询到相关内容</div>
<div v-else class="zan-wu">暂无数据</div>
</div>
</div>
</div> -->
<div></div>
<el-dialog title="二维码" :visible.sync="qrCodedialogVisible" width="900px" @close="closeCode" custom-class="g-dialog">
<div>
<el-form size="medium" label-width="100px">
<el-form-item label="二维码">
<div id="qrcode" ref="qrcode" class="qrcode-img" @mouseenter="showDownloadButton = true"
@mouseleave="showDownloadButton = false">
<div v-show="showDownloadButton" @click="downloadQrcode" class="downloadn-container">
<i class="el-icon-download" style="color: #409EFF;font-size:18px;margin-bottom:5px"></i>
<span>下载</span>
</div>
</div>
</el-form-item>
<el-form-item label="链接">
<el-input v-model="copyUrl" readonly class="input-with-select" id="text">
<el-button slot="append" @click="handleCopyUrl">复制</el-button>
</el-input>
</el-form-item>
<el-form-item label="">上述内容兼容PC端与移动端您可按需分享</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer"><el-button @click="closeCode"> </el-button></span>
</el-dialog>
<!-- TODO 修改展示字段 -->
<el-dialog title="审核记录" :visible.sync="dialogVisible" width="900px" custom-class="g-dialog">
<div>
<el-table max-height="500" border :data="inviteTeacher" style="width: 100%;">
<el-table-column prop="sysCreateBy" label="姓名" width="180"></el-table-column>
<el-table-column prop="type" label="审核状态">
<el-table-column prop="type" label="审核类型">
<template slot-scope="scope">
{{ scope.row.auditState ? '通过' : '不通过' }}
</template>
</el-table-column>
<el-table-column prop="type" label="审核状态">
<template slot-scope="scope">
{{ auditEnum[scope.row.status] }}
</template>
</el-table-column>
<el-table-column prop="auditUser" label="审核人"></el-table-column>
<el-table-column prop="auditTime" label="审核结果"></el-table-column>
<el-table-column prop="auditTime" label="审核时间"></el-table-column>
<el-table-column prop="auditRemark" label="备注"></el-table-column>
<el-table-column prop="auditRemark" label="审核意见"></el-table-column>
</el-table>
</div>
<span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false"> </el-button></span>
<span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false"> </el-button></span>
</el-dialog>
<course-form ref="courseForm" @submitSuccess="getList"></course-form>
<course-form ref="courseForm" @submitSuccess="getNewList"></course-form>
</div>
</template>
<script>
import courseImage from '@/components/Course/courseImage.vue';
import { mapGetters } from 'vuex';
import studyItem from '@/components/Course/studyItem.vue';
import courseForm from '@/components/Course/courseForm.vue';
import apiCourse from '@/api/modules/course.js';
import { courseType } from '@/utils/tools.js';
import apiAudit from '@/api/system/audit.js';
import apiHRBP from '@/api/boe/HRBP.js';
import apiOrg from '@/api/system/organiza.js';
import apiUserBasic from '@/api/boe/userbasic.js';
import QRCode from "qrcodejs2";
import courseImage from "@/components/Course/courseImage.vue";
import { mapGetters } from "vuex";
import studyItem from "@/components/Course/studyItem.vue";
import courseForm from "@/components/Course/courseForm.vue";
import apiCourse from "@/api/modules/course.js";
import { courseType } from "@/utils/tools.js";
import apiAudit from "@/api/system/audit.js";
import apiHRBP from "@/api/boe/HRBP.js";
import apiOrg from "@/api/system/organiza.js";
import apiUserBasic from "@/api/boe/userbasic.js";
// 状态权限映射
const STATUS_PERMISSIONS = {
// 未发布状态
unpublished: {
1: ["edit", "delete"], // 无审核状态
2: ["auditRecord"], // 审核中'withdraw'
3: ["edit", "delete", "auditRecord"], // 审核驳回
},
// 已发布状态
published: {
enabled: {
1: ["edit", "manage", "auditRecord", "qrcode"], //'offShelfApply', 'viewCurrent'
2: ["manage", "auditRecord", "qrcode"], // withdraw , 'viewCurrent'
3: ["edit", "manage", "auditRecord", "qrcode"], //'offShelfApply', 'viewCurrent'
5: ["edit", "manage", "auditRecord", "qrcode"], //'offShelfApply', 'viewCurrent'
},
disabled: {
// 所有状态在停用时操作一致
1: ["manage", "auditRecord"], //, 'viewCurrent'
2: ["manage", "auditRecord"], //, 'viewCurrent'
3: ["manage", "auditRecord"], //, 'viewCurrent'
5: ["manage", "auditRecord"], //, 'viewCurrent'
},
},
};
// 操作配置映射表
const ACTION_CONFIG = {
edit: {
label: "编辑",
handler: "editCourse",
icon: "edit",
hoverIcon: "editHover",
},
manage: {
label: "管理",
handler: "handleManage",
icon: "manage",
hoverIcon: "manageHover",
},
// withdraw: { label: '撤回', handler: 'handleWithdraw' },
auditRecord: {
label: "审核记录",
handler: "toExamine",
icon: "check",
hoverIcon: "checkHover",
},
qrcode: {
label: "二维码",
handler: "handleQrcode",
icon: "ercode",
hoverIcon: "ercodeHover",
},
// offShelfApply: { label: '下架申请', handler: 'handleOffShelfApply' },
// viewCurrent: { label: '查看当前版本', handler: 'handleViewCurrent', icon: 'detail' },
delete: {
label: "删除",
labelColor: "#FF1718",
handler: "delItem",
icon: "del",
hoverIcon: "del",
},
};
export default {
name: 'ucStudyIndex',
name: "ucStudyIndex",
components: { studyItem, courseForm, courseImage },
computed: {
...mapGetters(['userInfo'])
...mapGetters(["userInfo"]),
disabled() {
return this.loading || this.noMore;
},
},
data() {
@@ -130,19 +256,42 @@ export default {
courseType: courseType,
fileBaseUrl: process.env.VUE_APP_FILE_BASE_URL,
count: 0,
params: { keyword: '', type: '', status: '', createUser: '', pageIndex: 1, pageSize: 10, sysCreateAid: '' },
params: {
name: "",
publish: "",
status: "",
enabled: "",
pageIndex: 0,
pageSize: 10,
},
couresList: [],
flag: true,
isSearh:false,
isSearh: false,
qrCodedialogVisible: false,
copyUrl: "",
qrcodeImgUrl: "",
showDownloadButton: false, // 是否显示下载按钮
loading: false,
noMore: false,
auditEnum: {
1: "未审核",
2: "审核不通过",
9: "审核通过",
},
hoverStates: {},
};
},
mounted() {
if(this.$route.query && this.$route.query.open && this.$route.query.open == 'new') {
this.addNewCourse();
if (
this.$route.query &&
this.$route.query.open &&
this.$route.query.open == "new"
) {
this.addNewCourse();
}
this.getList();
// this.getList();
},
watch:{
watch: {
// '$route.query.open':function(val){
// if(val == 'new') {
// this.addNewCourse();
@@ -150,236 +299,330 @@ export default {
// }
},
methods: {
handleM() {
console.log("handleM");
},
load() {
this.loading = true;
this.params.pageIndex++;
this.getList();
},
getNewList() {
this.couresList = [];
this.params.pageIndex = 1;
this.getList();
},
getStatusLabel(code) {
if (code == "1") {
return { type: "info", label: "-" };
} else if (code == "2") {
return { type: "warning", label: "审核中" };
} else if (code == "3") {
return { type: "danger", label: "审核驳回" };
} else if (code == "5") {
return { type: "success", label: "审核通过" };
}
},
// 获取可用的操作配置
availableActions(item) {
const { status, published, enabled } = item;
let actionKeys = [];
if (!published) {
// 未发布状态
actionKeys = STATUS_PERMISSIONS.unpublished[status] || [];
} else {
// 已发布状态
const stateKey = enabled ? "enabled" : "disabled";
actionKeys = STATUS_PERMISSIONS.published[stateKey][status] || [];
}
return actionKeys
.map((key, index) => ({
name: key,
label: ACTION_CONFIG[key].label,
handler: this[ACTION_CONFIG[key].handler],
icon: ACTION_CONFIG[key].icon,
hoverIcon: ACTION_CONFIG[key].hoverIcon,
labelColor: ACTION_CONFIG[key].labelColor,
uniqueKey: `${item.id}-${key}-${index}`,
}))
.filter(Boolean);
},
handleManage(item) {
sessionStorage.setItem("courseDetail", JSON.stringify(item));
this.$router.push({ path: "/course/coursemanage" });
},
downloadQrcode() {
let img = document
.getElementById("qrcode")
.getElementsByTagName("img")[0];
let canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
let tempUrl = canvas.toDataURL("image/png");
// 创建a标签下载
let link = document.createElement("a"); //创建a标签
link.style.display = "none"; //使其隐藏
link.download = tempUrl;
link.setAttribute("target", "_blank");
link.href = tempUrl; //赋予文件下载地址
link.setAttribute("download", "二维码.jpg"); //设置下载属性 以及文件名
document.body.appendChild(link); //a标签插至页面中
link.click(); //强制触发a标签事件
document.body.removeChild(link);
},
handleCopyUrl() {
document.getElementById("text").select();
document.execCommand("Copy");
this.$showMessage('复制成功', 'success')
},
handleQrcode(row) {
this.qrCodedialogVisible = true;
let urlPre = window.location.protocol + "//" + window.location.host;
//动态的地址
//urlPre=urlPre+'/m?returnUrl='+urlPre+'/mobile/pages/login/loading?returnUrl=';
//固定的地址
// let returnUrl=urlPre+'/mobile/pages/login/loading?returnUrl=/pages/study/courseStudy?id='+row.id;
// let mobilePre=urlPre+'/m?returnUrl=';
// this.qrcodeImgUrl = mobilePre+encodeURIComponent(returnUrl);
// this.copyUrl=urlPre+this.webBaseUrl+'/course/studyindex?id='+row.id;
// if(row.type==20){
// this.copyUrl=urlPre+this.webBaseUrl+'/course/detail?id='+row.id;
// }
this.copyUrl = this.qrcodeImgUrl =
process.env.VUE_APP_BOE_WEB_URL +
"/systemapi/xboe/m/course/manage/redirectDetail?courseId=" +
row.id;
console.log("qrcodeImgUrl", this.qrcodeImgUrl);
console.log("webBaseUrl", this.webBaseUrl);
// 使用$nextTick确保数据渲染
this.$nextTick(() => {
this.crateQrcode();
});
},
// 生成二维码
crateQrcode() {
let qrcode = new QRCode("qrcode", {
width: 150,
height: 150, // 高度
text: this.qrcodeImgUrl, // 二维码内容
// render: 'canvas' // 设置渲染方式(有两种方式 table和canvas默认是canvas
// background: '#f0f'
// foreground: '#ff0'
});
console.log("qrcode", qrcode);
},
// 关闭弹框,清除已经生成的二维码
closeCode() {
this.qrCodedialogVisible = false;
// 逐个节点移除防止事件一起移除
let images = document.querySelectorAll(".qrcode-img img");
images.forEach((img) => img.remove());
let canvas = document.querySelectorAll(".qrcode-img canvas");
canvas.forEach((canvas) => canvas.remove());
},
// 撤回接口
withdraw(item) {
this.$confirm('此操作将撤回审核中的课程, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
this.$confirm("此操作将撤回审核中的课程, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
apiCourse.revokeSubmit(item.id).then(res => {
apiCourse.revokeSubmit(item.id).then((res) => {
if (res.status == 200) {
if (res.result) {
this.$message({
type: 'success',
message: '撤回成功!'
type: "success",
message: "撤回成功!",
});
this.getList();
this.getNewList();
}
}
});
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消撤回'
type: "info",
message: "已取消撤回",
});
});
},
reset() {
this.params.keyword = '';
this.params.status = '';
this.params.type = '';
this.params.name = "";
this.params.publish = "";
this.params.status = "";
this.params.enabled = "";
this.params.pageIndex = 1;
this.getList();
this.isSearh = false;
this.getNewList();
this.isSearh = false;
},
toExamine(row) {
// this.detailType = row.type;
this.dialogVisible = true;
apiAudit.page(1, row.id).then(res => {
if (res.status === 200) {
this.inviteTeacher = res.result;
} else {
this.$message.error(res.message);
}
});
apiCourse
.auditCourseRecords({
courseId: row.id,
})
.then((res) => {
if (res.status === 200) {
this.inviteTeacher = res.result;
} else {
this.$message.error(res.message);
}
});
},
examine(row) {
if(!row.orgId){
this.$message.error("课程还未设置资源归属,请先设置资源归属");
return;
}
let $this=this;
this.$confirm('您确定要直接提交审核所选课程吗?', '友情提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(()=>{
//新的提交流程
apiUserBasic.getOrgHrbpInfo(row.orgId).then(rs=>{
if(rs.status==200 && rs.result){
let req={
courseId:row.id,
email:rs.result.email,
courseUser:row.sysCreateBy,
courseName:row.name,
ucode:rs.result.userNo,
auditUser:rs.result.name,
//ukid:hrbpUser.user_id,
orgId:row.orgId,
orgName:rs.result.orgNamePath +'/'+rs.result.name
}
apiCourse.sumbits(req).then(res=>{
if(res.status==200){
$this.$message.success('提交成功');
row.status=2
}
if(res.status==400){
$this.$message.error('提交失败:'+res.message);
}
})
}else{
$this.$message.error("获取HRBP审核人员失败:"+rs.message);
}
});
// apiOrg.getSimple(row.orgId).then(rrs=>{
// if(rrs.status==200){
// apiHRBP.getHRBP(rrs.result.kid).then(rs=>{
// if(rs.status==200 && rs.result.length>0){
// let hrbpUser=rs.result[0];
// let req={
// courseId:row.id,
// email:hrbpUser.email,
// courseUser:row.sysCreateBy,
// courseName:row.name,
// ucode:hrbpUser.user_no,
// auditUser:hrbpUser.real_name,
// ukid:hrbpUser.user_id,
// orgId:row.orgId,
// orgName:rs.result.orgnization_name_path+'/'+rrs.result.name
// }
// apiCourse.sumbits(req).then(res=>{
// if(res.status==200){
// $this.$message.success('提交成功');
// row.status=2
// }
// if(res.status==400){
// $this.$message.error('提交失败:'+res.message);
// }
// })
// }else{
// $this.$message.error("获取HRBP审核人员失败:"+rs.message);
// }
// })
// }else{
// $this.$message.error("处理资源归属失败,请重新设置资源归属");
// }
// })
})
if (!row.orgId) {
this.$message.error("课程还未设置资源归属,请先设置资源归属");
return;
}
let $this = this;
this.$confirm("您确定要直接提交审核所选课程吗?", "友情提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
//新的提交流程
apiUserBasic.getOrgHrbpInfo(row.orgId).then((rs) => {
if (rs.status == 200 && rs.result) {
let req = {
courseId: row.id,
email: rs.result.email,
courseUser: row.sysCreateBy,
courseName: row.name,
ucode: rs.result.userNo,
auditUser: rs.result.name,
//ukid:hrbpUser.user_id,
orgId: row.orgId,
orgName: rs.result.orgNamePath + "/" + rs.result.name,
};
apiCourse.sumbits(req).then((res) => {
if (res.status == 200) {
$this.$message.success("提交成功");
row.status = 2;
}
if (res.status == 400) {
$this.$message.error("提交失败:" + res.message);
}
});
} else {
$this.$message.error("获取HRBP审核人员失败:" + rs.message);
}
});
});
},
delItem(row) {
this.$confirm('您确定要删除所选课程吗?', '删除提示', {
async delItem(row) {
this.$confirm(`<i class="el-icon-warning-outline"></i>确认删除${row.name}吗?`, '删除确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
dangerouslyUseHTMLString: true,
type: 'warning',
customClass: 'custom-confirm-dialog'
}).then(async () => {
let params = {
id: row.id,
title: row.name
title: row.name,
};
try {
// {id:课程id,多个使用逗号分隔,Boolean erasable 是否物理删除,title:课程的名称, remark 备注}
const { status } = await apiCourse.del(params);
if (status === 200) {
this.$message.success('操作成功!');
//事件移到后端处理
// if(!row.erasable){
// let event = {
// key: "DeleteCourse",//被管理员删除
// title: '自己删除课程',//事件的标题
// parameters:"author:"+this.userInfo.aid,//自己删除自己的课程,作者就是当前人
// content: '自己删除课程',//事件的内容
// objId: row.id,//关联的id
// objType: "1",//关联的类型
// objInfo:row.name,
// aid: this.userInfo.aid, //当前登录人的id
// aname: this.userInfo.name,//当前人的姓名
// status: 1 //状态直接写1
// }
// this.$store.dispatch("userTrigger", event);
// }
this.getList();
this.$showMessage('删除成功', 'success')
// this.$message.success("操作成功!");
this.getNewList();
} else {
this.$showMessage('删除失败', 'error')
}
} catch (error) {
console.log(error);
}
})
.catch(err => {
this.$message({ type: 'info', message: '已取消删除', offset: 50 });
});
})
},
jumpRouter(item) {
if (item.published) {
// if (item.type == 10) {
// let routeData = this.$router.resolve({ path: '/course/micro?id='+item.id});
// window.open(this.webBaseUrl+routeData.href, '_blank');
// let routeData = this.$router.resolve({ path: '/course/micro?id='+item.id});
// window.open(this.webBaseUrl+routeData.href, '_blank');
// window.open(this.webBaseUrl + '/course/micro?id=' + item.id, '_blank');
// this.$router.push({path:'/course/micro',query:{id:item.id}})
// this.$router.push({path:'/course/micro',query:{id:item.id}})
// }
// if (item.type == 20) {
// let routeData = this.$router.resolve({ path: '/course/detail?id='+item.id});
// window.open(this.webBaseUrl+routeData.href, '_blank');
// window.open(this.webBaseUrl + '/course/detail?id=' + item.id, '_blank');
//this.$router.push({path:'/course/detail',query:{id:item.id}})
this.$router.push({path:'/course/studyindex',query:{id:item.id}})
// }
// let routeData = this.$router.resolve({ path: '/course/detail?id='+item.id});
// window.open(this.webBaseUrl+routeData.href, '_blank');
// window.open(this.webBaseUrl + '/course/detail?id=' + item.id, '_blank');
//this.$router.push({path:'/course/detail',query:{id:item.id}})
this.$router.push({
path: "/course/studyindex",
query: { id: item.id },
});
// }
} else {
// if (item.type == 10) {
// // window.open(`${this.webBaseUrl}/course/microPreview?id=${item.id}`);
// this.$router.push({path:'/course/microPreview',query:{id:item.id}})
// } else {
// window.open(`${this.webBaseUrl}/course/rePreview?id=${item.id}`);
this.$router.push({path:'/course/rePreview',query:{id:item.id}})
this.$router.push({
path: "/course/rePreview",
query: { id: item.id },
});
// }
}
},
findList() {
this.params.pageIndex = 1;
this.isSearh = true;
this.getList();
this.getNewList();
},
getList() {
this.params.aid = this.userInfo.aid;
apiCourse.pageList(this.params).then(res => {
this.noMore = false;
// this.params.teacherId = this.userInfo.aid;
apiCourse.courseList(this.params).then((res) => {
this.loading = false;
if (res.status == 200) {
this.couresList = res.result.list;
this.couresList = [...this.couresList, ...res.result.list];
this.count = res.result.count;
console.log(this.couresList.length, "this.count", this.count);
if (this.couresList.length >= this.count) {
this.noMore = true;
}
} else {
this.$message.error(res.message);
this.$showMessage(res.message, 'error')
}
});
},
handleSizeChange(val) {
this.params.pageSize = val;
// this.params.pageIndex = 1;
this.getList();
},
handleCurrentChange(val) {
this.params.pageIndex = val;
this.getList();
},
addNewCourse() {
this.$refs.courseForm.initShow();
},
editCourse(row) {
console.log(row, "editCourse");
this.$refs.courseForm.initShow(row);
},
lastTabChange(tab, event) {
console.log(tab.name);
}
}
},
},
};
</script>
<style scoped lang="scss">
.list-wu{
.page-tip {
margin: 20px auto;
text-align: center;
font-size: 13px;
}
.list-wu {
text-align: center;
margin: 40px;
color: #333;
@@ -422,6 +665,35 @@ export default {
margin-top: 10px;
margin-right: 40px;
}
.qrcode-img {
width: 150px;
height: 150px;
display: block;
position: relative;
.downloadn-container {
position: absolute;
width: 40px;
height: 45px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 99;
background: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
transition: all 0.3s ease;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
cursor: pointer;
span {
color: #409eff;
display: block;
font-size: 12px;
line-height: 12px;
}
}
}
.uc-course {
cursor: pointer;
display: flex;
@@ -429,10 +701,11 @@ export default {
border-bottom: 1px solid #e8e8e8;
padding: 20px 0px 15px 0px;
margin: 0 32px 0 22px;
::v-deep .uc-course-img {
::v-deep .uc-course-img {
width: 212px;
img {
width: 212px;height:119px;
width: 212px;
height: 119px;
border: 1px solid #f4f4f5;
}
}
@@ -448,7 +721,7 @@ export default {
font-size: 14px;
overflow: hidden;
width: 90%;
word-break:break-all;
word-break: break-all;
display: -webkit-box;
// overflow: hidden;
-webkit-box-orient: vertical;
@@ -457,22 +730,36 @@ export default {
.uc-course-name {
font-size: 16px;
display: -webkit-box;
white-space:pre-wrap;
// word-wrap: break-word;
overflow: hidden;
text-overflow:ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
word-break:break-all;
white-space: pre-wrap;
// word-wrap: break-word;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
word-break: break-all;
// font-weight: 700;
}
.uc-course-text {
.uc-course-item {
color: #666;
margin-top: 28px;
// margin-top: 4px;
font-size: 14px;
display: flex;
// flex-wrap: nowrap;
.status-item {
margin-right: 20px;
flex-shrink: 0;
}
}
.btn-container {
margin-top: 10px;
display: flex;
.btn-item {
margin-right: 20px;
}
}
}
.uc-course-btns {
text-align: right;
.btn1 {
height: 44px;

View File

@@ -954,7 +954,7 @@ export default {
},
findPapers() {
let params={
pageSize:200,
pageSize:10000,
name:''
}
apiPaper.querypaper(params).then((res) => {

View File

@@ -5,8 +5,8 @@
<!-- 当轮播图等于一张时 -->
<swiper :options="swiperOptiontwo">
<swiper-slide style="margin: 0 auto" v-for="(item, idx) in resonimg" :key="'a' + idx"
class="swiper-slide games pointer">
<div class="bannbox" :style="{
class="swiper-slide games pointer" >
<div class="bannbox" @click="handleCarouselClick(item)" :style="{
background: `url(${fileBaseUrl + item.image
}) center center no-repeat`,
}"></div>
@@ -17,8 +17,8 @@
<div id="container" style="z-index: 99" v-else>
<swiper :options="swiperOption" ref="mySwiper" v-if="resonimg.length > 1">
<swiper-slide style="margin: 0 auto" v-for="(item, idx) in resonimg" :key="'b' + idx"
class="swiper-slide games pointer">
<div class="bannbox" :style="{
class="swiper-slide games pointer" >
<div class="bannbox" @click="handleCarouselClick(item)" :style="{
background: `url(${fileBaseUrl + item.image
}) center center no-repeat`,
}"></div>
@@ -220,7 +220,7 @@ export default {
autoplay: false,
// noSwiping: true,
},
resonimg: [],
// resonimg: [],
swiperOption: {
autoplay: {
delay: 2000,
@@ -249,6 +249,13 @@ export default {
this.getToolData()
},
methods: {
// 添加点击轮播图跳转的方法
handleCarouselClick(item) {
if (item.url) {
window.open(item.url, '_blank');
}
},
downTool(toolInfo) {
console.log(toolInfo);
window.open(`/activityApi/xboe/m/boe/tools/url/download?urlStr=${process.env.VUE_APP_BOE_WEB_URL}/upload${toolInfo.filePath}&fileName=${toolInfo.name}`)

Some files were not shown because too many files have changed in this diff Show More