Compare commits

..

424 Commits

Author SHA1 Message Date
lwj
7765b3c66c 修复1155报错、阶段性审核信息 2025-12-24 14:24:16 +08:00
liu.zixi
ee798fa595 fix: 资源学习情况倒序改正序
(cherry picked from commit 0837ab3676)
2025-12-24 09:35:44 +08:00
liuzixi
3a0cc65b55 fix: 修正问题10
(cherry picked from commit d6b7a9c380)
2025-12-23 21:51:35 +08:00
liuzixi
00a9c69555 fix: 修正问题10
(cherry picked from commit 233e7c29df)
2025-12-23 21:42:30 +08:00
liu.zixi
47add103d2 fix: 问题27修复
(cherry picked from commit 744f648748)
2025-12-23 18:49:05 +08:00
miaowenbo
b1d3aa7a98 fix:导出作业文件名逻辑修改
(cherry picked from commit be966faa02)
2025-12-23 16:11:02 +08:00
miaowenbo
f517c9059d 解决冲突后提交 2025-12-23 16:03:30 +08:00
liu.zixi
2ffdaf83a2 merge: AI课程特性融合至新的在线管理
(cherry picked from commit e9c884c246)
2025-12-23 09:54:03 +08:00
liu.zixi
ce347c7f6f fix: 问题19修复
(cherry picked from commit 90d09cac25)
2025-12-23 09:44:56 +08:00
liu.zixi
8f3e48b8d3 fix: 问题15修复
(cherry picked from commit 6c08b27ed3)
2025-12-22 19:45:25 +08:00
liu.zixi
2d65d2616f fix: 问题13修复
(cherry picked from commit b2632c9877)
2025-12-22 19:33:24 +08:00
yangxinyu
a17f659b26 fix:【FCJDFDXTXS-202】
(cherry picked from commit b5bf0429aa)
2025-12-22 19:33:19 +08:00
liu.zixi
51e7bea47a fix: 排序时对sys_create_time做适配
(cherry picked from commit 4c8c571a82)
2025-12-22 19:33:12 +08:00
liuzixi
84f7aa8c20 fix: 课程时长四舍五入 2025-12-20 10:16:15 +08:00
liu.zixi
1fb655024f fix: 导出的score四舍五入 2025-12-19 17:58:14 +08:00
miaowenbo
aadc14c88f fix:资源学习完成人数统计排除未报名人员 2025-12-19 17:58:10 +08:00
liu.zixi
a8693fd7a9 fix: 【FCJDFDXTXS-190】修复报名记录影响的学习记录 2025-12-19 15:41:19 +08:00
liu.zixi
e6c494e7c1 fix: 【FCJDFDXTXS-190】修复报名记录的一些bug 2025-12-19 15:22:27 +08:00
liu.zixi
452b1e9ec8 fix: 【FCJDFDXTXS-199】资源学习情况-作业/考试导出问题修复 2025-12-19 12:32:31 +08:00
liu.zixi
6227a91f98 fix: 【FCJDFDXTXS-199】资源学习情况-作业/考试导出问题修复 2025-12-19 12:02:05 +08:00
liu.zixi
dcd041e18c fix: 【FCJDFDXTXS-199】资源学习情况-作业导出问题修复 2025-12-19 11:56:51 +08:00
liu.zixi
3b7447f24f fix: 【FCJDFDXTXS-199】资源学习情况导出调试 2025-12-19 11:43:54 +08:00
liu.zixi
5644e8d99a fix: 【FCJDFDXTXS-199】资源学习情况导出调试 2025-12-19 11:43:46 +08:00
yangxinyu
c388c7199e fix:添加学习记录导出接口aid查询 2025-12-19 11:43:42 +08:00
liu.zixi
857b4a3907 fix: 【FCJDFDXTXS-199】资源学习情况的作业、考试的导出查询、拼excel数据逻辑修正 2025-12-19 11:23:06 +08:00
liu.zixi
c47bf78375 fix: 【FCJDFDXTXS-201】编辑后不从es里删除 2025-12-19 11:23:02 +08:00
liu.zixi
dddd5d4073 fix: 【FCJDFDXTXS-190】手动添加报名记录逻辑修正:1.修改学习人数 2.判断此前是否存在记录 2025-12-19 09:53:13 +08:00
liu.zixi
aad3b6ed78 fix: 【FCJDFDXTXS-190】资源学习情况 2025-12-18 19:33:11 +08:00
liu.zixi
84465d36af fix: 【FCJDFDXTXS-192】受众成员接口更新 2025-12-18 19:19:25 +08:00
liu.zixi
4ba5997448 fix: 【FCJDFDXTXS-190】资源学习情况只查询有报名记录的数据 2025-12-18 19:19:19 +08:00
miaowenbo
bb08b2da7e fix:【FCJDFDXTXS-190】报名记录导出接口,添加在学习记录中添加单独查询字段signUpAid,只查询有报名数据aid的用户 2025-12-18 18:44:51 +08:00
miaowenbo
b6a6ca8cf8 fix:【FCJDFDXTXS-190】添加报名记录列表查询接口,并在学习记录中添加单独查询字段signUpAid,只查询有报名数据aid的用户 2025-12-18 18:44:49 +08:00
yangxinyu
18ef1e3e49 fix:【FCJDFDXTXS-188】修改导出报名记录排序+导出报名记录aid查询 2025-12-18 18:44:42 +08:00
joshen
9a4511b703 Merge remote-tracking branch '121/test1031' into test1031 2025-12-18 15:13:13 +08:00
lwj
7b7798e124 解决代码冲突导致的问题 2025-12-18 15:12:57 +08:00
lwj
fb99a5562e 解决代码冲突导致的问题 2025-12-18 15:12:55 +08:00
liu.zixi
7a3176a05f fix: 【FCJDFDXTXS-186】修改置顶逻辑 2025-12-18 15:06:51 +08:00
liu.zixi
0e34f2edf2 fix: 状态修正 2025-12-18 15:06:44 +08:00
liu.zixi
4b19da0a5d fix: 审核记录修改 2025-12-18 15:06:38 +08:00
liuzixi
cb9cfca4c3 fix: 【FCJDFDXTXS-176】状态机修正 2025-12-18 15:06:35 +08:00
lwj
beb4fb7470 fix:在线课程管理列表中添加审核人审核时间 2025-12-18 14:22:45 +08:00
liuzixi
a83550f37a fix: 【FCJDFDXTXS-145】修复未开始数据出不来的问题 2025-12-17 21:50:46 +08:00
miaowenbo
e99b79be46 fix:【FCJDFDXTXS-177】为了拼接章名称+节名称后仍然可以根据资源名称进行模糊查询,修改原有的分页接口为手动分页(和需求确认后,现有数据课程资源数量不会超过50,因此效率相近),并添加对应查询逻辑 2025-12-17 21:50:41 +08:00
yangxinyu
6037c651d5 fix:【FCJDFDXTXS-177】 2025-12-17 21:49:38 +08:00
miaowenbo
577436ed71 fix:临时资源名称模糊查询逻辑修改 2025-12-17 21:49:05 +08:00
miaowenbo
188dcc5ac2 fix:【FCJDFDXTXS-133】 查询资源学习item数据(联表获取作业完成状态用),逻辑为根据studyCourseItem表的id连接studyHomework表的studyItemId获取作业完成状态 2025-12-17 21:49:00 +08:00
liu.zixi
a3fac42698 fix: 【FCJDFDXTXS-145】作业、评估 2025-12-17 17:54:49 +08:00
liu.zixi
6dba906938 fix: 【FCJDFDXTXS-145】解决一个问题 2025-12-17 17:29:18 +08:00
liu.zixi
83af38ff0f fix: 【FCJDFDXTXS-145】分页查询换成原始sql 2025-12-17 17:12:54 +08:00
liu.zixi
4160752e99 fix: 【FCJDFDXTXS-145】分页查询 2025-12-17 17:12:41 +08:00
yangxinyu
c8ed0141ec fix:【FCJDFDXTXS-174】资源展示列表改为完成时间降序 2025-12-17 17:12:31 +08:00
yangxinyu
be78754a62 fix:【FCJDFDXTXS-174】考试展示列表改为完成时间降序 2025-12-17 17:12:23 +08:00
yangxinyu
9abc3b7836 fix:【FCJDFDXTXS-174】评估展示列表改为完成时间降序 2025-12-17 17:12:19 +08:00
liuzixi
cb3acda07b fix: 【FCJDFDXTXS-145】调整sql写法 2025-12-17 17:12:17 +08:00
liu.zixi
ff54e2724e fix: 【FCJDFDXTXS-145】先不采用此方案 2025-12-16 20:39:27 +08:00
liu.zixi
f822e7b435 fix: 【FCJDFDXTXS-145】两个id调个个 2025-12-16 20:39:23 +08:00
liu.zixi
d1687dfd74 fix: 【FCJDFDXTXS-145】status纠错 2025-12-16 20:39:19 +08:00
liu.zixi
32c89745fd fix: 【FCJDFDXTXS-145】progress纠错 2025-12-16 20:39:17 +08:00
liu.zixi
f7e8f282c5 fix: 【FCJDFDXTXS-145】去掉group by 2025-12-16 20:13:23 +08:00
liu.zixi
65e6fb8149 fix: 【FCJDFDXTXS-145】打印堆栈 2025-12-16 19:59:31 +08:00
liu.zixi
7a001bda15 fix: 【FCJDFDXTXS-145】更换资源学习情况学习人员分页查询方法 2025-12-16 19:51:51 +08:00
miaowenbo
70dd103e73 fix:【FCJDFDXTXS-170】经过生产库数据确认,修改作业内容字段为hwAnswer 2025-12-16 19:51:47 +08:00
yangxinyu
3df1d8b120 fix:修改作业内容字段 2025-12-16 19:51:41 +08:00
miaowenbo
9b7c134ecd fix:【FCJDFDXTXS-143】默认展示全部学习时长从studyCourse表的totalDuration修改为studyCourseItem的studyDuration字段求和(原逻辑只有筛选时间段后求和,测试数据有不对应情况,因此改为所有情况均求和) 2025-12-16 19:51:38 +08:00
yangxinyu
1b7665b066 fix:修改获取章节问题 2025-12-16 19:51:35 +08:00
miaowenbo
2f981735be fix:【FCJDFDXTXS-169】修改导出excel的展示逻辑,修改为课程名称的作业名称 2025-12-16 19:51:28 +08:00
miaowenbo
88e5958a02 fix:添加根据课程id查询studyCourse表数据集合,并修正对应的错误逻辑 2025-12-16 19:51:26 +08:00
yangxinyu
6be065cf80 fix:【FCJDFDXTXS-151】修改资源名称展示章名称-节名称 2025-12-16 19:51:23 +08:00
miaowenbo
f3785714aa 【FCJDFDXTXS-165】作业导出去掉完成时间字段 2025-12-16 14:01:56 +08:00
yangxinyu
04081dc142 fix:【FCJDFDXTXS-151】新增多个aid查询 2025-12-16 14:01:53 +08:00
miaowenbo
025274108e fix:【FCJDFDXTXS-136】修改考试的查询状态,考试通过-2,考试未通过-4 2025-12-16 14:01:46 +08:00
miaowenbo
c87e5cd592 feat:【FCJDFDXTXS-138】考试状态的枚举修改为“已通过、未通过” 2025-12-16 14:01:42 +08:00
miaowenbo
1e2e18152e feat:.【FCJDFDXTXS-138】所有考试成绩修改为整数 2025-12-16 14:01:41 +08:00
郭诚奇
ecf99890e3 feat: 新增初始化会话接口,给前端返回初始化会话id 2025-12-16 13:58:21 +08:00
miaowenbo
880d1012fb feat:
1.【FCJDFDXTXS-120】导出学习记录学习完成时间为空时,学习结束时间应为学生最后一次学习时间
2.【FCJDFDXTXS-115、138、140】修改课程名称的展示逻辑,修改为章名称+节名称,详细逻辑如下:默认取sectionName-contentName,如果sectionName不存在,就用courseName-contentName
2025-12-16 09:00:52 +08:00
hehongqiang
4de1577435 Merge branch 'feature/20251130-hhq' into test1031 2025-12-15 20:25:00 +08:00
liu.zixi
f515d0c49e fix: 【FCJDFDXTXS-112】增加txt类型上传支持 2025-12-15 20:08:46 +08:00
liu.zixi
bc771a3878 fix: 【FCJDFDXTXS-87】纠错 2025-12-15 18:56:39 +08:00
liu.zixi
7f32ba5b91 fix: 【FCJDFDXTXS-87】、【FCJDFDXTXS-88】更新top方法的逻辑 2025-12-15 17:55:47 +08:00
liu.zixi
3257e41975 fix: 更新课程基本信息时不变更状态 2025-12-15 17:55:43 +08:00
liu.zixi
a795dc3670 fix: 【FCJDFDXTXS-144】优化复制课程的逻辑-去掉空格 2025-12-15 15:05:18 +08:00
liu.zixi
75a788dd78 fix: 【FCJDFDXTXS-144】优化复制课程的逻辑 2025-12-15 14:57:06 +08:00
yangxinyu
018912b26d fix:【FCJDFDXTXS-142】学习时长字段表头与.学习状态字段枚举值应为“未开始、进行中、已完成”修改 2025-12-15 14:27:56 +08:00
yangxinyu
530d479de5 feat:修改作业导出时,展示为作业内容和完成状态 2025-12-15 14:27:49 +08:00
yangxinyu
a381b44c84 fix:FCJDFDXTXS-114学习状态字段展示修改 2025-12-15 14:27:47 +08:00
liuzixi
f1a3fb2a8d fix: 【FCJDFDXTXS-88】修正批量置顶排序功能 2025-12-13 15:53:32 +08:00
liu.zixi
6d4074495a fix: 【FCJDFDXTXS-87】修正置顶时对es的修改逻辑 2025-12-13 15:43:52 +08:00
yangxinyu
542ad20fac feat:导出报名记录添加按照报名时间倒叙 2025-12-13 09:33:14 +08:00
liu.zixi
370da3120f fix: 【FCJDFDXTXS-82】排序修改成gbk 2025-12-12 17:19:53 +08:00
liu.zixi
3f4dbd6f09 fix: 【FCJDFDXTXS-62】修正资源归属排序字段 2025-12-12 16:37:31 +08:00
liu.zixi
b8dd446703 fix: 【FCJDFDXTXS-82】修正置顶及置顶排序的逻辑 2025-12-12 16:37:28 +08:00
liu.zixi
a2cc0a4965 fix: 【FCJDFDXTXS-86】去掉一个where条件 2025-12-12 11:13:30 +08:00
zhrh
33f52eb209 Merge branch 'test1031' of http://10.251.129.121/boeu/java-servers into test1031 2025-12-12 11:02:21 +08:00
zhrh
52bd123eb3 添加日志,记录学习个节点查询时间 2025-12-12 10:56:25 +08:00
liu.zixi
51dd464bdd fix: 【FCJDFDXTXS-84】修改查询语句,查询授课教师 2025-12-12 10:54:07 +08:00
liu.zixi
37ab50c9ca fix: 【FCJDFDXTXS-85】置顶列表修正 2025-12-12 10:54:03 +08:00
liu.zixi
238c61f4fa fix: 【FCJDFDXTXS-44】资源归属查询失败修正 2025-12-12 10:53:58 +08:00
liu.zixi
2c6f931d8e fix: 【FCJDFDXTXS-57、FCJDFDXTXS-65】给列表页一些默认数据 2025-12-12 10:53:55 +08:00
liu.zixi
e29d8c466e fix: 课程列表学习人数只统计学习中的,即status > 1 2025-12-11 19:37:15 +08:00
liu.zixi
e179fc0558 fix: 【FCJDFDXTXS-70】导出时课程评分四舍五入 2025-12-11 19:17:02 +08:00
liu.zixi
bac2c3f3fc feat: 课程列表导出,组织名称改为导出全路径 2025-12-11 19:11:37 +08:00
liu.zixi
675324757b feat: 丰富一下导出excel的内容和样式 2025-12-11 19:07:31 +08:00
yangxinyu
f8f7923e93 feat:增加入参 userId 支持多选 2025-12-11 18:51:54 +08:00
liu.zixi
eca24fb550 fix: 修复部分情况下topList接口报错的问题 2025-12-11 18:51:50 +08:00
liu.zixi
a1232d7bf7 fix: 【FCJDFDXTXS-69】兼容open_course为null的情况 2025-12-11 18:51:48 +08:00
liu.zixi
3c057b9f6e fix: 【FCJDFDXTXS-66】修正导出数据 2025-12-11 16:50:30 +08:00
liu.zixi
a77874f361 fix: 【FCJDFDXTXS-47】修正课程分类的排序问题 2025-12-11 16:50:25 +08:00
liu.zixi
b5c9fc27e0 fix: 【FCJDFDXTXS-35】修正培训时间查询 2025-12-11 16:50:23 +08:00
liu.zixi
39b6e1b36d fix: 【FCJDFDXTXS-35】修正培训时间查询 2025-12-11 14:33:15 +08:00
liu.zixi
be180cbb36 fix: 【FCJDFDXTXS-50】教师姓名用、分隔 2025-12-11 14:33:10 +08:00
liu.zixi
81849c7cbb fix: sortWeight应用到es 2025-12-11 14:33:05 +08:00
Jiang Yulong
634e7d83af feat: chat接口会话结束时, 发送docId给前端 2025-12-11 11:19:19 +08:00
joshen
6d9eaac6a0 Merge branch 'player-20251117' into test1031 2025-12-10 17:18:55 +08:00
Jiang Yulong
9809092454 feat: chat接口会话结束时, 发送docId给前端 2025-12-10 16:57:57 +08:00
liu.zixi
24036aa1a1 fix: 调接口时增加请求头(目前只在创建对话时做处理) 2025-12-10 16:16:16 +08:00
liu.zixi
5959ded9f3 feat: 修改默认提示语 2025-12-10 16:16:13 +08:00
Jiang Yulong
21d14b74b1 feat: AI消息查询功能出参增加字段 2025-12-10 15:37:28 +08:00
yangxinyu
7395e6a7b6 feat:修改学习记录导出中学习时长字段格式为两位小数 2025-12-10 08:49:38 +08:00
joshen
7849f7c98d Merge branch 'player-20251117' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/school/study/api/StudyCourseApi.java
2025-12-09 10:15:45 +08:00
joshen
c5b9de8a44 Merge branch 'player-20251117' into test1031 2025-12-08 19:39:56 +08:00
joshen
0dcc075579 Merge branch 'player-20251117' into test1031 2025-12-08 18:50:43 +08:00
joshen
bfc2c86f28 commit code 2025-12-08 18:30:25 +08:00
joshen
b4124572eb Merge branch 'player-20251117' into test1031 2025-12-08 17:58:07 +08:00
zhrh
ee6a830ad0 szx-1194 删除日志 2025-12-08 17:26:22 +08:00
zhrh
d67a6afca4 szx-1194 获取用户信息用http添加日志修改 2025-12-08 17:13:13 +08:00
zhrh
8e6dd70117 szx-1194 获取用户信息用http添加日志修改 2025-12-08 17:00:13 +08:00
zhrh
f61e2c1585 Merge branch 'refs/heads/SZX-1194-20251203-zhrh' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java
2025-12-08 16:37:08 +08:00
zhrh
64a3b26e77 szx-1194 获取用户信息用http添加日志 2025-12-08 16:32:42 +08:00
joshen
3c8d39acc2 Merge remote-tracking branch '121/test1031' into test1031 2025-12-08 15:52:34 +08:00
joshen
6419959daa Merge branch 'player-20251117' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java
2025-12-08 15:52:07 +08:00
zhrh
4b282f272c Merge branch 'SZX-1194-20251203-zhrh' into test1031 2025-12-08 15:51:16 +08:00
zhrh
9f4475dd05 szx-1194 获取用户信息用http 2025-12-08 15:50:00 +08:00
joshen
ac19d95213 Merge branch 'player-20251117' into test1031 2025-12-08 14:59:19 +08:00
zhrh
057bba928c 处理冲突 2025-12-08 14:38:43 +08:00
zhrh
5033cf6852 szx-1194 审批时邮箱的获取由前端传入改为后端获取添加日志 2025-12-08 14:16:17 +08:00
zhrh
02f253254f Merge branch 'refs/heads/SZX-1194-20251203-zhrh' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/boecase/api/CaseAiChatApi.java
#	servers/boe-server-all/src/main/java/com/xboe/module/boecase/service/ICaseAiChatService.java
#	servers/boe-server-all/src/main/java/com/xboe/module/boecase/service/impl/CaseAiChatServiceImpl.java
#	servers/boe-server-all/src/main/java/com/xboe/module/boecase/task/CaseUploadTask.java
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java
#	servers/boe-server-all/src/main/resources/application-prod.yml
#	servers/boe-server-all/src/main/resources/log/logback-prod.xml
2025-12-08 14:14:54 +08:00
zhrh
ec3d8c57ac szx-1194 审批时邮箱的获取由前端传入改为后端获取添加日志 2025-12-08 14:07:49 +08:00
joshen
28f5c42676 commit code 2025-12-08 14:00:05 +08:00
yangxinyu
c224f73173 feat:修改资源学习列表count数计算 2025-12-08 13:23:49 +08:00
joshen
db7fb7a24e Merge branch 'player-20251117' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java
#	servers/boe-server-all/src/main/resources/application-test.yml
2025-12-08 11:23:46 +08:00
joshen
bd241e27bf 解决冲突 2025-12-07 11:34:30 +08:00
joshen
b8267c7d05 解决冲突 2025-12-07 11:31:18 +08:00
miaowenbo
3c98dd11f1 feat:
1.导出学习记录接口修改工号字段映射,调用用户中心取code字段,本地库取userNo字段
2.修改分页查询课程学习记录接口,原有分页接口只支持查询当前登录用户,增加同逻辑的课程维度分页接口
3.增加学习时长时间筛选字段与枚举(学习时长筛选逻辑还未完成)
2025-12-07 11:26:41 +08:00
liu.zixi
d6aa0ef534 fix: 课程列表接口纠错 2025-12-06 17:38:30 +08:00
liu.zixi
dee8c54de5 fix: 课程列表接口纠错 2025-12-06 17:38:27 +08:00
liu.zixi
32b69e57af fix: 课程列表接口增加返回最后修改时间 2025-12-06 17:27:12 +08:00
liu.zixi
b77c095930 fix: 课程列表接口增加返回课程类型 2025-12-06 17:27:08 +08:00
miaowenbo
6a385fe0bd fix:修复了资源学习情况列表查询的有没有状态名称模糊查询不一致的问题,现在统一模糊查询
status为空查询字段加上aid,方便前端获取工号部门信息
2025-12-06 17:27:06 +08:00
joshen
2ef5d652d9 ceshiwenti 2025-12-05 22:55:45 +08:00
liu.zixi
046386af18 fix: 新定时任务修正 2025-12-04 19:20:25 +08:00
liu.zixi
0a80acb1ef fix: 加回注解 2025-12-04 19:05:25 +08:00
liu.zixi
e306868745 fix: 去掉注解 2025-12-04 18:58:12 +08:00
liu.zixi
c33e7eda13 fix: 修正索引添加 2025-12-04 18:51:21 +08:00
liu.zixi
2225ef2265 feat: 新增功能:导出消息时记录错误提示 2025-12-04 18:44:39 +08:00
郭诚奇
b1e128f39c feat: AI消息查询功能完善 2025-12-04 18:44:35 +08:00
郭诚奇
3cd9b6881b feat: AI消息点赞/踩/取消点赞/取消踩/问题反馈信息保存功能完善 2025-12-04 18:44:33 +08:00
郭诚奇
6afd809aa7 feat: 停止当前聊天输出接口功能完善 2025-12-04 18:44:30 +08:00
yangxinyu
f3f80d2bee feat:修改资源学习列表无完成人数无法查到资源的问题 2025-12-04 18:44:08 +08:00
miaowenbo
cfa92cc13e fix:学习记录查询/导出接口中,学习时长条件查询重新赋值补全实体类解耦逻辑,避免影响原表数据 2025-12-04 15:03:14 +08:00
yangxinyu
8188427a9a feat:修改完成人数统计错误 2025-12-04 15:03:09 +08:00
yangxinyu
1377f529f1 Reapply "Merge branch '251114-feature-course-online' of https://codeup.aliyun.com/67762337eccfc218f6110e0e/per-boe/java-servers into 251114-feature-course-online"
This reverts commit f506fe49f2.
2025-12-04 15:03:05 +08:00
yangxinyu
3c648b81ed Revert "Merge branch '251114-feature-course-online' of https://codeup.aliyun.com/67762337eccfc218f6110e0e/per-boe/java-servers into 251114-feature-course-online"
This reverts commit 3c582e9ade, reversing
changes made to 716ba91c2e.
2025-12-04 15:03:00 +08:00
yangxinyu
c8588eea72 feat资源学习列表新增content_id 2025-12-04 15:01:07 +08:00
liu.zixi
653d2f6f90 增加配置项 2025-12-04 12:41:30 +08:00
郭诚奇
6703d8aebc feat: 停止当前聊天输出接口功能完善 2025-12-04 11:17:20 +08:00
Jiang Yulong
672d098e52 feat: AI消息点赞/踩/取消点赞/取消踩/问题反馈信息保存 2025-12-04 11:17:15 +08:00
liu.zixi
d38477ff76 feat: 增加批处理,处理元数据异常的旧文档 2025-12-04 11:17:13 +08:00
liu.zixi
81d789b34e fix: 停止会话接口改get 2025-12-04 11:17:10 +08:00
liu.zixi
ae5e5d8d47 fix: 停止会话 2025-12-04 11:17:06 +08:00
liu.zixi
ae00eda79d fix: 服务繁忙的错误处理修正 2025-12-04 11:17:05 +08:00
liu.zixi
96506b9ed8 feat: 增加重新上传的批处理 2025-12-04 11:17:01 +08:00
liu.zixi
57ef4da53b fix: 修复metadata中文乱码的问题 2025-12-04 11:15:19 +08:00
miaowenbo
748335ab8f fix:分页查询课程学习记录以及导出课程学习记录修改时间条件(初版) 2025-12-04 11:14:13 +08:00
miaowenbo
f167196e82 fix:学习记录导出接口补全缺少的空值校验 2025-12-04 11:14:11 +08:00
zhrh
aa9b24de1f szx-1194 审批时邮箱的获取由前端传入改为后端获取 2025-12-03 14:00:03 +08:00
liu.zixi
0ad96cf08e feat: 数据权限确认 2025-12-01 19:59:28 +08:00
yangxinyu
eb3f01d8ac feat:增加查询资源学习列表的contentName字段 2025-12-01 18:32:59 +08:00
miaowenbo
02bb380fd3 fix:修改学习记录查询未开始的查询sql,结合现有数据,筛选item表中状态为1及为null的数据 2025-12-01 14:14:54 +08:00
yangxinyu
7e3037a26c feat:修改导出报名记录接口signType筛选问题 2025-11-29 21:56:59 +08:00
miaowenbo
a4d83bdbdf fix:修复分页查询课程学习记录的时间查询参数空值校验 2025-11-29 21:56:57 +08:00
yangxinyu
be27afbb99 feat:评估学习记录、报名记录查询修改为以报名方式筛选、6类课件学习记录增加content_type字段 2025-11-29 21:56:54 +08:00
miaowenbo
529709f70b fix:修改资源学习记录-考试信息的查询结果,由查询当前课程的所有考试修改为查询当前课程的特定考试 2025-11-29 21:56:52 +08:00
miaowenbo
5f3f78a8e9 fix:修改机构表的获取字段,统一从name修改为分部门级别的namePath字段 2025-11-29 21:56:49 +08:00
miaowenbo
27d0dd8aa3 feat: 资源学习情况导出-作业信息导出接口补全附件和zip导出 2025-11-29 21:55:25 +08:00
miaowenbo
b4e973fa30 feat:查询考试表部分代码逻辑优化 2025-11-29 21:55:23 +08:00
miaowenbo
73d8c8c27e feat: 资源学习情况导出-作业信息初版接口(缺少附件和zip导出) 2025-11-29 21:55:21 +08:00
miaowenbo
7fd3b1ba3c feat:添加资源学习情况导出-考试信息接口,支持导出单个课程单次考试的所有学生信息及考试信息 2025-11-29 21:55:17 +08:00
miaowenbo
2eaaeaa40d feat:补全部分注释,去掉多余日志,补全手动写sql时缺失的item表联表字段(item表id),并赋值到查询数据集合的id字段中 2025-11-29 21:55:16 +08:00
miaowenbo
451d2b4f6a feat:资源学习情况分页查询-考试信息,同时修复原资源学习情况分页查询接口在参数为null时的错误查询结果 2025-11-29 21:55:13 +08:00
liu.zixi
362e802844 fix: 课程列表默认排序,只保留系统创建时长倒排 2025-11-29 21:54:15 +08:00
joshen
b133f23a17 Merge branch 'feature/20251130-hhq' into test1031 2025-11-28 13:54:52 +08:00
liu.zixi
65035b73c1 fix: 完善接口监听逻辑 2025-11-27 15:31:23 +08:00
liu.zixi
1bb068a6ef fix: 日志转储 2025-11-27 15:31:22 +08:00
liu.zixi
1c262f9901 fix: 解决报错 2025-11-27 15:31:17 +08:00
liu.zixi
d48ec42458 fix: 完善错误信息提示的处理方式 2025-11-27 15:31:15 +08:00
liu.zixi
4f7e01363e fix: 课程二维码接口调整逻辑 2025-11-26 19:31:10 +08:00
miaowenbo
f2601f0de2 feat:添加学生章节级别学习记录分页查询接口,并补全学习时长字段 2025-11-26 16:49:29 +08:00
liu.zixi
62a351b0d6 feat: 课程列表分页、导出功能修改 2025-11-26 16:49:25 +08:00
miaowenbo
2f2f70892d feat:查询报名记录分页添加根据报名方式查询逻辑 2025-11-26 16:47:26 +08:00
miaowenbo
025814249f 导出课程学习记录添加用户、状态、时间等查询字段支持 2025-11-26 16:47:24 +08:00
吴季分
32b77bc006 修正重定向地址 2025-11-26 11:01:40 +08:00
joshen
bf5df3de65 解决合并代码时的问题 2025-11-25 21:55:05 +08:00
joshen
9d4c76903e 解决合并代码时的问题 2025-11-25 21:53:22 +08:00
CHINAMI-GR51T7H\EDY
9de38c6fc2 feat:导出报名记录接口、资源学习列表接口 2025-11-25 21:49:14 +08:00
吴季分
40160add45 二维码扫描重定向 2025-11-25 21:47:49 +08:00
miaowenbo
a117f4e38c feat:
1.开始结束时间均传入的情况,实现筛选逻辑(startTime >= 查询开始时间 AND startTime <= 查询结束时间) OR (finishTime >= 查询开始时间 AND finishTime <= 查询结束时间),这样兼容查询结束时间为空值的情况,因为学员课程未结束时没有结束时间
2.和前端沟通组件中有通过组件实现今年以来等筛选逻辑,去掉对应逻辑和枚举类
2025-11-25 21:46:59 +08:00
zhrh
c98ef16549 Merge branch 'refs/heads/SZX-1293-zhrh-20251124' into test1031 2025-11-25 18:47:14 +08:00
zhrh
b9d224b89e Merge branch 'refs/heads/SZX-1293-zhrh-20251124' into test1031 2025-11-25 18:43:01 +08:00
zhrh
c7e9f61609 Merge branch 'refs/heads/SZX-1293-zhrh-20251124' into test1031 2025-11-25 18:22:41 +08:00
zhrh
f1fda24aad Merge branch 'refs/heads/SZX-1293-zhrh-20251124' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java
2025-11-25 17:44:19 +08:00
zhrh
54167efba5 处理空指针 2025-11-25 17:13:56 +08:00
liu.zixi
1bd61e57b1 fix: 报错时也记录 2025-11-25 14:06:19 +08:00
liu.zixi
c3b3ee0db8 fix: 修复ES数据类型解析的问题 2025-11-25 13:32:38 +08:00
joshen
9e66f6a6c1 解决合并代码时的问题 2025-11-25 13:14:53 +08:00
liu.zixi
0470dc1ec8 fix: 修复下载excel接口入参问题 2025-11-25 12:10:01 +08:00
liu.zixi
537801d21d fix: 修复下载excel接口;
增加日志
2025-11-25 11:31:47 +08:00
liu.zixi
d5b280adb7 fix: 增加下载excel接口 2025-11-25 10:58:54 +08:00
liu.zixi
3abe092c06 fix: 上传文档增加限流处理 2025-11-25 10:58:46 +08:00
liu.zixi
d55acb4ff6 fix: 代码修正 2025-11-25 10:58:43 +08:00
liu.zixi
3fbcfb0fd3 fix: 超时异常处理、批处理逻辑修正 2025-11-25 10:58:38 +08:00
liu.zixi
486823e06b 并发数量设置成5 2025-11-25 10:57:17 +08:00
miaowenbo
774c31d9be feat:
1.添加根据课程id得到对应学习记录(包括考试记录)接口
2.修改学习记录中的分数根据考试设置为最新/最高分数
2025-11-24 17:44:11 +08:00
liu.zixi
0ad52cb5d0 fix: page接口增加出参字段isPermission;
page接口显示顺序
2025-11-24 17:44:05 +08:00
miaowenbo
b3ff7ec224 feat:学习进度导出接口添加入参校验,同时添加部门、学习时长字段获取逻辑 2025-11-24 17:43:50 +08:00
liu.zixi
c300433327 fix: controller层代码修正 2025-11-24 15:42:09 +08:00
liu.zixi
0a0086fc1e fix: 课程导出问题修正
继续尝试修正文件名错误的问题
2025-11-24 14:06:57 +08:00
liu.zixi
ad0cf76dfb fix: 课程导出问题修正
修正文件名错误的问题
2025-11-24 13:46:19 +08:00
liu.zixi
6ad97c10c1 fix: 课程导出问题修正
排查空指针问题修正
2025-11-24 13:37:37 +08:00
liu.zixi
280da23089 fix: 课程导出问题修正
排查空指针问题修正
2025-11-24 13:31:23 +08:00
liu.zixi
c7e6eb3322 fix: 课程列表dao层报错修正
排查空指针问题修正
2025-11-24 12:09:16 +08:00
liu.zixi
65bb6ced9c fix: 课程列表dao层报错修正
ResultSet修正
2025-11-24 11:55:27 +08:00
liu.zixi
9a181b35dc fix: 课程列表dao层报错修正
修复timestamp和localDateTime的兼容
2025-11-24 11:50:22 +08:00
liu.zixi
c37b0982e9 fix: 课程列表dao层报错修正
修复id数据类型的问题
2025-11-24 11:42:12 +08:00
liu.zixi
47697ac637 fix: 课程列表dao层报错继续修正 2025-11-24 11:29:55 +08:00
liu.zixi
7e33658a9a fix: 课程列表dao层报错继续修正 2025-11-24 11:24:40 +08:00
liu.zixi
de76804796 fix: 课程列表dao层报错修正 2025-11-24 11:12:19 +08:00
liu.zixi
d33c17a68f feat: 课程列表SQL版
完善了所有查询条件,并完善导出接口
2025-11-24 10:24:36 +08:00
liu.zixi
8e10697163 feat: 课程列表SQL版
完善了所有查询条件,并完善导出接口
2025-11-24 10:24:31 +08:00
miaowenbo
4923de1ad1 feat:添加根据课程id获取对应考试记录接口 2025-11-24 10:24:26 +08:00
miaowenbo
969a6a0513 feat: 解决冲突
1.忽略项目参考文档内容
2.修改excel导出工具类,支持导出动态列excel
3.补全导出课程学习记录接口初版(还缺少部分字段)
4.添加列表查询课程学习记录方法
2025-11-24 10:24:21 +08:00
miaowenbo
e1c97f47f9 feat:添加启动成功提示 2025-11-24 10:20:58 +08:00
liu.zixi
865ac3703d feat: 课程列表相关接口
完善了“查看置顶课程列表”的接口出参格式
2025-11-24 10:20:55 +08:00
joshen
66d2b65d1a Merge branch 'player-20251117' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseAuditApi.java
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseFullTextApi.java
#	servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java
2025-11-21 15:03:04 +08:00
joshen
6f43ae5718 Merge branch 'player-20251117' into test1031 2025-11-21 11:29:10 +08:00
joshen
44b513b75a 合并代码 2025-11-21 11:05:07 +08:00
joshen
b8d66edcd4 Merge branch 'player-20251117' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java
2025-11-21 10:58:56 +08:00
liu.zixi
3e952e89dc feat: 课程列表相关接口
完善了“查看置顶课程列表”、“设置置顶”、“置顶排序”、“导出课程列表”api层、service层逻辑
2025-11-20 16:11:32 +08:00
liu.zixi
f7c872b998 feat: 课程列表相关接口
增加了“查看置顶课程列表”、“设置置顶”、“置顶排序”、“导出课程列表”接口,部分未完成
2025-11-20 16:11:26 +08:00
liu.zixi
4a6efabd07 课程列表管理端新版 2025-11-20 16:11:23 +08:00
joshen
5a12ba3cea Merge branch 'player-20251117' into test1031 2025-11-20 16:06:06 +08:00
joshen
73dbeed3b6 Merge branch 'player-20251117' into test1031 2025-11-20 15:15:39 +08:00
joshen
aed29cfd23 Merge branch 'player-20251117' into test1031 2025-11-20 14:55:32 +08:00
joshen
be0433fc9e Merge branch 'player-20251117' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseFullTextApi.java
2025-11-20 14:14:30 +08:00
670788339
b1a396cf86 Merge remote-tracking branch '121/test1031' into test1031 2025-11-20 10:43:49 +08:00
670788339
f39c26a2de Merge branch 'PingCode-20251117' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/assistance/service/impl/SmtpEmailServiceImpl.java
#	servers/boe-server-all/src/main/java/com/xboe/module/boecase/api/CaseAiChatApi.java
#	servers/boe-server-all/src/main/java/com/xboe/module/boecase/service/impl/CaseKnowledgeServiceImpl.java
#	servers/boe-server-all/src/main/java/com/xboe/module/boecase/task/CaseDocumentLogTask.java
#	servers/boe-server-all/src/main/java/com/xboe/module/boecase/task/CaseUploadTask.java
#	servers/boe-server-all/src/main/resources/application-prod.yml
2025-11-20 10:43:11 +08:00
joshen
fe21a7935b Merge branch 'player-20251117' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/school/study/api/StudyCourseApi.java
2025-11-19 20:10:49 +08:00
joshen
0511032c05 合并代码 2025-11-19 19:19:19 +08:00
joshen
f530597553 合并代码 2025-11-19 19:09:46 +08:00
joshen
228f930a42 Merge branch 'player-20251117' into test1031 2025-11-19 18:17:59 +08:00
joshen
fab976e88d Merge branch 'player-20251117' into test1031 2025-11-19 17:53:59 +08:00
joshen
e0062ccfdb Merge branch 'player-20251117' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseAuditApi.java
#	servers/boe-server-all/src/main/java/com/xboe/school/study/api/StudyCourseApi.java
2025-11-19 17:12:53 +08:00
670788339
1cd8a2aa5d Merge remote-tracking branch '121/test1031' into test1031 2025-11-19 17:06:11 +08:00
670788339
7f0ddf8d98 Merge branch 'merge-20251113-tag' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CoursePortalApi.java
#	servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java
2025-11-19 17:05:41 +08:00
joshen
c264ffc38d Merge branch 'player-20251117' into test1031 2025-11-19 15:29:57 +08:00
joshen
057ea3e03c Merge branch 'player-20251117' into test1031 2025-11-19 14:44:21 +08:00
joshen
1ab107001f Merge branch 'player-20251117' into test1031 2025-11-19 13:32:25 +08:00
joshen
6fdf0ab0ee Merge remote-tracking branch '121/test1031' into test1031 2025-11-19 11:42:44 +08:00
joshen
99af01b70d Merge branch 'player-20251117' into test1031 2025-11-19 11:41:02 +08:00
670788339
1e4990120b 解决报错 2025-11-19 10:36:16 +08:00
670788339
d0d6636ed8 解决报错 2025-11-19 10:29:43 +08:00
670788339
e2c5fa9cd7 调整查询课程tags位置 2025-11-19 10:18:44 +08:00
670788339
1e616f3e55 Merge branch 'player-20251117' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseAuditApi.java
2025-11-19 10:05:55 +08:00
670788339
46aa931024 标签审核日志 2025-11-19 09:59:23 +08:00
670788339
e663c5fd0f 标签审核日志 2025-11-19 09:32:23 +08:00
670788339
f25bb1ea23 Merge branch 'master-20251023-tag' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java
#	servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseTagServiceImpl.java
2025-11-14 14:44:17 +08:00
670788339
a0f6cec0fc 还原在线保存时标签注释 2025-11-14 14:35:01 +08:00
670788339
e2fc783d06 日志 2025-11-14 14:23:43 +08:00
670788339
e8d4cabd04 日志 2025-11-14 14:19:44 +08:00
670788339
7b4a1fdd24 日志 2025-11-14 13:51:17 +08:00
670788339
62374fcebd 日志 2025-11-14 13:28:06 +08:00
670788339
bce9a5d9f1 日志 2025-11-14 13:15:29 +08:00
670788339
146e56ae45 日志 2025-11-14 12:30:58 +08:00
670788339
fd4ce05c96 日志 2025-11-14 11:03:50 +08:00
670788339
fb55098ba4 Merge remote-tracking branch '121/test1031' into test1031 2025-11-14 10:00:27 +08:00
670788339
8371a38738 Merge branch 'master-20251023-tag' into test1031 2025-11-14 10:00:04 +08:00
liu.zixi
1c1ad2d2c1 生产kId变更 2025-11-12 18:30:36 +08:00
liu.zixi
5bde7df40b ai对话错误信息处理2 2025-11-12 18:30:35 +08:00
670788339
71bcfee756 Merge branch 'master-20251023-tag' into test1031 2025-11-12 08:56:08 +08:00
670788339
876dbefbdb 排序调整 2025-11-11 18:34:05 +08:00
670788339
ccc70f142c Merge branch 'master-20251023-tag' into test1031 2025-11-10 18:31:19 +08:00
670788339
2e323ade65 Merge branch 'master-20251023-tag' into test1031 2025-11-10 18:22:28 +08:00
670788339
b65871f6c0 Merge branch 'master-20251023-tag' into test1031 2025-11-10 18:14:19 +08:00
670788339
aa59e8bfe4 Merge branch 'master-20251023-tag' into test1031 2025-11-10 17:52:01 +08:00
670788339
9f2e7807e8 Merge remote-tracking branch '121/test1031' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/entity/Course.java
2025-11-10 17:32:11 +08:00
670788339
a0da2f684f Merge branch 'master-20251023-tag' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java
2025-11-10 17:30:32 +08:00
joshen
5d8d232803 Merge remote-tracking branch 'nyx/test1031' into test1031 2025-11-10 16:51:48 +08:00
xu
37d444800a Merge branch 'refs/heads/release-20250328-master-xc' into test1031 2025-11-10 16:47:49 +08:00
670788339
902c0877dd Merge branch 'master-20251023-tag' into test1031 2025-11-08 15:40:35 +08:00
670788339
57e881da89 Merge remote-tracking branch '121/test1031' into test1031 2025-11-08 15:37:00 +08:00
670788339
56634abd76 Merge branch 'master-20251023-tag' into test1031 2025-11-08 15:23:52 +08:00
joshen
5f39dd69fe Merge remote-tracking branch '121/test1031' into test1031 2025-11-07 14:47:51 +08:00
liu.zixi
cb85982dc6 ai对话错误信息处理 2025-11-07 14:47:25 +08:00
liu.zixi
6e475e4eff 生产环境配置 2025-11-07 14:47:23 +08:00
670788339
8431705f45 Merge remote-tracking branch '121/test1031' into test1031 2025-11-07 11:27:41 +08:00
670788339
3e2c1ef397 Merge branch 'master-20251023-tag' into test1031 2025-11-07 11:26:43 +08:00
liu.zixi
32b996b400 批处理增加入参;
问答增加历史
2025-11-05 16:32:45 +08:00
xu
8ff8703576 【bug:SZX-1155】在线课程管理列表中,增加两列:审核人和审核时间。 2025-11-05 15:50:44 +08:00
670788339
1ebd252759 Merge branch 'master-20251023-tag' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseTagServiceImpl.java
2025-11-05 15:18:59 +08:00
670788339
a9a1f75fb3 Merge branch 'master-20251023-tag' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseTagServiceImpl.java
2025-11-05 14:36:25 +08:00
670788339
1b79b94a9a 日志 2025-11-05 14:21:40 +08:00
670788339
247c3ec5a2 日志 2025-11-05 14:17:20 +08:00
670788339
be3c4e50ad Merge branch 'master-20251023-tag' into test1031 2025-11-05 14:03:36 +08:00
670788339
d5a6595288 Merge remote-tracking branch '121/test1031' into test1031 2025-11-05 13:38:10 +08:00
670788339
c6af21cf32 Merge branch 'master-20251023-tag' into test1031 2025-11-05 13:36:56 +08:00
xu
d5b774a9ad 社招新员工数据迁移。 2025-11-04 15:09:42 +08:00
Caojr
3472378c4f Merge branch '20251103-1282-fix-gj' into test1031 2025-11-04 14:09:36 +08:00
Caojr
1d87e2dc40 Merge branch '20251103-1282-fix-gj' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseFileApi.java
2025-11-04 13:34:03 +08:00
joshen
c76dac6543 Merge remote-tracking branch '121/test1031' into test1031 2025-11-04 08:58:16 +08:00
joshen
371f79366e Merge remote-tracking branch 'nyx/20251031-1279-fix-gj' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java
2025-11-03 18:12:41 +08:00
Caojr
ef6fefe90f Merge remote-tracking branch '测试环境121/test1031' into test1031 2025-11-03 17:54:10 +08:00
Caojr
af0d925b69 Merge branch '20251031-1279-fix-gj' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java
2025-11-03 17:53:55 +08:00
liu.zixi
0bd8b9e9a6 上传文档时url调整为案例详情页 2025-11-03 16:23:05 +08:00
Caojr
694733c3c2 Merge branch '20251103-1282-fix-gj' into test1031 2025-11-03 16:07:26 +08:00
Caojr
d63c8a9de7 Merge branch '20251103-1282-fix-gj' into test1031 2025-11-03 15:39:11 +08:00
Caojr
85455fe771 Merge branch '20251103-1282-fix-gj' into test1031 2025-11-03 15:13:37 +08:00
Caojr
ec6d2e5ac4 Merge remote-tracking branch '测试环境121/test1031' into test1031 2025-11-03 15:07:00 +08:00
Caojr
a2616e8572 Merge branch '20251103-1282-fix-gj' into test1031 2025-11-03 15:06:48 +08:00
liu.zixi
9e31f2b124 上传文档时增加url;
解决文件名错误的问题
2025-11-03 14:49:15 +08:00
liu.zixi
b149d5d697 案例专家对话增加时长记录,增加任务;
上传文档时增加metadata
2025-11-03 13:52:07 +08:00
Caojr
3cff5c9b51 Merge branch '20251103-1282-fix-gj' into test1031 2025-11-03 11:51:39 +08:00
Caojr
bd403c89f0 szx-1283 修改依赖 2025-11-03 11:50:25 +08:00
Caojr
80f06dd495 Merge branch '20251103-1282-fix-gj' into test1031 2025-11-03 11:45:41 +08:00
Caojr
b7f39a28cb Merge branch '20251031-1279-fix-gj' into test1031 2025-11-03 10:59:29 +08:00
670788339
b8223b0e0d Merge branch 'master-20251023-tag' into test1031 2025-11-02 13:53:10 +08:00
670788339
69d4fd9fbb Merge branch 'master-20251023-tag' into test1031 2025-11-02 13:36:12 +08:00
670788339
1199da9a65 Merge branch 'master-20251023-tag' into test1031 2025-11-02 12:54:24 +08:00
670788339
dfc9d8dc90 Merge branch 'master-20251023-tag' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java
2025-11-02 10:34:26 +08:00
670788339
e0fa124a91 Merge branch 'master-20251023-tag' into test1031 2025-11-01 17:28:05 +08:00
670788339
9e70668bca Merge branch 'master-20251023-tag' into test1031 2025-10-31 20:29:56 +08:00
670788339
e715f26c9b Merge branch 'master-20251023-tag' into test1031 2025-10-31 20:09:49 +08:00
670788339
94381ec285 同步 2025-10-31 19:39:20 +08:00
670788339
0d6f4e1a6a Merge branch 'master-20251023-tag' into test1031 2025-10-31 15:32:09 +08:00
670788339
4bbc8b9f9f Merge branch 'master-20251023-tag' into test1031 2025-10-31 15:09:44 +08:00
670788339
8153f6846f Merge branch 'master-20251023-tag' into test1031 2025-10-31 14:50:15 +08:00
670788339
8a93278248 Merge branch 'master-20251023-tag' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseFullTextApi.java
2025-10-31 13:55:32 +08:00
670788339
e7e8a7169f 课程查询日志 2025-10-31 13:17:34 +08:00
670788339
9a862e3d4e 注释多余代码
提交审核时创建标签
2025-10-31 10:53:49 +08:00
670788339
ec6a5a0c07 Merge branch 'refs/heads/master-20251023-tag' into test1031 2025-10-31 10:53:16 +08:00
liu.zixi
8a9648fe57 [DAT] 业务处理挡板只保留更改时上传挡板 2025-10-31 10:45:19 +08:00
liu.zixi
770f467523 [DAT] 配合业务处理挡板 2025-10-31 10:37:28 +08:00
liu.zixi
70a537781c [DAT] 对话接口加新的apiCode 2025-10-31 10:37:27 +08:00
liu.zixi
918d444f36 [DAT] 数据挡板:业务处理失败 2025-10-31 10:37:25 +08:00
liu.zixi
ef28650966 [DAT] 数据挡板:更新时,删除成功新增失败 2025-10-31 10:37:24 +08:00
liu.zixi
8188810f5d [DAT] 重试时根据上一次执行步骤来决定 2025-10-31 10:37:23 +08:00
liu.zixi
ad981eb49d [DAT] 数据挡板:接口调用失败挡板去除 2025-10-31 10:37:21 +08:00
liu.zixi
dae2e29b93 [DAT] 数据挡板:更改时新增失败 2025-10-31 10:37:20 +08:00
liu.zixi
6a73dc60dd [DAT] 数据挡板:新增、删除、更改全挡 2025-10-31 10:37:19 +08:00
liu.zixi
66cbf57387 [DAT] from改为带@的全称 2025-10-31 10:37:18 +08:00
liu.zixi
fafb584213 [DAT] 告警邮件配置 2025-10-31 10:37:17 +08:00
liu.zixi
50cf9fa4fb [DAT] 增加白名单配置 2025-10-31 10:37:15 +08:00
liu.zixi
e4ada3e3c5 [DAT] email更换 2025-10-31 10:37:14 +08:00
liu.zixi
7eb98eece4 [DAT] 去挡板 2025-10-31 10:37:13 +08:00
liu.zixi
c103ea2605 [DAT] 接口失败时,业务状态设为null 2025-10-31 10:37:12 +08:00
liu.zixi
9616c819b3 [DAT] upload时应当为接口失败 2025-10-31 10:37:11 +08:00
liu.zixi
93d5b30489 [DAT] upload加挡板 2025-10-31 10:37:09 +08:00
liu.zixi
cd3bb38390 [DAT] 文档去重 2025-10-31 10:37:08 +08:00
liu.zixi
dab0efb010 [DAT] 显示摘要 2025-10-31 10:37:07 +08:00
liu.zixi
d7acd100b5 [DAT] 去挡板 2025-10-31 10:37:06 +08:00
liu.zixi
abb6cf5516 [DAT] 修复时间错误的问题;尝试修复发邮件 2025-10-31 10:37:04 +08:00
liu.zixi
4fab87998d [DAT] 接口调用失败的数据挡板2 2025-10-31 10:37:03 +08:00
liu.zixi
ceaeda8614 [DAT] 接口调用失败的数据挡板 2025-10-31 10:37:02 +08:00
liu.zixi
636d67165d [DAT] 发邮件增加日志打印 2025-10-31 10:37:01 +08:00
liu.zixi
253eb4ee2e [DAT] 放开重试挡板 2025-10-31 10:36:59 +08:00
liu.zixi
a811b675e7 [DAT] 打日志查看 2025-10-31 10:36:58 +08:00
liu.zixi
1f28daedc5 [DAT] 新增失败时发邮件 2025-10-31 10:36:57 +08:00
liu.zixi
147b74d99c [DAT] 批处理更改responseBody 2025-10-31 10:36:56 +08:00
liu.zixi
4b0a5a8761 [DAT] 去掉com.sun.mail依赖 2025-10-31 10:36:54 +08:00
liu.zixi
b90da03486 [DAT] 发送邮件实现方式再次修改 2025-10-31 10:36:53 +08:00
liu.zixi
4c8e228fa2 [DAT] 发送邮件实现方式修改 2025-10-31 10:36:51 +08:00
liu.zixi
a0a22ead1b [DAT] 调用时间查询逻辑修改 2025-10-31 10:36:50 +08:00
liu.zixi
8a03b3a983 [DAT] 修改update方法调试 2025-10-31 10:36:49 +08:00
liu.zixi
f864e8ba66 [DAT] 删除时修改数据查询条件 2025-10-31 10:36:48 +08:00
liu.zixi
5c4234a3b7 [DAT] 修改update方法只删除不上传的错误 2025-10-31 10:36:46 +08:00
liu.zixi
27c84faa48 [DAT] 照原型数据更新 2025-10-31 10:36:45 +08:00
liu.zixi
0304fc10f1 DAT测试配合 2025-10-31 10:36:44 +08:00
liu.zixi
a12c1f410b 案例专家:增加部分情况下的日志记录 2025-10-31 10:36:42 +08:00
liu.zixi
7b08d26da6 案例专家:修正调用逻辑 2025-10-31 10:36:41 +08:00
liu.zixi
d143ceeb4c 案例专家:新数据处理 2025-10-31 10:36:40 +08:00
liu.zixi
45192a3140 换日志级别,调试 2025-10-31 10:36:38 +08:00
liu.zixi
98f4356a49 延长 Spring Boot 异步请求超时 2025-10-31 10:36:37 +08:00
liu.zixi
8f0b579f6b okhttp的超时时长调到300秒 2025-10-31 10:36:36 +08:00
liu.zixi
6a8a9e5c87 整理es相关代码;增加手动调试用接口 2025-10-31 10:36:34 +08:00
liu.zixi
1898252fc1 案例专家:是否深度思考做成入参,先关闭思考 2025-10-31 10:36:33 +08:00
liu.zixi
cb448a09a3 案例专家:es修改索引格式、添加event-stream专属线程池 2025-10-31 10:36:32 +08:00
liu.zixi
c48c0a0f86 案例专家:yml中的用户列表加双引号 2025-10-31 10:36:31 +08:00
liu.zixi
cb103442e7 案例专家:修改白名单校验逻辑 2025-10-31 10:36:29 +08:00
liu.zixi
24bc40b6ec 案例专家:修改yml文件一个配置的写法 2025-10-31 10:36:28 +08:00
liu.zixi
d75dc2b7b5 案例专家:日志等级修改 2025-10-31 10:36:26 +08:00
liu.zixi
75478cbda7 案例专家:增加手动刷新索引功能 2025-10-31 10:36:25 +08:00
liu.zixi
bf555b1070 案例专家:userId更换成code 2025-10-31 10:36:24 +08:00
liu.zixi
8ae8a650fd 案例专家:userId更换成code 2025-10-31 10:36:23 +08:00
liu.zixi
f7f7a928b2 案例专家:打印入参,调试用 2025-10-31 10:36:22 +08:00
liu.zixi
f465c39b83 案例专家:修改log等级,观察联调 2025-10-31 10:36:20 +08:00
liu.zixi
a2f65a8a29 案例专家:修改批处理问题 2025-10-31 10:36:18 +08:00
liu.zixi
28c3812260 案例专家:邮件告警逻辑 2025-10-31 10:36:17 +08:00
liu.zixi
fa125b29cc 批处理:JobHandler开发 2025-10-31 10:36:15 +08:00
liu.zixi
f35ab10bd2 批处理:JobHandler开发 2025-10-31 10:36:14 +08:00
liu.zixi
d0af06b572 案例助手:代码整理和部分问题修复 2025-10-31 10:36:12 +08:00
liu.zixi
5610289893 案例助手:修复找不到旧会话的bug 2025-10-31 10:36:11 +08:00
liu.zixi
b4103bd4e5 案例助手:聊天接口兼容application/json 2025-10-31 10:36:10 +08:00
liu.zixi
72399eff18 案例助手:增加@Transactional注解 2025-10-31 10:36:08 +08:00
liu.zixi
952301b095 案例助手:增加字段,增加白名单机制等 2025-10-31 10:36:07 +08:00
liu.zixi
0eff0123ca 案例助手:聊天增加上传时间和企业信息 2025-10-31 10:36:05 +08:00
liu.zixi
4d3d4978aa 修复清空日志的bug 2025-10-31 10:36:03 +08:00
liu.zixi
abb036d769 三方接口异步处理 2025-10-31 10:36:02 +08:00
liu.zixi
fe2422574c 返回conversationId 2025-10-31 10:36:00 +08:00
liu.zixi
efe17f3b72 文件读取逻辑纠正 2025-10-31 10:35:58 +08:00
liu.zixi
1aa804118e 修正AI接口的数据入库逻辑 2025-10-31 10:35:56 +08:00
liu.zixi
bd2b372333 修改不同环境回调地址 2025-10-31 10:35:54 +08:00
liu.zixi
8ba8651988 修正编译错误 2025-10-31 10:35:53 +08:00
liu.zixi
ece950fddc 修正编译错误;
增加临时接口
2025-10-31 10:35:52 +08:00
liu.zixi
622c3bdd5b AI调用日志 重试功能补完 2025-10-31 10:35:50 +08:00
liu.zixi
278336c9f7 案例专家功能提交 2025-10-31 10:35:49 +08:00
670788339
264a581df8 Merge branch 'master-20251023-tag' into test1031
# Conflicts:
#	servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java
#	servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java
2025-10-31 10:20:09 +08:00
24 changed files with 966 additions and 453 deletions

View File

@@ -0,0 +1,71 @@
package com.xboe.enums;
import lombok.Getter;
import java.util.Arrays;
import java.util.Objects;
/**
* 学习时长时间筛选状态枚举
* <p>用于筛选学习时长的时间范围条件</p>
*
* @author miaowenbo
* @since 2025-11-24
*/
@Getter
public enum StudyTimeStatusEnum {
/**
* 所有时间范围
*/
STATUS_ALL(0, "所有"),
/**
* 今年以来
*/
STATUS_THIS_YEAR(1, "今年以来"),
/**
* 最近一年
*/
STATUS_LAST_YEAR(2, "最近一年"),
/**
* 最近三个月
*/
STATUS_LAST_THREE_MONTHS(3, "最近三个月"),
/**
* 最近一个月
*/
STATUS_LAST_MONTH(4, "最近一个月"),
/**
* 最近一周
*/
STATUS_LAST_WEEK(5, "最近一周");
private final int code;
private final String label;
/**
* 构造函数
*
* @param code 状态码
* @param label 标签描述
*/
StudyTimeStatusEnum(int code, String label) {
this.code = code;
this.label = label;
}
/**
* 根据状态码获取对应的枚举值
*
* @param code 状态码
* @return 对应的枚举值若未找到则返回默认值STATUS_ALL
*/
public static StudyTimeStatusEnum getByCode(Integer code) {
return Arrays.stream(values()).filter(item -> Objects.equals(item.code, code)).findFirst().orElse(STATUS_ALL);
}
}

View File

@@ -1,7 +1,6 @@
package com.xboe.module.assistance.service.impl;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import javax.mail.Authenticator;
@@ -23,13 +22,12 @@ import com.xboe.module.assistance.service.ISmtpEmailService;
@Slf4j
public class SmtpEmailServiceImpl implements ISmtpEmailService {
//region 默认SMTP服务器配置信息
// SMTP服务器配置信息
private static final String SMTP_HOST = "mail.boe.com.cn";
private static final String SMTP_USERNAME = "boeu_learning@boe.com.cn";
private static final String SMTP_PASSWORD = "boeLms20251112Syse";
private static final String SMTP_PASSWORD = "boeLms20250814Syse";
private static final String SMTP_PORT = "465";
private static final String SMTP_ENCRYPTION = "ssl";
//endregion
@Override
public void sendMailBySmtp(String to, String subject, String htmlMsg, String from) throws Exception {
@@ -45,7 +43,6 @@ public class SmtpEmailServiceImpl implements ISmtpEmailService {
if (StringUtils.isBlank(htmlMsg)) {
throw new Exception("发送邮件失败,未指定邮件内容");
}
// 初始化配置项
// 设置SMTP属性
Properties props = new Properties();

View File

@@ -200,10 +200,7 @@ public class CaseAiChatApi extends ApiBaseController {
try {
String currentUserCode = getCurrent().getCode();
boolean shouldShow = caseAiPermissionService.shouldShowCaseAiEntrance(currentUserCode);
// return success(shouldShow);
JsonResponse<Boolean> result = success(shouldShow);
result.setMessage(currentUserCode);
return result;
return success(shouldShow);
} catch (Exception e) {
log.error("判断案例专家功能入口显示权限异常", e);
return error("判断失败", e.getMessage());

View File

@@ -216,7 +216,6 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
EventSourceListener listener = new EventSourceListener() {
@Override
public void onOpen(@NotNull EventSource eventSource, @NotNull Response response) {
log.info("调用接口 [{}] 接口开始监听", request.url());
// 检查contentType
String contentType = response.header("Content-Type");
if (contentType == null || !contentType.contains("text/event-stream")) {
@@ -258,6 +257,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
eventSource.cancel();
return;
}
log.info("调用接口 [{}] 接口开始监听", request.url());
// 将EventSource存储到Map中以便后续可以中断
conversationEventSourceMap.put(conversationId, eventSource);
}
@@ -375,7 +375,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
// 8. 执行HTTP请求
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(100, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(600, TimeUnit.SECONDS)
.readTimeout(600, TimeUnit.SECONDS)
.callTimeout(600, TimeUnit.SECONDS)

View File

@@ -765,191 +765,186 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService {
}
}
if (StringUtils.equals(cases.getConfidentialityLevel(), "内部")) {
JSONObject requestBody = new JSONObject();
String userId = getCurrentUserId();
requestBody.put("userId", userId);
requestBody.put("kId", caseAiProperties.getCaseKnowledgeId());
requestBody.put("parseType", "AUTO");
// 2. 检查文件路径
if (StringUtil.isBlank(cases.getFilePath())) {
log.error("上传案例文档失败案例文件路径为空caseId: {}", caseId);
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), "上传案例文档失败,案例文件路径为空",
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), null, null);
return false;
}
JSONObject requestBody = new JSONObject();
String userId = getCurrentUserId();
requestBody.put("userId", userId);
requestBody.put("kId", caseAiProperties.getCaseKnowledgeId());
requestBody.put("parseType", "AUTO");
// 2. 检查文件路径
if (StringUtil.isBlank(cases.getFilePath())) {
log.error("上传案例文档失败案例文件路径为空caseId: {}", caseId);
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), "上传案例文档失败,案例文件路径为空",
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), null, null);
return false;
}
String savePath = fileUploader.getSavePath();
String filePath = savePath + cases.getFilePath();
File file = new File(filePath);
if (!file.exists()) {
log.error("上传案例文档失败案例文件不存在filePath: {}", filePath);
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), "上传案例文档失败案例文件不存在filePath: " + filePath,
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), null, null);
return false;
}
String savePath = fileUploader.getSavePath();
String filePath = savePath + cases.getFilePath();
File file = new File(filePath);
if (!file.exists()) {
log.error("上传案例文档失败案例文件不存在filePath: {}", filePath);
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), "上传案例文档失败案例文件不存在filePath: " + filePath,
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), null, null);
return false;
}
// 4. 构建上传参数
String fileName = file.getName();
// 4. 构建上传参数
String fileName = file.getName();
String fileType = getFileType(fileName);
String fileType = getFileType(fileName);
// 5. 重试逻辑最多3次机会
int uploadMaxRetries = 3;
// 5. 重试逻辑最多3次机会
int uploadMaxRetries = 3;
// 构建multipart/form-data请求体
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", file);
builder.addTextBody("userId", userId, ContentType.TEXT_PLAIN);
builder.addTextBody("kId", caseAiProperties.getCaseKnowledgeId(), ContentType.TEXT_PLAIN);
builder.addTextBody("fileName", fileName, ContentType.TEXT_PLAIN);
requestBody.put("fileName", fileName);
builder.addTextBody("fileType", fileType, ContentType.TEXT_PLAIN);
requestBody.put("fileType", fileType);
builder.addTextBody("parseType", "AUTO", ContentType.TEXT_PLAIN);
// 构建multipart/form-data请求体
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", file);
builder.addTextBody("userId", userId, ContentType.TEXT_PLAIN);
builder.addTextBody("kId", caseAiProperties.getCaseKnowledgeId(), ContentType.TEXT_PLAIN);
builder.addTextBody("fileName", fileName, ContentType.TEXT_PLAIN);
requestBody.put("fileName", fileName);
builder.addTextBody("fileType", fileType, ContentType.TEXT_PLAIN);
requestBody.put("fileType", fileType);
builder.addTextBody("parseType", "AUTO", ContentType.TEXT_PLAIN);
String url = caseAiProperties.getCaseDetailUrlBase() + caseId;
requestBody.put("url", url);
String downloadUrl = fileUploader.getHttpPath() + cases.getFilePath();
requestBody.put("downloadUrl", downloadUrl);
builder.addTextBody("url", url, ContentType.TEXT_PLAIN);
builder.addTextBody("downloadUrl", downloadUrl, ContentType.TEXT_PLAIN);
// metadata
JSONObject fileMetaData = new JSONObject();
fileMetaData.put("标题", cases.getTitle());
fileMetaData.put("作者", cases.getAuthorName());
fileMetaData.put("年份", String.valueOf(cases.getSysCreateTime().getYear()));
fileMetaData.put("摘要", cases.getSummary());
// 组织领域orgDomainParent
String orgDomainParent = cases.getOrgDomainParent();
List<DictItem> orgDomainParentItems = sysDictionaryService.findByKey("org_domain");
Optional<DictItem> orgDomainParentItem = orgDomainParentItems.stream()
.filter(item -> StringUtils.equals(orgDomainParent, item.getCode()))
.findFirst();
if (orgDomainParentItem.isPresent()) {
StringBuilder sb = new StringBuilder();
sb.append(orgDomainParentItem.get().getName());
if (StringUtils.isNotBlank(cases.getOrgDomainParent2())) {
Optional<DictItem> orgDomainParent2Item = orgDomainParentItems.stream()
.filter(item -> StringUtils.equals(cases.getOrgDomainParent2(), item.getCode()))
String url = caseAiProperties.getCaseDetailUrlBase() + caseId;
requestBody.put("url", url);
String downloadUrl = fileUploader.getHttpPath() + cases.getFilePath();
requestBody.put("downloadUrl", downloadUrl);
builder.addTextBody("url", url, ContentType.TEXT_PLAIN);
builder.addTextBody("downloadUrl", downloadUrl, ContentType.TEXT_PLAIN);
// metadata
JSONObject fileMetaData = new JSONObject();
fileMetaData.put("标题", cases.getTitle());
fileMetaData.put("作者", cases.getAuthorName());
fileMetaData.put("年份", String.valueOf(cases.getSysCreateTime().getYear()));
fileMetaData.put("摘要", cases.getSummary());
// 组织领域orgDomainParent
String orgDomainParent = cases.getOrgDomainParent();
List<DictItem> orgDomainParentItems = sysDictionaryService.findByKey("org_domain");
Optional<DictItem> orgDomainParentItem = orgDomainParentItems.stream()
.filter(item -> StringUtils.equals(orgDomainParent, item.getCode()))
.findFirst();
if (orgDomainParentItem.isPresent()) {
StringBuilder sb = new StringBuilder();
sb.append(orgDomainParentItem.get().getName());
if (StringUtils.isNotBlank(cases.getOrgDomainParent2())) {
Optional<DictItem> orgDomainParent2Item = orgDomainParentItems.stream()
.filter(item -> StringUtils.equals(cases.getOrgDomainParent2(), item.getCode()))
.findFirst();
orgDomainParent2Item.ifPresent(dictItem -> sb.append(" - ").append(dictItem.getName()));
if (StringUtils.isNotBlank(cases.getOrgDomainParent3())) {
Optional<DictItem> orgDomainParent3Item = orgDomainParentItems.stream()
.filter(item -> StringUtils.equals(cases.getOrgDomainParent3(), item.getCode()))
.findFirst();
orgDomainParent2Item.ifPresent(dictItem -> sb.append(" - ").append(dictItem.getName()));
if (StringUtils.isNotBlank(cases.getOrgDomainParent3())) {
Optional<DictItem> orgDomainParent3Item = orgDomainParentItems.stream()
.filter(item -> StringUtils.equals(cases.getOrgDomainParent3(), item.getCode()))
.findFirst();
orgDomainParent3Item.ifPresent(dictItem -> sb.append(" - ").append(dictItem.getName()));
}
}
fileMetaData.put("组织领域", sb.toString());
}
// 分类majorIds
List<CasesMajorType> cmtList = casesMajorTypeDao.findList(FieldFilters.eq("caseId", cases.getId()));
if (cmtList != null && !cmtList.isEmpty()) {
List<String> majorIds = cmtList.stream().map(CasesMajorType::getMajorId).collect(Collectors.toList());
List<DictItem> majorItems = sysDictionaryService.findByKey("major_type");
if (majorItems != null && !majorItems.isEmpty()) {
List<String> majorNames = majorItems.stream()
.filter(item -> majorIds.contains(item.getCode()))
.map(DictItem::getName)
.collect(Collectors.toList());
fileMetaData.put("组织领域", String.join(", ", majorNames));
orgDomainParent3Item.ifPresent(dictItem -> sb.append(" - ").append(dictItem.getName()));
}
}
fileMetaData.put("组织领域", sb.toString());
}
// 分类majorIds
List<CasesMajorType> cmtList = casesMajorTypeDao.findList(FieldFilters.eq("caseId", cases.getId()));
if (cmtList != null && !cmtList.isEmpty()) {
List<String> majorIds = cmtList.stream().map(CasesMajorType::getMajorId).collect(Collectors.toList());
ContentType contentType = ContentType.create("text/plain", StandardCharsets.UTF_8);
builder.addTextBody("fileMetaData", fileMetaData.toJSONString(), contentType);
requestBody.put("fileMetaData", fileMetaData);
// 由于接口权限,目前采用不回调,而是通过批处理的方式,处理文件状态
if (caseAiProperties.isFileUploadUseCallback()) {
builder.addTextBody("callbackUrl", caseAiProperties.getFileUploadCallbackUrl(), ContentType.TEXT_PLAIN);
requestBody.put("callbackUrl", caseAiProperties.getFileUploadCallbackUrl());
List<DictItem> majorItems = sysDictionaryService.findByKey("major_type");
if (majorItems != null && !majorItems.isEmpty()) {
List<String> majorNames = majorItems.stream()
.filter(item -> majorIds.contains(item.getCode()))
.map(DictItem::getName)
.collect(Collectors.toList());
fileMetaData.put("组织领域", String.join(", ", majorNames));
}
}
String uploadUrl = caseAiProperties.getBaseUrl() + "/apigateway/knowledge/v1/file/upload";
ContentType contentType = ContentType.create("text/plain", StandardCharsets.UTF_8);
builder.addTextBody("fileMetaData", fileMetaData.toJSONString(), contentType);
requestBody.put("fileMetaData", fileMetaData);
// 由于接口权限,目前采用不回调,而是通过批处理的方式,处理文件状态
if (caseAiProperties.isFileUploadUseCallback()) {
builder.addTextBody("callbackUrl", caseAiProperties.getFileUploadCallbackUrl(), ContentType.TEXT_PLAIN);
requestBody.put("callbackUrl", caseAiProperties.getFileUploadCallbackUrl());
}
// 3. 获取access_token
String accessToken = aiAccessTokenService.getAccessToken();
if (StringUtil.isBlank(accessToken)) {
log.error("上传案例文档失败获取access_token失败");
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), "上传案例文档失败获取access_token失败",
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), null, null);
return false;
}
for (int attempt = 1; attempt <= uploadMaxRetries; attempt++) {
log.info("上传案例文档第{}次尝试caseId: {}", attempt, caseId);
String uploadUrl = caseAiProperties.getBaseUrl() + "/apigateway/knowledge/v1/file/upload";
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(uploadUrl);
httpPost.setHeader("X-AI-ApiCode", caseAiProperties.getAiApiCode());
httpPost.setHeader("access_token", accessToken);
// 3. 获取access_token
String accessToken = aiAccessTokenService.getAccessToken();
if (StringUtil.isBlank(accessToken)) {
log.error("上传案例文档失败,获取access_token失败");
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), "上传案例文档失败获取access_token失败",
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), null, null);
return false;
}
for (int attempt = 1; attempt <= uploadMaxRetries; attempt++) {
log.info("上传案例文档第{}次尝试caseId: {}", attempt, caseId);
HttpEntity multipart = builder.build();
httpPost.setEntity(multipart);
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(uploadUrl);
httpPost.setHeader("X-AI-ApiCode", caseAiProperties.getAiApiCode());
httpPost.setHeader("access_token", accessToken);
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
int statusCode = response.getStatusLine().getStatusCode();
String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
HttpEntity multipart = builder.build();
httpPost.setEntity(multipart);
if (statusCode == 200) {
JSONObject result = JSON.parseObject(responseBody);
if (result.getBooleanValue("success")) {
// 业务处理成功
JSONObject data = result.getJSONObject("data");
String taskId = data.getString("taskId");
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
int statusCode = response.getStatusLine().getStatusCode();
String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
// 保存成功的CaseDocumentLog记录
if (statusCode == 200) {
JSONObject result = JSON.parseObject(responseBody);
if (result.getBooleanValue("success")) {
// 业务处理成功
JSONObject data = result.getJSONObject("data");
String taskId = data.getString("taskId");
// 保存成功的CaseDocumentLog记录
// saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
// requestBody.toJSONString(), responseBody,
// CaseDocumentLogRunStatusEnum.RUNNING.getCode(), null, null, taskId);
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), responseBody,
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.SUCCESS.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), taskId);
log.info("上传案例文档成功,等待文档状态变更. caseId: {}, taskId: {}, 尝试次数: {}", caseId, taskId, attempt);
return true;
} else {
// 业务处理失败,不重试
log.error("上传案例文档业务处理失败不重试response: {}", responseBody);
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), responseBody,
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.SUCCESS.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null);
return false;
}
} else {
// 接口调用失败
log.error("上传案例文档接口调用失败,第{}次尝试status: {}, response: {}", attempt, statusCode, responseBody);
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), responseBody,
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), null, null);
if (attempt == uploadMaxRetries) {
// 最后一次尝试仍然失败
return false;
}
// 继续下一次重试
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.SUCCESS.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), taskId);
log.info("上传案例文档成功,等待文档状态变更. caseId: {}, taskId: {}, 尝试次数: {}", caseId, taskId, attempt);
return true;
} else {
// 业务处理失败,不重试
log.error("上传案例文档业务处理失败不重试response: {}", responseBody);
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), responseBody,
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.SUCCESS.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null);
return false;
}
} else {
// 接口调用失败
log.error("上传案例文档接口调用失败,第{}次尝试status: {}, response: {}", attempt, statusCode, responseBody);
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), responseBody,
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), null, null);
if (attempt == uploadMaxRetries) {
// 最后一次尝试仍然失败
return false;
}
// 继续下一次重试
}
} catch (Exception e) {
// 接口调用异常
log.error("上传案例文档接口调用异常,第{}次尝试", attempt, e);
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), "接口调用异常: " + e.getMessage(),
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), null, null);
if (attempt == uploadMaxRetries) {
// 最后一次尝试仍然异常
log.error("上传案例文档最终失败,已重试{}次", uploadMaxRetries);
return false;
}
// 继续下一次重试
}
} catch (Exception e) {
// 接口调用异常
log.error("上传案例文档接口调用异常,第{}次尝试", attempt, e);
saveCaseDocumentLog(caseId, cases.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), CaseAiConstants.CASE_DOC_UPLOAD_INTERFACE_NAME,
requestBody.toJSONString(), "接口调用异常: " + e.getMessage(),
CaseDocumentLogRunStatusEnum.COMPLETED.getCode(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), null, null);
if (attempt == uploadMaxRetries) {
// 最后一次尝试仍然异常
log.error("上传案例文档最终失败,已重试{}次", uploadMaxRetries);
return false;
}
// 继续下一次重试
}
} else {
log.info("非【内部】密级案例,不进行上传");
return true;
}
return false;
@@ -1033,7 +1028,7 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService {
@Override
public void batchCheckFileStatus() {
// log.info("开始批量检查文件状态");
log.info("开始批量检查文件状态");
// 1. 查询CaseDocumentLog表中前10条run_status等于0的数据并按创建时间升序排序
PageList<CaseDocumentLog> runningLogPage = caseDocumentLogDao.getGenericDao()
@@ -1043,11 +1038,11 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService {
// 2. 如果没有符合条件的数据,完成
if (runningLogs == null || runningLogs.isEmpty()) {
// log.info("没有需要检查状态的文档,批量检查完成");
log.info("没有需要检查状态的文档,批量检查完成");
return;
}
// log.info("找到{}条需要检查状态的文档记录", runningLogs.size());
log.info("找到{}条需要检查状态的文档记录", runningLogs.size());
// 3. 把这些数据的taskId聚合成一个List<String>
List<String> taskIds = runningLogs.stream()
@@ -1057,11 +1052,11 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService {
.collect(java.util.stream.Collectors.toList());
if (taskIds.isEmpty()) {
// log.error("所有运行中的记录都没有有效的taskId");
log.error("所有运行中的记录都没有有效的taskId");
return;
}
// log.info("需要检查状态的taskId数量: {}", taskIds.size());
log.info("需要检查状态的taskId数量: {}", taskIds.size());
// 4. 获取access_token
String accessToken = aiAccessTokenService.getAccessToken();
@@ -1101,7 +1096,7 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService {
log.error("批量检查文件状态异常", e);
}
// log.info("批量检查文件状态完成");
log.info("批量检查文件状态完成");
}
/**
@@ -1369,7 +1364,7 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService {
caseLog.setCaseStatus(CaseDocumentLogCaseStatusEnum.SUCCESS.getCode());
caseLog.setMetadataStatus(1);
needUpdate = true;
// log.info("文档向量化成功更新状态taskId: {}, caseId: {}", caseLog.getTaskId(), caseLog.getCaseId());
log.info("文档向量化成功更新状态taskId: {}, caseId: {}", caseLog.getTaskId(), caseLog.getCaseId());
} else if ("failed".equals(fileStatus)) {
// 状态为failedrun_status、opt_status变更为1case_status变更为2
caseLog.setRunStatus(CaseDocumentLogRunStatusEnum.COMPLETED.getCode());
@@ -1377,20 +1372,20 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService {
caseLog.setCaseStatus(CaseDocumentLogCaseStatusEnum.FAILED.getCode());
needUpdate = true;
needToSendEmail = true;
// log.error("文档处理失败需要发送邮件更新状态taskId: {}, caseId: {}", caseLog.getTaskId(), caseLog.getCaseId());
log.error("文档处理失败需要发送邮件更新状态taskId: {}, caseId: {}", caseLog.getTaskId(), caseLog.getCaseId());
} else {
// 其他状态uploaded、texted、vectoring不做数据变更
// log.info("文档状态为{}暂不更新数据库taskId: {}", fileStatus, caseLog.getTaskId());
log.info("文档状态为{}暂不更新数据库taskId: {}", fileStatus, caseLog.getTaskId());
}
// 如果需要更新执行update操作
if (needUpdate) {
caseLog.setSysUpdateTime(LocalDateTime.now());
caseDocumentLogDao.save(caseLog);
// log.info("更新CaseDocumentLog成功logId: {}, taskId: {}, fileStatus: {}",
// caseLog.getId(), caseLog.getTaskId(), fileStatus);
// } else {
// log.info("无需更新CaseDocumentLogtaskId: {}, fileStatus: {}", caseLog.getTaskId(), fileStatus);
log.info("更新CaseDocumentLog成功logId: {}, taskId: {}, fileStatus: {}",
caseLog.getId(), caseLog.getTaskId(), fileStatus);
} else {
log.info("无需更新CaseDocumentLogtaskId: {}, fileStatus: {}", caseLog.getTaskId(), fileStatus);
}
} catch (Exception e) {
log.error("更新日志状态异常taskId: {}, fileStatus: {}", caseLog.getTaskId(), fileStatus, e);
@@ -1407,7 +1402,7 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService {
// 使用配置的收件人列表
List<String> recipients = caseAiProperties.getAlertEmailRecipients();
// log.info("使用配置的收件人列表:{}", recipients);
log.info("使用配置的收件人列表:{}", recipients);
if (recipients != null && !recipients.isEmpty()) {
try {
String to = String.join(",", recipients);

View File

@@ -20,8 +20,8 @@ public class CaseDocumentLogTask {
*/
@XxlJob("batchCheckFileStatusJob")
public void batchCheckFileStatusJob() {
// log.info("开始批量查询文件状态");
log.info("开始批量查询文件状态");
caseKnowledgeService.batchCheckFileStatus();
// log.info("结束批量查询文件状态");
log.info("结束批量查询文件状态");
}
}

View File

@@ -18,6 +18,7 @@ import com.xboe.module.course.service.*;
import com.xboe.module.course.dto.*;
import com.xboe.module.course.entity.*;
import com.xboe.module.course.utils.HttpUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
@@ -26,7 +27,6 @@ import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -359,6 +359,8 @@ public class CourseAuditApi extends ApiBaseController{
return badRequest("无审核结果信息");
}
Course c=courseService.get(courseId);
log.info("-- hrbp-submit-audit 提交审核 -- " + c );
log.info("-- hrbp-submit-audit 提交审核 tags-- " + c.getTags() );
if(c==null) {
return badRequest("课程不存在");
}
@@ -377,7 +379,9 @@ public class CourseAuditApi extends ApiBaseController{
try {
CurrentUser cu=getCurrent();
service.hrbpSubmitAudit(auditId, courseId,open, pass,cu.getAccountId(),cu.getName(), remark);
log.info("-- hrbpSubmitAudit 提交审核 tags-- " + c.getTags() );
Course cc=courseService.get(courseId);
log.info("-- hrbpSubmitAudit 提交审核 tags-- " + cc.getTags() );
if (pass){
//修改在线课开课状态=已开课
String token = request.getHeader("Xboe-Access-Token");
@@ -387,6 +391,9 @@ public class CourseAuditApi extends ApiBaseController{
param.setOrgName(c.getOrgName());
thirdApi.updateOrSaveCourse(param,token);
}
log.info("-- updateOrSaveCourse 提交审核 tags-- " + c.getTags() );
Course ccc=courseService.get(courseId);
log.info("-- updateOrSaveCourse 提交审核 tags-- " + ccc.getTags() );
return success(true);
} catch (Exception e) {
log.error("HRBP审核提交处理错误",e);
@@ -492,14 +499,16 @@ public class CourseAuditApi extends ApiBaseController{
log.info("aiSet:"+course.getAiSet()+",aiAbstract:"+course.getAiAbstract()+",aiDraft:"+course.getAiDraft()+",aiTranslate:"+course.getAiTranslate()+",languageCode:"+course.getLanguageCode());
List<CourseTeacher> teachers = dto.getTeachers();
StringBuilder teacherNames = new StringBuilder();
if(!CollectionUtils.isEmpty(teachers)){
if(teachers != null){
for (CourseTeacher teacher : teachers) {
teacherNames.append(teacher.getTeacherName()).append(",");
}
}
log.info("---------------courseID= "+course.getId());
log.info("-----------ccontentService:"+ccontentService);
List<CourseContent> cclist = ccontentService.getByCourseId(course.getId());
List<String> languageCode = course.getLanguageCode();
String code = String.join(",", languageCode);
String code = languageCode == null ? "" : String.join(",", languageCode);
List<BoeaiCourseDto> courseDtos = new ArrayList<>();
BoeaiCourseDto boeaiCourseDto = new BoeaiCourseDto();
List<BoeaiVideoResourceDto> videoList = new ArrayList<>();

View File

@@ -14,10 +14,10 @@ import com.boe.feign.api.serverall.entity.UserData;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.xboe.api.ThirdApi;
import com.xboe.data.outside.IOutSideDataService;
import com.xboe.module.course.entity.CourseTag;
import com.xboe.module.course.service.*;
import com.xboe.module.course.dto.BoeaiCourseDto;
import com.xboe.module.course.utils.HttpUtils;
import com.xboe.module.course.entity.CourseTag;
import com.xboe.module.course.service.*;
import com.xboe.module.course.vo.TeacherVo;
import com.xboe.school.study.entity.StudyCourse;
import com.xboe.school.study.service.IStudyCourseService;
@@ -46,7 +46,7 @@ import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
//课程AI设置
@Slf4j
@RestController
@RequestMapping(value="/xboe/m/course/fulltext")
@@ -82,8 +82,6 @@ public class CourseFullTextApi extends ApiBaseController{
@Value("${kjb.aicoreUrl}")
private String aicoreUrl;
/**
* 课程的初始化
* @return
@@ -441,9 +439,11 @@ public class CourseFullTextApi extends ApiBaseController{
c.setKeywordsList(keywordsList);
}
}
if (StringUtils.isNotBlank(c.getTags()) && c.getTags().matches("[0-9,]+")) {
log.info("课程查询接口 getTags = " + c.getTags());
if (StringUtils.isNotBlank(c.getTags()) && c.getTags().matches("[0-9,]+")) {
List<CourseTag> tagList = courseTagService.getTagsByIds(c.getTags());
List<String> tags = tagList.stream().map(CourseTag::getTagName).collect(Collectors.toList());
log.info("课程查询接口 Tags = " + tags);
c.setTagsList(tags);
}

View File

@@ -18,11 +18,10 @@ import com.xboe.api.vo.UserBasicInfoVo;
import com.xboe.module.course.dto.*;
import com.xboe.module.course.entity.*;
import com.xboe.module.course.service.*;
import com.xboe.module.course.vo.CoursePageVo;
import org.apache.commons.collections4.CollectionUtils;
import com.xboe.module.course.vo.CoursePageVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.parameters.P;
import org.springframework.web.bind.annotation.GetMapping;
@@ -42,6 +41,19 @@ import com.xboe.data.dto.UserOrgIds;
import com.xboe.data.outside.IOutSideDataService;
import com.xboe.data.service.IDataUserSyncService;
import com.xboe.module.assistance.service.IEmailService;
import com.xboe.module.course.entity.Course;
import com.xboe.module.course.entity.CourseContent;
import com.xboe.module.course.entity.CourseCrowd;
import com.xboe.module.course.entity.CourseHRBPAudit;
import com.xboe.module.course.entity.CourseSection;
import com.xboe.module.course.entity.CourseTeacher;
import com.xboe.module.course.entity.CourseUpdateLog;
import com.xboe.module.course.service.ICourseContentService;
import com.xboe.module.course.service.ICourseCrowdService;
import com.xboe.module.course.service.ICourseHRBPAuditService;
import com.xboe.module.course.service.ICourseSectionService;
import com.xboe.module.course.service.ICourseService;
import com.xboe.module.course.service.ICourseTeacherService;
import com.xboe.module.excel.ExportsExcelSenderUtil;
import com.xboe.standard.enums.BoedxContentType;
import com.xboe.standard.enums.BoedxCourseType;
@@ -99,7 +111,6 @@ public class CourseManageApi extends ApiBaseController{
private ICourseTagService tagService;
@Resource
IOutSideDataService outSideDataService;
@Autowired
IDataUserSyncService userSyncService;
@Resource
@@ -110,7 +121,6 @@ public class CourseManageApi extends ApiBaseController{
@Resource
CourseFullTextApi courseFullTextApi;
@Value("${boe.pcPageUrl}")
private String pcPageUrl;
@@ -123,6 +133,8 @@ public class CourseManageApi extends ApiBaseController{
@Value("${boe.pcLoginUrl}")
private String pcLoginUrl;
// @PostMapping("/test")
// public JsonResponse<PageList<Course>> findTest(Pagination pager,CourseQueryDto dto){
// //dto.setOrgAid("7003708665807110150");
@@ -196,6 +208,7 @@ public class CourseManageApi extends ApiBaseController{
public void manageExport(CoursePageQueryDTO coursePageQueryDTO, HttpServletResponse response) {
coursePageService.exportCourseList(coursePageQueryDTO, response);
}
/**
* 管理列表的查询
* @param pager
@@ -248,13 +261,36 @@ public class CourseManageApi extends ApiBaseController{
public void fullAuditInfo(List<Course> list){
List<String> courseIdList = list.stream().map(Course::getId).collect(Collectors.toList());
List<CourseHRBPAudit> auditList = hrbpAuditService.listByCourseIds(courseIdList);
Map<String,CourseHRBPAudit> map = auditList.stream().collect(Collectors.toMap(CourseHRBPAudit::getCourseId, i->i));
Map<String,CourseHRBPAudit> map = new HashMap<>();
for(CourseHRBPAudit audit : auditList){
CourseHRBPAudit r = map.get(audit.getCourseId());
//可能存在多个审核记录,取时间最新的那一条
if(r == null || r.getAddTime().isBefore(audit.getAddTime())){
map.put(audit.getCourseId(),audit);
}
}
list.forEach(item ->{
CourseHRBPAudit audit = map.get(item.getId());
if(audit != null){
//暂时获取这两个字段,之后看是否需要调整
item.setAuditUser(audit.getAuditUser());
item.setAuditTime(audit.getAuditTime());
//公开课审核完成取公开课的审核信息
if(StringUtils.isNotEmpty(audit.getLastAname())){
item.setAuditUser(audit.getLastAname());
item.setAuditTime(audit.getLastTime());
}else if(CourseHRBPAudit.FORWARD_TEACHER == audit.getForward()){
//转发到教师审核取教师审核信息
item.setAuditUser(audit.getToName());
}else if (CourseHRBPAudit.FORWARD_TO_FINISH == audit.getForward()){
//老师审核完成
item.setAuditUser(audit.getAuditUser());
if(CourseHRBPAudit.STATUS_NOPASS ==audit.getStatus()){
//老师审核不通过时取老师的审核时间
item.setAuditTime(audit.getToAuditTime());
}
}else {
item.setAuditUser(audit.getAuditUser());
item.setAuditTime(audit.getAuditTime());
}
}
});
@@ -314,6 +350,7 @@ public class CourseManageApi extends ApiBaseController{
return success(rs);
}
@GetMapping("/getDictIds")
public JsonResponse<Map<String,Object>> getDictIds(Long pid,Integer type){
CommonSearchVo searcher = new CommonSearchVo();
@@ -467,9 +504,8 @@ public class CourseManageApi extends ApiBaseController{
fillCourseData(dto.getCourse());
courseService.save(dto);
}else {
// 20251215lzx编辑基本信息不提交状态让前端课程可以继续查看
//修改后重置,重新提交审核,重新发布
// dto.getCourse().setPublished(false);
dto.getCourse().setPublished(false);
dto.getCourse().setStatus(Course.STATUS_NONE);
courseService.update(dto);
}
@@ -726,9 +762,8 @@ public class CourseManageApi extends ApiBaseController{
//设置为提交状态
dto.getCourse().setStatus(Course.STATUS_SUBMIT);
// 20251217lzx 提交审核时不改变状态
// dto.getCourse().setEnabled(true);//设置启用状态问题
// dto.getCourse().setPublished(false);//重新提交审核设置为未发布状态
dto.getCourse().setEnabled(true);//设置启用状态问题
dto.getCourse().setPublished(false);//重新提交审核设置为未发布状态
courseService.submit(dto);
//提交成功发邮件提醒
try {
@@ -1045,7 +1080,6 @@ public class CourseManageApi extends ApiBaseController{
*/
@PostMapping("/top")
public JsonResponse<Boolean> setTop(String ids,String title, Boolean top){
// lzx这个ids实际上只有一个id。。。
if(StringUtils.isBlank(ids)){
return badRequest("参数错误");
}
@@ -1054,14 +1088,8 @@ public class CourseManageApi extends ApiBaseController{
}
try {
// courseService.setTop(ids, top,getCurrent().getAccountId(), title,"");
// return success(true);
// 调整置顶逻辑
ServiceResponse<Boolean> serviceResponse = coursePageService.top(ids, top);
if (!serviceResponse.isSuccess()) {
return error(serviceResponse.getMessage());
}
return success(serviceResponse.getData());
courseService.setTop(ids, top,getCurrent().getAccountId(), title,"");
return success(true);
} catch (Exception e) {
log.error("课程设置置顶错误",e);
return error("设置置顶失败",e.getMessage(),false);
@@ -1423,40 +1451,4 @@ public class CourseManageApi extends ApiBaseController{
courseService.saveTip(aid);
return success(true);
}
/**
* 扫描二维码重定向
* @param courseId 课程id
* @param request
* @param response
* @throws IOException
*/
@GetMapping("/redirectDetail")
public void redirectDetail(
@NotNull Long courseId,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
boolean isMobile = UserAgentUtil.parse(request.getHeader(Header.USER_AGENT.toString())).isMobile();
String baseUrl = isMobile ? h5PageUrl : pcPageUrl;
// String loginUrl = isMobile ? h5LoginUrl : pcLoginUrl;
//
// CurrentUser currentUser;
// try {
// currentUser = getCurrent();
// } catch (Exception e) {
// log.warn("获取当前用户信息异常跳转至登录页。课程ID: {}", courseId, e);
// response.sendRedirect(loginUrl);
// return;
// }
//
// if (currentUser == null) {
// log.info("用户未登录跳转至登录页。课程ID: {}", courseId);
// response.sendRedirect(loginUrl);
// return;
// }
log.info("跳转到课程详情页课程ID: {}", courseId);
response.sendRedirect(baseUrl + courseId);
}
}

View File

@@ -442,19 +442,22 @@ public class Course extends BaseEntity {
@Transient
private String teacher;
/**审核人名称(列表展示用)*/
@Transient
private String auditUser;
/**审核时间(列表展示用)*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Transient
private LocalDateTime auditTime;
/**
* 新增在线课时是否需要标签提示
*/
@Transient
private Boolean isTip;
@Transient
private String auditUser;
@Transient
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime auditTime;
/**
* 课程时长(秒)
*/

View File

@@ -2,6 +2,7 @@ package com.xboe.module.course.entity;
import com.xboe.core.SysConstant;
import com.xboe.core.orm.BaseEntity;
import com.xboe.module.course.dto.BoeaiSubtitleRsp;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -9,14 +10,6 @@ import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.xboe.core.SysConstant;
import com.xboe.core.orm.BaseEntity;
import com.xboe.module.course.dto.BoeaiSubtitleRsp;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
@@ -102,9 +95,6 @@ public class CourseContent extends BaseEntity {
@Transient
private Integer status;
@Transient
List<BoeaiSubtitleRsp> boeaiSubtitleRspList;
/**
* 展示名称(章名+节名,如果没有章节,则为课程名+节名)
* 25.12.15新增
@@ -112,6 +102,9 @@ public class CourseContent extends BaseEntity {
@Transient
private String displayName;
@Transient
List<BoeaiSubtitleRsp> boeaiSubtitleRspList;
public CourseContent() {
}

View File

@@ -2,6 +2,7 @@ package com.xboe.module.course.service;
import java.util.List;
import java.util.Map;
import com.xboe.common.PageList;
import com.xboe.module.course.dto.CourseHRBPAuditDto;
@@ -56,7 +57,12 @@ public interface ICourseHRBPAuditService {
*/
PageList<CourseHRBPAudit> pageList(Integer pageIndex, Integer pageSize,int userType, CourseHRBPAudit info);
List<CourseHRBPAudit> listByCourseIds(List<String> courseIdList);
/**
* 查询一组课程的最近一次审核记录返回键为courseId的映射。
*/
Map<String, CourseHRBPAudit> findLatestByCourseIds(List<String> courseIds);
}

View File

@@ -1,7 +1,9 @@
package com.xboe.module.course.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
@@ -263,7 +265,31 @@ public class CourseHRBPAuditServiceImpl implements ICourseHRBPAuditService {
return courseHRBPAuditDao.get(id);
}
@Override
public Map<String, CourseHRBPAudit> findLatestByCourseIds(List<String> courseIds) {
Map<String, CourseHRBPAudit> result = new HashMap<String, CourseHRBPAudit>();
if (courseIds == null || courseIds.isEmpty()) {
return result;
}
try {
// 按 addTime 倒序使首次出现的courseId即为该课程的最近一条审核记录
List<CourseHRBPAudit> audits = courseHRBPAuditDao.findList(
OrderCondition.desc("addTime"),
FieldFilters.in("courseId", courseIds)
);
for (CourseHRBPAudit a : audits) {
if (!result.containsKey(a.getCourseId())) {
result.put(a.getCourseId(), a);
}
}
} catch (Exception e) {
log.error("批量查询课程审核记录错误", e.getMessage());
}
return result;
}
public List<CourseHRBPAudit> listByCourseIds(List<String> courseIdList){
return courseHRBPAuditDao.findList(FieldFilters.in("courseId",courseIdList));
}
}

View File

@@ -18,27 +18,29 @@ import javax.management.Query;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
//import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
//import com.alibaba.fastjson2.JSON;
//import cn.hutool.json.JSONUtil;
import com.xboe.api.ThirdApi;
import com.xboe.core.orm.*;
import com.xboe.enums.CourseAuditTypeEnum;
import com.xboe.module.course.dao.*;
import com.xboe.module.course.dto.*;
import com.xboe.module.course.entity.*;
import com.xboe.module.course.utils.HttpUtils;
import com.xboe.module.course.dao.*;
import com.xboe.module.course.entity.*;
import com.xboe.module.course.dto.CourseTagRelationDto;
import com.xboe.module.course.entity.*;
import com.xboe.module.course.service.ICourseHRBPAuditService;
import com.xboe.module.course.service.ICourseTagService;
import com.xboe.module.course.utils.HttpUtils;
import com.xboe.school.study.dao.StudyCourseDao;
import com.xboe.school.study.entity.StudyCourse;
import org.apache.commons.lang3.StringUtils;
@@ -133,8 +135,6 @@ public class CourseServiceImpl implements ICourseService {
@Resource
RestHighLevelClient restHighLevelClient;
@Resource
private TipDao tipDao;
@Resource
private CourseTeacherDeletedRecordDao courseTeacherDeletedRecordDao;
@@ -145,6 +145,10 @@ public class CourseServiceImpl implements ICourseService {
@Value("${kjb.aicoreUrl}")
private String aicoreUrl;
@Resource
private TipDao tipDao;
/**
* 生成过滤条件
*
@@ -439,12 +443,15 @@ public class CourseServiceImpl implements ICourseService {
}
Set<String> seache = getSeache(dto);
//查出全部的课程
log.info("-------hhh-dto为" + dto);
List<Course> listByFilters2 = courseDao.findListByFilters(oc, filters2);
log.info("*************listByFilters2为" + listByFilters2);
if (TempFilterConfig.Manager_CourseFile_ByOrgIds) {
if (dto.getIsSystemAdmin() == null || !dto.getIsSystemAdmin()) {
List<String> finalStrings = strings;
log.info("dto为" + dto);
if (dto.getIsCreateCourse() != null && dto.getIsCreateCourse()) {
log.info("-----111------" + "---------111---------");
listByFilters2.removeIf(e -> {
//去掉未发布的课程
if (!e.getPublished() && seache.contains(e.getId()) && !finalStrings.contains(e.getOrgId()) && !dto.getOrgAid().equals(e.getSysCreateAid())) {
@@ -458,36 +465,30 @@ public class CourseServiceImpl implements ICourseService {
});
//将需要隐藏的做标记
listByFilters2.forEach(e -> {
if ((seache.contains(e.getId()) || dto.getReadIds().contains(e.getOrgId())) && !finalStrings.contains(e.getOrgId()) && !dto.getOrgAid().equals(e.getSysCreateAid())) {
if ((seache.contains(e.getId())||dto.getReadIds().contains(e.getOrgId())) && !finalStrings.contains(e.getOrgId()) && !dto.getOrgAid().equals(e.getSysCreateAid())) {
e.setIsPermission(false);
} else {
e.setIsPermission(true);
}
});
listByFilters2.sort(Comparator.comparing(Course::getIsPermission).reversed());
} else {
List<Course> collect = listByFilters2.stream().filter(e -> dto.getReadIds().contains(e.getOrgId()) || dto.getOrgAid().equals(e.getSysCreateAid()) || finalStrings.contains(e.getOrgId())).collect(Collectors.toList());
}else{
log.info("-----222------" + "---------222---------");
List<Course> collect = listByFilters2.stream().filter(e ->dto.getReadIds().contains(e.getOrgId())||dto.getOrgAid().equals(e.getSysCreateAid())||finalStrings.contains(e.getOrgId())).collect(Collectors.toList());
List<Course> paginate = paginate(collect, pageIndex, pageSize);
PageList<Course> rs = new PageList<>();
rs.setCount(collect.size());
rs.setList(paginate);
//log.info("78888888888888888888 "+paginate.isEmpty());
if (paginate != null && !paginate.isEmpty()) {
log.info("-----KJB------ getCourse");
for (Course course : paginate) {
this.getCourseFromKJB(course);
}
}
return rs;
}
}
}
log.info("-----333------" + "---------333---------");
List<Course> paginate = paginate(listByFilters2, pageIndex, pageSize);
PageList<Course> rs = new PageList<>();
rs.setCount(listByFilters2.size());
rs.setPageSize(pageSize);
rs.setList(paginate);
if (paginate != null && !paginate.isEmpty()) {
log.info("-----KJB------ getCourse");
for (Course course : paginate) {
@@ -555,7 +556,7 @@ public class CourseServiceImpl implements ICourseService {
String sql = "SELECT DISTINCT\n" +
"rt.course_id\n" +
"FROM\n" +
"boe_new.student s INNER JOIN boe_new.router_task rt on s.pid=rt.router_id inner join boe_course c on c.id=rt.course_id\n" +
"boe.student s INNER JOIN boe.router_task rt on s.pid=rt.router_id inner join boe_course c on c.id=rt.course_id\n" +
"\n" +
"WHERE\n" +
"\n" +
@@ -578,7 +579,7 @@ public class CourseServiceImpl implements ICourseService {
String sql = "SELECT DISTINCT\n" +
"pt.course_id\n" +
"FROM\n" +
"boe_new.student s INNER JOIN boe_new.project_task pt on s.pid=pt.project_id inner join boe_course c on c.id=pt.course_id\n" +
"boe.student s INNER JOIN boe.project_task pt on s.pid=pt.project_id inner join boe_course c on c.id=pt.course_id\n" +
"\n" +
"WHERE\n" +
"\n" +
@@ -635,8 +636,8 @@ public class CourseServiceImpl implements ICourseService {
String sql = "SELECT DISTINCT\n" +
"\tc.id \n" +
"FROM\n" +
"\tboe_new.student s\n" +
"\tINNER JOIN boe_new.grow_task gt ON s.pid = gt.grow_id\n" +
"\tboe.student s\n" +
"\tINNER JOIN boe.grow_task gt ON s.pid = gt.grow_id\n" +
"\tINNER JOIN boe_course c ON gt.course_id = c.id \n" +
"WHERE\n" +
"\ts.type = 14 \n" +
@@ -948,6 +949,7 @@ public class CourseServiceImpl implements ICourseService {
public Course getAddView(String id) {
Course c = courseDao.get(id);
courseDao.updateFieldById(id, "views", c.getViews() + 1);
return c;
}
@@ -1043,7 +1045,6 @@ public class CourseServiceImpl implements ICourseService {
Course c = full.getCourse();//当前的课程信息
Course nowCourse = courseDao.get(c.getId());//修改之前的课程信息
StringBuffer stringBuffer = new StringBuffer("[");
//追加日志内容
appendUpdateLog(stringBuffer, nowCourse, c);
@@ -1176,6 +1177,7 @@ public class CourseServiceImpl implements ICourseService {
hrbpAudit.setCourseId(c.getId());
hrbpAudit.setAddTime(LocalDateTime.now());
hrbpAudit.setAid(full.getAuditUser().getAid());
hrbpAudit.setAuditUser(full.getAuditUser().getName());//提前保存审核hrbp的名字用于显示下一步审核人
hrbpAudit.setAuditRemark("");
hrbpAudit.setForward(CourseHRBPAudit.FORWARD_NONE);
hrbpAudit.setStatus(CourseHRBPAudit.STATUS_NONE);
@@ -1189,8 +1191,9 @@ public class CourseServiceImpl implements ICourseService {
@Override
public void submitAndPublish(CourseFullDto full, String aid, String aname) throws Exception {
Course c = full.getCourse();//当前的课程信息
log.info(" 课程 c = " + c.getId());
log.info(" 课程 c = " + c);
c.setPublished(true);
c.setPublishTime(LocalDateTime.now());
Course nowCourse = courseDao.get(c.getId());

View File

@@ -2,10 +2,37 @@ package com.xboe.school.study.api;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.com.google.common.util.concurrent.RateLimiter;
import com.boe.feign.api.infrastructure.entity.CommonSearchVo;
import com.boe.feign.api.infrastructure.entity.Dict;
import com.xboe.api.ThirdApi;
import com.xboe.constants.CacheName;
import com.xboe.module.course.api.CourseFullTextApi;
import com.xboe.module.course.dto.AiVideoResourceRsp;
import com.xboe.module.course.dto.BoeaiSubtitleRsp;
import com.xboe.module.course.dto.CourseFullText;
import com.xboe.module.course.utils.HttpUtils;
import com.xboe.module.course.entity.*;
import com.xboe.module.course.service.ICourseTagService;
import com.xboe.module.course.vo.TeacherVo;
import com.xboe.module.usergroup.service.IUserGroupService;
import com.xboe.school.study.dao.StudyCourseDao;
import com.xboe.school.vo.StudyTimeVo;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.xboe.common.OrderCondition;
import com.xboe.common.PageList;
import com.xboe.common.Pagination;
@@ -63,7 +90,6 @@ import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
//添加AI课程学习内容
/**
* 课程学习的内容
*/
@@ -116,6 +142,12 @@ public class StudyCourseApi extends ApiBaseController{
@Resource
private ICourseTagService courseTagService;
@Autowired
CourseFullTextApi courseFullTextApi;
@Value("${kjb.aicoreUrl}")
private String aicoreUrl;
@Resource
private IOutSideDataService outsideService;
@@ -128,12 +160,6 @@ public class StudyCourseApi extends ApiBaseController{
@Resource
private XFileUploader fileUploader;
@Autowired
CourseFullTextApi courseFullTextApi;
@Value("${kjb.aicoreUrl}")
private String aicoreUrl;
/**
* 用于避免JPA查询后修改entity实体字段自动更新到数据库
*/
@@ -464,8 +490,6 @@ public class StudyCourseApi extends ApiBaseController{
Organization organization = organizationService.get(userInfo.getDepartId());
String departName = organization != null ? organization.getNamePath() : "";
studyCourse1.setOrgInfo(departName);
// 取userNo为工号
studyCourse1.setUserNo(userInfo.getUserNo());
}
}
} else {
@@ -567,6 +591,11 @@ public class StudyCourseApi extends ApiBaseController{
//StudyCourse sc=service.findByCourseIdAndAid(id, aid);
Map<String,Object> rs=new HashMap<String,Object>();
Course course=courseService.getAddView(cid);
if (StringUtils.isNotBlank(course.getTags()) && course.getTags().matches("[0-9,]+")) {
List<CourseTag> tagList = courseTagService.getTagsByIds(course.getTags());
String tags = tagList.stream().map(CourseTag::getTagName).collect(Collectors.joining(","));
course.setTags(tags);
}
if(course==null || course.getDeleted()){
return badRequest("课程不存在或已被删除");
}
@@ -577,13 +606,14 @@ public class StudyCourseApi extends ApiBaseController{
String tags = tagList.stream().map(CourseTag::getTagName).collect(Collectors.joining(","));
course1.setTags(tags);
}
//rs.put("course",course1);
rs.put("course",course1);
//获取课程AI详情
log.info("---- KJB 获取课程详情 ---");
CourseFullText courseFullText = new CourseFullText();
courseFullText.setId(cid);
courseFullTextApi.getCourseFromKJB(courseFullText,course1);
rs.put("course",course1);
//rs.put("course",course);
List<CourseCrowd> courseCrowdList = courseService.findCrowdByCourseId(cid);
if(crowd!=null && crowd) {
@@ -809,41 +839,38 @@ public class StudyCourseApi extends ApiBaseController{
@PostMapping("/study")
public JsonResponse<String> study(@RequestBody StudyContentDto sci, HttpServletRequest request){
log.info("study已进入");
if(StringUtils.isBlank(sci.getStudyId())){
return error("参数错误");
}
if(StringUtils.isBlank(sci.getContentId())){
return error("参数错误:内容");
}
// LocalDateTime now=LocalDateTime.now();
CurrentUser cuser=getCurrent();
if(sci.getDuration()==null) {
sci.setDuration(1);//增加5秒的学习时长,因方法是每5秒调用一次的
}
// StudyTime st=new StudyTime();
// st.setContentId(sci.getContentId());
// st.setCourseId(sci.getCourseId());
// st.setDuration(5);//增加5秒的学习时长,因方法是每5秒调用一次的
// st.setEndTime(now);
// st.setStartTime(now);
// st.setStudentId(cuser.getAccountId());
// st.setStudentName(cuser.getName());
// st.setStudyId(sci.getStudyId());
String token = request.getHeader("Xboe-Access-Token");
if (StringUtils.isEmpty(token)) {
token = request.getHeader("token");
}
//检查是否已存在
long checkStartTime = System.currentTimeMillis();
StudyCourseItem item = studyService.checkHas(sci.getStudyId(),sci.getContentId());
long checkEndTime = System.currentTimeMillis();
log.info("【学习记录】检查学习记录是否存在完成,耗时={}ms, 是否存在={}", checkEndTime - checkStartTime, item != null);
if(item!=null) {
long redisStartTime = System.currentTimeMillis();
String studyKey = CacheName.NAME_AUTH + ":" + CacheName.STUDY_KEY + item.getCourseId()+":"+cuser.getAccountId()+":"+item.getContentId();
String studyKey2 = CacheName.NAME_AUTH + ":" + CacheName.STUDY_KEY + sci.getCourseId()+":"+cuser.getAccountId()+":"+sci.getContentId();
redisTemplate.opsForValue().set(studyKey,
String.valueOf(item.getProgress()), 2, TimeUnit.HOURS);
String progressStr = redisTemplate.opsForValue().get(studyKey2);
long redisEndTime = System.currentTimeMillis();
log.info("【学习记录】Redis操作完成耗时={}ms", redisEndTime - redisStartTime);
if (progressStr != null && !progressStr.isEmpty()) {
// 尝试将 Redis 中的字符串转换为整数
int redisProgress = Integer.parseInt(progressStr);
@@ -851,20 +878,24 @@ public class StudyCourseApi extends ApiBaseController{
int sciProgress = sci.getProgress();
if (redisProgress < sciProgress && redisProgress < 100) {
// 执行一些操作
// if(item.getProgress()<100 && sci.getProgress()>item.getProgress()) {
// }
long updateStartTime = System.currentTimeMillis();
studyService.updateProcess(item.getId(), sci.getStudyId(), sci.getCourseId(), sci.getContentTotal(), sci.getProgress(),token);
long updateEndTime = System.currentTimeMillis();
log.info("【学习记录】更新学习进度完成,耗时={}ms", updateEndTime - updateStartTime);
}
}
//追加学习时长
long appendStartTime = System.currentTimeMillis();
studyService.appendStudyDuration(sci.getStudyId(),item.getId(),sci.getContentId(),sci.getDuration());
long appendEndTime = System.currentTimeMillis();
log.info("【学习记录】追加学习时长完成1耗时={}ms", appendEndTime - appendStartTime);
log.info(" 1 在线课学习记录 sci.getStudyId() = "+ sci.getStudyId() + " , sci.getCourseId() = " + sci.getCourseId() );
log.info("【学习记录】调用第三方APIsci.getStudyId()={}, sci.getCourseId()={}", sci.getStudyId(), sci.getCourseId());
long thirdApiStartTime = System.currentTimeMillis();
List<StudyCourse> allUserList = thirdApi.getStudyCourseList(sci.getStudyId() ,sci.getCourseId(), token);
log.info("在线课学习记录"+allUserList);
long thirdApiEndTime = System.currentTimeMillis();
log.info("【学习记录】第三方API调用完成耗时={}ms, 结果={}", thirdApiEndTime - thirdApiStartTime, allUserList);
return success(item.getId());
//如果记录存在但是进度不100无成情况就更新进度一期不会有这种情况
}
if(StringUtils.isBlank(sci.getCourseId())){
@@ -878,15 +909,22 @@ public class StudyCourseApi extends ApiBaseController{
sci.setAid(cuser.getAccountId());
sci.setAname(cuser.getName());
long saveStartTime = System.currentTimeMillis();
studyService.saveStudyInfo(sci,token);
long saveEndTime = System.currentTimeMillis();
log.info("【学习记录】保存学习信息完成,耗时={}ms", saveEndTime - saveStartTime);
//学习记录成功后处理
long appendStartTime2 = System.currentTimeMillis();
studyService.appendStudyDuration(sci.getStudyId(),sci.getStudyItemId(),sci.getContentId(),sci.getDuration());
long appendEndTime2 = System.currentTimeMillis();
log.info("【学习记录】追加学习时长完成2耗时={}ms", appendEndTime2 - appendStartTime2);
long thirdApiStartTime2 = System.currentTimeMillis();
List<StudyCourse> allUserList = thirdApi.getStudyCourseList(sci.getStudyId() ,sci.getCourseId(), token);
log.info("在线课学习记录"+allUserList);
//System.out.println("在线课学习记录"+allUserList);
long thirdApiEndTime2 = System.currentTimeMillis();
log.info("【学习记录】第三方API调用完成2耗时={}ms, 结果={}", thirdApiEndTime2 - thirdApiStartTime2, allUserList);
return success(sci.getStudyItemId());
}catch(Exception e) {
log.error("记录学习情况错误",e);
return error("记录学习情况失败",e.getMessage());
}

View File

@@ -13,9 +13,9 @@ import javax.persistence.Transient;
import java.time.LocalDateTime;
/*
* 课程学习表,课程图片通过对应图片的api获取,这里不做存储。
* 此表也是一种历史记录,所以记录的字段多一些
* */
* 课程学习表,课程图片通过对应图片的api获取,这里不做存储。
* 此表也是一种历史记录,所以记录的字段多一些
* */
@Data
@Entity
@EqualsAndHashCode(callSuper = true)
@@ -23,123 +23,123 @@ import java.time.LocalDateTime;
public class StudyCourse extends IdEntity{
private static final long serialVersionUID = 1L;
/**未开始学习*/
public static final int STATUS_NOSTUDY=1;
/**学习中*/
public static final int STATUS_STUDYING=2;
/**终止,比如课程下架*/
public static final int STATUS_ABORTED=8;
/**学习完成*/
public static final int STATUS_FINISH=9;
/*
* 课程id
* */
* 课程id
* */
@Column(name = "course_id",nullable=false,length = 20)
private String courseId;
/*
* 课程类型
* */
* 课程类型
* */
@Column(name = "course_type",nullable=false,length = 1)
private Integer courseType;
/*
* 课程名称
* */
* 课程名称
* */
@Column(name = "course_name",nullable=false,length = 100)
private String courseName;
/*
* 账号id
* */
* 账号id
* */
@Column(name = "aid",nullable=false,length = 20)
private String aid;
/*
* 姓名,用于查看学习记录时显示,
* */
* 姓名,用于查看学习记录时显示,
* */
@Column(name="aname",length = 30)
private String aname;
/*
* 来源:自主报名,和报名中的报名方式一致
* */
* 来源:自主报名,和报名中的报名方式一致
* */
@Column(name = "source")
private Integer source;
/*
* 加入时间 对应报名时间
* */
* 加入时间 对应报名时间
* */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Column(name = "add_time")
private LocalDateTime addTime;
/*
* 开始学习时间,报名和学习是一体的,此字段为后续报名学习不致的情况,当前这种情况没有
* 25.11.21修改:经生产数据查证本字段实际未废弃,因此继续使用
*/
* 开始学习时间,报名和学习是一体的,此字段为后续报名学习不致的情况,当前这种情况没有
* 25.11.21修改:经生产数据查证本字段实际未废弃,因此继续使用
*/
// @Deprecated
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Column(name = "start_time")
private LocalDateTime startTime;
/*
* 完成学习时间
* */
* 完成学习时间
* */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Column(name = "finish_time")
private LocalDateTime finishTime;
/*
* 学习进度
* */
* 学习进度
* */
@Column(name = "progress")
private Float progress;
/*
* 学习总时间,秒,没有小数的情况,所以直接使用整数类型
* 这一项计算时间,在二期中已经不在使用,学习时长已经移到统计服务中,单独的课程不再记录
* 25.11.21修改:经生产数据查证本字段实际未废弃,因此继续使用
*/
* 学习总时间,秒,没有小数的情况,所以直接使用整数类型
* 这一项计算时间,在二期中已经不在使用,学习时长已经移到统计服务中,单独的课程不再记录
* 25.11.21修改:经生产数据查证本字段实际未废弃,因此继续使用
*/
// @Deprecated
@Column(name = "total_duration")
private Integer totalDuration;
/*
* 最终成绩
* */
* 最终成绩
* */
@Column(name = "last_score")
private Float lastScore;
/*
* 状态 1表未开始8表意外终止9表正常完成。
*
* */
* 状态 1表未开始8表意外终止9表正常完成。
*
* */
@Column(name = "status")
private Integer status;
/*
* 状态时间
* */
* 状态时间
* */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Column(name = "status_time")
private LocalDateTime statusTime;
/**
* 最后的学习时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Column(name = "last_time")
private LocalDateTime lastTime;
/*
* 备注
* */
* 备注
* */
@Column(name = "remark",length = 200)
private String remark;

View File

@@ -92,8 +92,8 @@ public class StudyCourseServiceImpl implements IStudyCourseService{
@Autowired
StudyTimeDao studyTimeDao;
@Autowired
CourseStatDao courseStatDao;
@Autowired
CourseStatDao courseStatDao;
@Autowired
CourseDao courseDao;
@@ -279,16 +279,16 @@ public class StudyCourseServiceImpl implements IStudyCourseService{
return studyCoursePageList;
}
/**
* 分页查询课程的资源名称以及资源学习完成人数
*
* @param pageIndex 页码
* @param pageSize 每页数据条数
* @param courseId 课程id
* @param contentName 资源名称
*/
@Override
public PageList<CourseFinishCountDto> findPageResource(int pageIndex, int pageSize, String courseId, String contentName) {
/**
* 分页查询课程的资源名称以及资源学习完成人数
*
* @param pageIndex 页码
* @param pageSize 每页数据条数
* @param courseId 课程id
* @param contentName 资源名称
*/
@Override
public PageList<CourseFinishCountDto> findPageResource(int pageIndex, int pageSize, String courseId, String contentName) {
// 1. 调用Dao层查当前页数据传入偏移量、每页条数、courseId条件
List<CourseFinishCountDto> dtoList = courseStatDao.findFinishCountList(courseId, contentName);
// 2. 调用Dao层查总条数对应PageList的count字段用int类型和PageList一致
@@ -297,13 +297,13 @@ public class StudyCourseServiceImpl implements IStudyCourseService{
int fromIndex = (pageIndex - 1) * pageSize;
int toIndex = Math.min(fromIndex + pageSize, totalCount);
List<CourseFinishCountDto> pageData = dtoList.subList(fromIndex, toIndex);
// 4. 按PageList构造函数创建对象只传list和count
// 4. 按PageList构造函数创建对象只传list和count
PageList<CourseFinishCountDto> pageList = new PageList<>(pageData, totalCount);
// 5. 设置pageSize覆盖默认10确保总页数计算正确
pageList.setPageSize(pageSize);
// 6. 返回totalPage会在前端调用getTotalPages()时自动计算
return pageList;
}
// 5. 设置pageSize覆盖默认10确保总页数计算正确
pageList.setPageSize(pageSize);
// 6. 返回totalPage会在前端调用getTotalPages()时自动计算
return pageList;
}
@Override
public List<StudyCourseNameDto> studyCounts(int num) {
// QueryBuilder builder = QueryBuilder.from(StudyCourse.class);

View File

@@ -9,20 +9,20 @@ spring:
cloud:
nacos:
discovery:
server-addr: 10.232.28.76:8848,10.232.28.83:8848,10.232.28.77:8848
server-addr: 10.251.113.100:8848
config:
server-addr: 10.232.28.76:8848,10.232.28.83:8848,10.232.28.77:8848
server-addr: 10.251.113.100:8848
redis:
database: 1
host: 10.232.27.44
password: j2ZsxUyl
host: 10.251.88.213
password: qwert!W588
port: 6379
jpa:
hibernate:
ddl-auto: none
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://10.232.27.47:3306/boe_base?useSSL=false&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull
url: jdbc:mysql://10.251.88.216:3306/boe_base?useSSL=false&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull
username: admin
password: boeRds01
type: com.zaxxer.hikari.HikariDataSource
@@ -34,7 +34,7 @@ spring:
max-lifetime: 1800000
maximum-pool-size: 20
activemq:
broker-url: tcp://10.232.28.73:61616
broker-url: tcp://10.251.113.100:61616
user: admin
password: admin
jms:
@@ -67,12 +67,12 @@ xboe:
url: https://u.boe.com/userbasic
elasticsearch:
server:
ip: 10.232.27.40
ip: 10.251.88.218
port: 9200
user:
password:
email:
url: http://u.boe.com/infrasApi/sendMsg/sendMail
url: https://u.boe.com/api/b1/email/send
from: boeu_learning@boe.com.cn
user:
security:
@@ -314,7 +314,6 @@ xboe:
- "120434"
- "126466"
- "98050020"
- "10928732"
alert-email-recipients:
- chengmeng@boe.com.cn
- liyubing@boe.com.cn
@@ -338,28 +337,9 @@ aop-log-record:
#不进行拦截的包或者类
excludeClassNames:
activemq:
broker-url: tcp://10.232.28.73:61616
broker-url: tcp://10.251.113.100:61616
user: admin
password: admin
elasticsearch:
host: 10.232.27.40
port: 9200
boe:
domain: http://192.168.0.253
domain-name: https://u.boe.com
pcPageUrl: ${boe.domain-name}/pc/course/studyindex?id=
h5PageUrl: ${boe.domain-name}/mobile/pages/study/courseStudy?id=
pcLoginUrl: ${boe.domain-name}/web/
h5LoginUrl: ${boe.domain-name}/m/loginuser
mysql:
schema:
user-center-schema: user_basic
kjb:
aicoreUrl: http://10.232.28.95:8080
videoUrlPrefix: https://u.boe.com/upload
boe:
domain: https://u.boe.com
host: 10.251.88.218
port: 9200

View File

@@ -168,6 +168,7 @@ boe:
kjb:
aicoreUrl: http://10.251.186.27:8088
videoUrlPrefix: https://u-pre.boe.com/upload
ok:
http:
connect-timeout: 30

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="false">
<springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
<property name="log.path" value="/data/logs/${spring.application.name}"/>
<property name="log.path" value="/home/logs/${spring.application.name}"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
@@ -37,27 +37,27 @@
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<file>${log.path}/caseAiChat.log</file>
<File>${log.path}/caseAiChat.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/caseAiChat.%d{yyyy-MM-dd}.log</fileNamePattern>
<FileNamePattern>${log.path}/caseAiChat.%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
</appender>
<!-- Log file error output -->
<!-- <appender name="caseAiChat" class="ch.qos.logback.core.rolling.RollingFileAppender">-->
<!-- <file>${log.path}/caseAiChat.log</file>-->
<!-- <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">-->
<!-- <fileNamePattern>${log.path}/%d{yyyy-MM}/caseAiChat.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>-->
<!-- <maxFileSize>50MB</maxFileSize>-->
<!-- <maxHistory>30</maxHistory>-->
<!-- </rollingPolicy>-->
<!-- <encoder>-->
<!-- <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>-->
<!-- </encoder>-->
<!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">-->
<!-- <level>ERROR</level>-->
<!-- </filter>-->
<!-- </appender>-->
<appender name="caseAiChat" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/caseAiChat.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM}/caseAiChat.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="INFO">

View File

@@ -2,8 +2,8 @@
spring:
redis:
database: 1
host: 10.232.27.44
password: j2ZsxUyl
host: 10.251.88.213
password: qwert!W588
port: 6379
jpa:
hibernate:
@@ -16,12 +16,12 @@ spring:
driverClassName: com.mysql.jdbc.Driver
db1:
driverClassName: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://10.232.27.47:3306/boe_basic?useSSL=false&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull
jdbc-url: jdbc:mysql://10.251.88.216:3306/boe_basic?useSSL=false&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull
username: admin
password: boeRds01
db2:
driverClassName: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://10.232.27.47:3306/boe_base?useSSL=false&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull
jdbc-url: jdbc:mysql://10.251.88.216:3306/boe_base?useSSL=false&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull
username: admin
password: boeRds01

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="false">
<springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
<property name="log.path" value="/data/logs/${spring.application.name}"/>
<property name="log.path" value="/home/logs/${spring.application.name}"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

View File

@@ -0,0 +1,215 @@
-- 数据迁移SQL项目与报名
-- 执行顺序:
-- 1.1 查看项目数据量
-- 1.2 预览项目数据
-- 1.3 迁移项目信息
-- 1.4 验证项目迁移结果
-- 2.1 查看报名数据量按项目ID
-- 2.2 预览报名数据
-- 2.3 获取新项目ID
-- 2.4 写入报名数据使用新项目ID
-- 2.5 验证报名迁移结果
-- 任务1项目数据迁移eln_boe_mixture_project -> boe_new.project_info条件is_deleted='0' AND program_name='社招新员工在线入职学习'
-- 步骤1.1:查看符合条件的数据量(执行前验证)
SELECT COUNT(*) AS data_count
FROM elearninglms.eln_boe_mixture_project
WHERE is_deleted = '0'
AND program_name = '社招新员工在线入职学习';
-- 步骤1.2:查看要迁移的数据详情(执行前验证)
SELECT *
FROM elearninglms.eln_boe_mixture_project
WHERE is_deleted = '0'
AND program_name = '社招新员工在线入职学习';
-- 步骤1.3执行数据迁移INSERT INTO ... SELECT
INSERT INTO boe_new.project_info (
name,
pic_url,
type,
begin_time,
end_time,
manager_id,
remark,
status,
num_value,
introduction,
new_type,
deleted,
unlock_mode,
rank_flag,
attach_switch,
bpm_flag,
load_flag,
create_time,
create_id,
update_time,
update_id
)
SELECT
p.program_name AS name,
p.theme_url AS pic_url,
1 AS type, -- 项目类别固定为1
CASE
WHEN p.open_start_time IS NOT NULL AND p.open_start_time > 0
THEN FROM_UNIXTIME(p.open_start_time)
WHEN p.start_time IS NOT NULL AND p.start_time > 0
THEN FROM_UNIXTIME(p.start_time)
ELSE NULL
END AS begin_time,
CASE
WHEN p.open_end_time IS NOT NULL AND p.open_end_time > 0
THEN FROM_UNIXTIME(p.open_end_time)
WHEN p.end_time IS NOT NULL AND p.end_time > 0
THEN FROM_UNIXTIME(p.end_time)
ELSE NULL
END AS end_time,
p.project_manager_id AS manager_id,
COALESCE(p.program_desc, p.program_desc_nohtml, '') AS remark,
CASE
WHEN p.status = '0' THEN 0 -- 临时 → 草稿
WHEN p.status = '1' THEN 1 -- 正常 → 已发布
WHEN p.status = '2' THEN -1 -- 停用 → 已结束
ELSE 0
END AS status,
p.program_code AS num_value,
COALESCE(p.program_desc_nohtml, p.program_desc, '') AS introduction,
2 AS new_type, -- 学习项目
0 AS deleted, -- 未删除
1 AS unlock_mode, -- 自由模式
0 AS rank_flag, -- 不显示积分排行榜
1 AS attach_switch, -- 共享文档开启
0 AS bpm_flag, -- 报名审批关闭
0 AS load_flag, -- 下载成绩关闭
FROM_UNIXTIME(p.created_at) AS create_time,
CAST(p.created_by AS UNSIGNED) AS create_id,
FROM_UNIXTIME(COALESCE(p.updated_at, p.created_at)) AS update_time,
CAST(COALESCE(p.updated_by, p.created_by) AS UNSIGNED) AS update_id
FROM elearninglms.eln_boe_mixture_project p
WHERE p.is_deleted = '0'
AND p.program_name = '社招新员工在线入职学习'
AND NOT EXISTS (
-- 防止重复插入:如果项目名称已存在则跳过
SELECT 1
FROM boe_new.project_info pi
WHERE pi.name = p.program_name
AND pi.deleted = 0
);
-- 步骤1.4:验证迁移结果
SELECT
COUNT(*) AS migrated_count,
name,
status,
begin_time,
end_time
FROM boe_new.project_info
WHERE name = '社招新员工在线入职学习'
AND deleted = 0
GROUP BY name, status, begin_time, end_time;
-- 任务2项目报名数据迁移eln_boe_mixture_project_enroll -> boe_base.boe_study_course
-- 迁移全部报名数据(包括已删除记录,按 is_deleted 映射状态)
-- 步骤2.1:查看符合条件的数据量(执行前验证)
-- 注意:需要先将 '123xxx' 替换为实际的项目IDkid
SELECT COUNT(*) AS enroll_count
FROM elearninglms.eln_boe_mixture_project_enroll
WHERE program_id = '123xxx'; -- 请替换为实际的项目IDkid
-- 步骤2.2:查看要迁移的数据详情(执行前验证)
SELECT *
FROM elearninglms.eln_boe_mixture_project_enroll
WHERE program_id = '123xxx' -- 请替换为实际的项目IDkid
LIMIT 100;
-- 步骤2.3获取新项目ID
SET @new_project_id = (
SELECT id FROM boe_new.project_info
WHERE name = '社招新员工在线入职学习' AND deleted = 0
ORDER BY id DESC LIMIT 1
);
-- 步骤2.4写入报名数据使用新项目ID
INSERT INTO boe_base.boe_study_course (
course_id,
course_type,
course_name,
aid,
aname,
source,
add_time,
start_time,
last_score,
status,
progress,
remark
)
SELECT
pi.id AS course_id, -- 使用新项目表的自增ID
90 AS course_type,
COALESCE(pi.name, p.program_name, '') AS course_name,
e.user_id AS aid,
COALESCE(u.real_name, '') AS aname,
CASE
WHEN e.enroll_method = 'self' THEN 1
WHEN e.enroll_method = 'admin' THEN 2
WHEN e.enroll_method = 'manager' THEN 3
ELSE 1
END AS source,
FROM_UNIXTIME(e.enroll_time) AS add_time,
FROM_UNIXTIME(e.enroll_time) AS start_time,
NULL AS last_score,
CASE
WHEN e.enroll_type = '1' AND e.approved_state = '1' AND e.is_deleted = '0' THEN 2
WHEN e.enroll_type = '3' THEN 8
WHEN e.cancel_state = '1' THEN 8
WHEN e.is_deleted = '1' THEN 8
ELSE 1
END AS status,
0 AS progress,
CONCAT('迁移自项目报名表报名ID', e.kid) AS remark
FROM elearninglms.eln_boe_mixture_project_enroll e
LEFT JOIN elearninglms.eln_boe_mixture_project p
ON e.program_id = p.kid
LEFT JOIN boe_new.project_info pi
ON p.program_name = pi.name AND pi.deleted = 0
LEFT JOIN elearninglms.eln_fw_user u
ON e.user_id = u.kid
WHERE e.program_id = '123xxx' -- 请替换为实际的项目IDkid
AND pi.id = @new_project_id -- 使用新项目ID
AND NOT EXISTS (
SELECT 1
FROM boe_base.boe_study_course sc
WHERE sc.course_id = @new_project_id
AND sc.aid = e.user_id
);
-- 步骤2.5:验证迁移结果
SELECT
COUNT(*) AS migrated_count,
status,
COUNT(CASE WHEN last_score IS NOT NULL THEN 1 END) AS has_score_count
FROM boe_base.boe_study_course
WHERE course_id = @new_project_id
GROUP BY status;
-- 回滚SQL
-- 回滚步骤R1确认新项目ID如变量丢失可重新获取
--SET @new_project_id = (
-- SELECT id FROM boe_new.project_info
-- WHERE name = '社招新员工在线入职学习' AND deleted = 0
-- ORDER BY id DESC LIMIT 1
--);
--
---- 回滚步骤R2回滚报名数据按备注标记仅删除本次迁移写入的数据
--DELETE FROM boe_base.boe_study_course
--WHERE course_id = @new_project_id
-- AND remark LIKE '迁移自项目报名表%';
--
---- 回滚步骤R3回滚项目信息谨慎执行确认仅影响本次迁移记录
--DELETE FROM boe_new.project_info
--WHERE id = @new_project_id
-- AND name = '社招新员工在线入职学习'
-- AND deleted = 0;

View File

@@ -0,0 +1,187 @@
# 数据迁移方案文档
## 一、迁移概述
本次迁移涉及两个数据迁移任务:
1. **项目数据迁移**:从 `elearninglms.eln_boe_mixture_project` 迁移到 `boe_new.project_info`
2. **项目报名数据迁移**:从 `elearninglms.eln_boe_mixture_project_enroll` 迁移到 `boe_base.boe_study_course`
---
## 二、任务1项目数据迁移
### 2.1 迁移信息
- **源表**`elearninglms.eln_boe_mixture_project`
- **目标表**`boe_new.project_info`
- **迁移条件**`is_deleted='0'` AND `program_name='社招新员工在线入职学习'`
### 2.2 字段映射关系
| 源表字段 | 目标表字段 | 说明 | 转换规则 |
|---------|-----------|------|---------|
| `kid` | - | 项目IDvarchar | 不直接映射目标表id为自增 |
| `program_name` | `name` | 项目名称 | 直接映射 |
| `program_desc` | `remark` | 项目描述/说明 | 直接映射 |
| `theme_url` | `pic_url` | 封面图地址 | 直接映射 |
| `start_time` / `open_start_time` | `begin_time` | 开始时间 | 优先使用 `open_start_time`,空则用 `start_time`,需转换为 timestamp |
| `end_time` / `open_end_time` | `end_time` | 结束时间 | 优先使用 `open_end_time`,空则用 `end_time`,需转换为 timestamp |
| `project_manager_id` | `manager_id` | 项目经理ID | 直接映射 |
| `status` | `status` | 状态 | 需要转换:'0'→0(草稿), '1'→1(已发布), '2'→-1(已结束) |
| `created_at` | `create_time` | 创建时间 | 需转换为 timestamp |
| `created_by` | `create_id` | 创建人ID | 需转换为 bigint |
| `updated_at` | `update_time` | 更新时间 | 需转换为 timestamp |
| `updated_by` | `update_id` | 更新人ID | 需转换为 bigint |
| `program_code` | `num_value` | 项目编号 | 直接映射 |
| `program_desc` / `program_desc_nohtml` | `introduction` | 项目介绍 | 优先使用 `program_desc_nohtml` |
### 2.3 默认值设置
- `type`: 1项目类别
- `new_type`: 2学习项目
- `deleted`: 0未删除
- `unlock_mode`: 1自由模式
- `rank_flag`: 0不显示积分排行榜
- `attach_switch`: 1共享文档开启
- `bpm_flag`: 0报名审批关闭
- `load_flag`: 0下载成绩关闭
### 2.4 注意事项
1. 目标表的 `id` 字段为自增主键,无需手动设置
2. 时间字段需要从 int时间戳转换为 timestamp
3. 状态字段需要根据源表的值进行映射转换
4. 如果源表中存在多条符合条件的记录,需要确认是否全部迁移或仅迁移最新的一条
---
## 三、任务2项目报名数据迁移
### 3.1 迁移信息
- **源表**`elearninglms.eln_boe_mixture_project_enroll`
- **目标表**`boe_base.boe_study_course`
- **迁移条件**`program_id='123xxx'`注意实际执行时需要替换为真实的项目ID
- **重要说明****迁移全部报名数据包括已删除的记录is_deleted='1'**。已删除的记录在状态映射时会被标记为"终止"状态status=8
### 3.2 字段映射关系
| 源表字段 | 目标表字段 | 说明 | 转换规则 |
|---------|-----------|------|---------|
| `program_id` | `course_id` | 项目ID作为课程ID | 直接映射 |
| `user_id` | `aid` | 学员ID | 直接映射 |
| - | `last_score` | 学习成绩 | 初始设置为 NULL后续需要从成绩表关联更新 |
| `enroll_type` + `approved_state` | `status` | 完成状态 | 根据业务规则映射(见下方) |
| `enroll_time` | `add_time` | 加入时间(报名时间) | 需转换为 datetime |
| `enroll_time` | `start_time` | 开始学习时间 | 需转换为 datetime |
### 3.3 状态映射规则
根据 `boe_study_course` 表的 status 定义:
- `STATUS_NOSTUDY = 1`(未开始学习)
- `STATUS_STUDYING = 2`(学习中)
- `STATUS_ABORTED = 8`(终止)
- `STATUS_FINISH = 9`(学习完成)
**状态映射逻辑**
```sql
CASE
WHEN enroll_type = '1' AND approved_state = '1' AND is_deleted = '0' THEN 2 -- 报名成功且审批同意 → 学习中
WHEN enroll_type = '3' THEN 8 -- 拒绝报名 → 终止
WHEN cancel_state = '1' THEN 8 -- 取消审批同意 → 终止
WHEN is_deleted = '1' THEN 8 -- 已删除 → 终止
ELSE 1 -- 其他情况 → 未开始
END AS status
```
### 3.4 其他字段设置
- `course_type`: 需要根据项目类型设置(默认为项目类型对应的课程类型)
- `course_name`: 需要关联项目表获取项目名称
- `aname`: 需要关联用户表获取学员姓名
- `source`: 根据 `enroll_method` 映射('self'→1, 'admin'→2, 'manager'→3
- `progress`: 初始设置为 0 或 NULL
- `last_score`: 初始设置为 NULL需要后续从成绩表更新
### 3.5 注意事项
1. **学习成绩last_score**:源表中没有直接的成绩字段,需要:
- 方案A从其他成绩表`eln_ln_examination_result_user`)关联获取
- 方案B先设置为 NULL后续通过业务逻辑更新
2. **完成状态status**:需要根据业务逻辑判断,当前映射规则仅供参考,实际使用时需要根据业务需求调整
3. **项目ID替换**SQL中的 `'123xxx'` 需要替换为实际的项目ID
4. **数据去重**:确保 `(course_id, aid)` 组合的唯一性,避免重复插入
5. **关联查询**:可能需要关联用户表获取学员姓名等信息
6. **全部数据迁移**:本次迁移会包含所有符合条件的报名记录,包括已删除的记录。已删除的记录会根据 `is_deleted='1'` 映射为终止状态status=8
---
## 四、执行步骤
### 4.1 执行前准备
1. **备份数据**:执行迁移前,务必备份源表和目标表
2. **验证条件**确认迁移条件是否正确特别是项目名称和项目ID
3. **数据检查**:检查源表中符合条件的数据量
4. **环境确认**:确认目标数据库连接和权限
### 4.2 执行顺序
1. **先执行任务1**:迁移项目数据
2. **获取新项目ID**记录迁移后的项目ID如果需要
3. **更新任务2的SQL**将项目ID替换为实际值
4. **执行任务2**:迁移项目报名数据
### 4.3 执行后验证
1. **数据量核对**:对比源表和目标表的记录数
2. **关键字段验证**:抽查关键字段是否正确迁移
3. **业务功能验证**:在系统中验证迁移后的数据是否正常
---
## 五、风险评估与回滚方案
### 5.1 风险点
1. **数据量**:如果数据量较大,可能影响系统性能
2. **字段类型不匹配**:时间戳转换、状态值转换可能出错
3. **数据完整性**:关联字段可能缺失或无效
4. **业务逻辑**:状态映射规则可能与实际业务不符
### 5.2 回滚方案
1. **备份恢复**:使用备份数据恢复目标表
2. **删除迁移数据**:根据迁移条件删除已迁移的数据
3. **数据修复**:手动修复错误的数据
---
## 六、附录
### 6.1 相关表结构
- `elearninglms.eln_boe_mixture_project`:源项目表
- `boe_new.project_info`:目标项目表
- `elearninglms.eln_boe_mixture_project_enroll`:源报名表
- `boe_base.boe_study_course`:目标课程学习表
### 6.2 状态值对照表
**项目状态映射**
- '0'(临时)→ 0草稿
- '1'(正常)→ 1已发布
- '2'(停用)→ -1已结束
**学习状态映射**
- 1未开始学习
- 2学习中
- 8终止
- 9学习完成
---