Compare commits

92 Commits

Author SHA1 Message Date
liweijie 60841e5bc8 连接字符串修改 2026-09-24 17:40:56 +08:00
liweijie 4137d61561 数据库连接修改,换国产数据库opengauss 2026-09-24 15:50:17 +08:00
liweijie f8e6466d24 1、课时统计功能调整新增;
2、教学楼序号改为自动填充,无需填写;
3、教学楼检索,教学楼代号下拉选择;
4、课表冲突检查修复
2026-09-24 15:07:26 +08:00
liweijie bd395a5504 课时统计功能提交 2026-09-24 14:08:44 +08:00
liweijie d9f8bf705d 从班次信息管理的排课按钮进排课窗口,刷新页面信息 2026-09-24 11:49:22 +08:00
liweijie 836995a794 班次学期管理,年度检索下拉框数据缺失问题修复 2026-09-24 11:32:26 +08:00
liweijie 094245231c 1、新增教学大纲,报专业名称重复,其实是code重复,修复;
2、已经限制教员排课的,教员仍然可以排课的问题修复
2026-09-24 11:13:23 +08:00
liweijie 4f5e219a6e 新增专业信息的时候设置下拉选项 2026-09-24 09:07:43 +08:00
liweijie 06c057e490 1、学员信息管理成绩查看,只显示课程编号改为显示课程名称和课程编号;
2、机关教学日志日期显示格式修改
2026-09-23 17:43:40 +08:00
liweijie 07ec44e9d4 学员查看成绩没有操作权限的问题修复 2026-09-23 16:41:55 +08:00
liweijie ad92f4afc9 学员信息列表,性别改为显示标签 2026-09-23 15:39:25 +08:00
liweijie 69a1a7d560 学员队表和学员队期表联动 2026-09-23 15:19:19 +08:00
liweijie fb3d20def6 1、学员队期下拉选择;
2、学员信息管理,操作列改为两行显示
2026-09-23 14:58:19 +08:00
liweijie 90fb852cf2 日期保存报错修复 2026-09-22 17:26:04 +08:00
liweijie 62fb137611 课程科目新建的时候部分字段改为下拉选择 2026-09-22 17:13:55 +08:00
liweijie f87e02b06b 选修课和课程科目,上传按钮样式调整,点击按钮选择文件导入 2026-09-22 16:46:56 +08:00
liweijie 1ac022757d 1、选修课保存调整,加上教材的保存;
2、课程可以下拉选择;
2026-09-22 16:25:55 +08:00
liweijie 97ae86f9c7 1、选修课选择教室、教员等用下拉选择,
2、绑定教材落库
2026-09-22 16:09:20 +08:00
liweijie cda0854ab1 教学场地工具条按两行显示 2026-09-22 15:24:06 +08:00
liweijie 3fcec5d756 把工具条横过来,占满一行,数据导入也放到工具条中,不要单独放 2026-09-22 11:56:08 +08:00
liweijie 69a32e31d0 属性信息填写及编号回填等梳理 2026-09-22 10:35:02 +08:00
liweijie c9a2098f3f 添加一个复职的功能,页面操作列按钮分成两行展示,添加根据离职过滤 2026-09-22 10:17:37 +08:00
liweijie 2c5823df09 教研室-教员管理,新建教员的时候,在职类型和导师类型改为下拉,在职类型默认在职 2026-09-22 09:51:15 +08:00
liweijie 738d5917f9 教研室管理,按照序号字段排序 2026-09-22 09:27:20 +08:00
liweijie ae3dbe66a5 人才培养方案,列表过滤,停用的不展示 2026-09-22 09:16:41 +08:00
liweijie 12eddac276 教学大纲,导出选中数据,有勾选导出勾选条目,无勾选导出所有 2026-09-21 17:48:38 +08:00
liweijie 450d664c33 教学大纲,模板下载,添加填写说明 2026-09-21 17:28:46 +08:00
liweijie 3fe66d770d 学员队新增的时候,教室改为下拉,默认在校 2026-09-21 17:20:16 +08:00
liweijie f5728c0827 操作列透明度设置为不透明,否则底层显示跟操作列冲突 2026-09-21 17:09:31 +08:00
liweijie 1482bfd31c 班次编号生成,改为XYD+年度+补零序号 2026-09-21 16:36:09 +08:00
liweijie 035c01e90b 教学任务管理界面完善,教员、教学场地改为下拉 2026-09-20 19:03:39 +08:00
zhaichao 7b84d499a9 排课窗口单元格单击双选问题修复 2026-09-20 17:22:55 +08:00
zhaichao f5a5c89ee3 联教编辑报错 2026-09-20 15:24:07 +08:00
zhaichao 5e3bee9c5f 学员学籍异动申请新增报错 2026-09-20 14:45:19 +08:00
zhaichao a566a26fec 选修课管理 2026-09-20 14:26:52 +08:00
zhaichao 9f0c0ac873 人才培养方案 2026-09-20 11:59:04 +08:00
liweijie e4f4720113 生成课表的时候死循环导致系统崩溃 2026-09-18 20:58:00 +08:00
liweijie 574d41aea8 课表模板新增的时候报错修复 2026-09-18 20:38:21 +08:00
liweijie 62ff4d48ab 学科专业新增报错修复 2026-09-18 20:31:29 +08:00
liweijie b87e910f9a 教学配当界面无法打开的问题修复 2026-09-18 20:11:59 +08:00
liweijie 7e0d96f627 教学任务 → 复制所选 → 粘贴到其它班次,目标班次选择弹窗会正常浮在最上层,不再被遮罩盖住 2026-09-18 19:58:39 +08:00
liweijie fdc7bb01fd 教学业务-班次学期信息管理-操作列点击教学任务-新增课程任务,课编号要求下拉选择,并能带出所选课程的对应信息 2026-09-18 19:51:41 +08:00
liweijie 7096873e2c 教研室账号校验改为用角色校验 2026-09-18 19:31:53 +08:00
liweijie 5a3d202599 添加页面必填信息校验 2026-09-18 19:00:08 +08:00
liweijie 04551fce73 教学公告删除报错 2026-09-18 18:20:36 +08:00
liweijie f36b1f4701 AI测试反馈的报错调整 2026-09-18 18:12:59 +08:00
liweijie 68b02ea58e 部分表名写成了英文名调整 2026-09-18 17:48:31 +08:00
liweijie cff7b039e3 DBVersion的读写修改 2026-09-18 16:56:26 +08:00
liweijie e27b61b5fe 工具条按钮样式统一 2026-09-18 11:50:09 +08:00
liweijie b529f0b523 人才培养方案工具条调整 2026-09-18 11:36:30 +08:00
liweijie a0d5a3b0fe 教学公告添加发布功能 2026-09-18 10:50:26 +08:00
liweijie f3ae9fb2fd 1、校历的78、晚上、夜间等直接落库,
2、配当、任务书完善、排课窗完善;
3、任务书批量发布、删除等;
4、班历同步校历
2026-09-18 10:38:39 +08:00
liweijie 911dfe911b 1课表模板管理;
2、课表生成;
3、课表的网格视图;
4、导出与打印
2026-09-18 09:02:41 +08:00
liweijie 971ea46da5 1、添加实施计划统计分析;
2、添加单课程实施计划列表;
3、恢复同步班历;
4、冲突项添加颜色分级;
5、校历补上正课;
6、添加教学场地总览;
2026-09-17 18:20:48 +08:00
liweijie 351df2cba2 排课功能优化 2026-09-17 17:14:31 +08:00
liweijie a958bcf059 添加排课功能 2026-09-17 15:58:33 +08:00
liweijie 80e91707e6 1、分页添加默认项,
2、登录名冲突无"复用/认领"机制,教员永久无法开通账号
3、两条对齐路径对"停用教研室"处理不一致
2026-09-17 15:18:13 +08:00
liweijie 8c346de4d8 1、停用教员的同时禁用该教员的账号;
2、教员导入的时候,如果有错误,跳过并返回具体报错行;
3、教研室接口权限添加控制
2026-09-17 14:35:06 +08:00
liweijie 95a3571c69 新增教研室和教员的时候,同步创建部门和教员账号 2026-09-17 12:00:44 +08:00
liweijie f7299c36e8 教学大纲新增导出模板和导入按钮 2026-09-17 10:03:29 +08:00
liweijie 9af6de6ff3 新增教学场地校验编号的重复性 2026-09-17 09:30:04 +08:00
liweijie abf616a8ee 班历功能添加 2026-09-16 17:13:57 +08:00
liweijie 2e151ea228 1、添加教学场地历;
2、很多表继承了基础类,但是没有添加对应字段导致报错,把继承去掉
2026-09-16 16:37:23 +08:00
liweijie 58499afe8e 教室编号生成调整 2026-09-16 12:02:33 +08:00
zhaichao 49b3232e79 人培新建 2026-09-16 11:22:11 +08:00
liweijie 62cf543760 专业代码改为下拉框,选择之后带出专业信息 2026-09-16 11:15:13 +08:00
zhaichao af51469121 Merge branch 'main' of https://gitea.fengyingkj.top/liweijie/education 2026-09-16 11:07:00 +08:00
zhaichao 490e1845f6 人才培养方案新增自动生成代号,代码 2026-09-16 11:04:18 +08:00
liweijie 4cb39ca1b0 Merge remote-tracking branch 'origin/main' into main 2026-09-16 09:30:37 +08:00
liweijie 25c1922f08 注释添加 2026-09-16 09:30:31 +08:00
zhaichao bbf54c26a3 人才培养方案新增下拉框 2026-09-16 09:28:16 +08:00
liweijie 9d70d4c25e Merge remote-tracking branch 'origin/main' into main 2026-09-16 09:27:34 +08:00
liweijie 8c992183e3 教学楼排序调整 2026-09-16 09:27:17 +08:00
zhaichao b05c4d33db 教学大纲新增显示排序问题 2026-09-16 09:24:10 +08:00
liweijie b30e39f91a 1、教学楼添加批量删除功能;
2、教学楼导入代号从excel获取,不要自己生成
2026-09-16 09:07:47 +08:00
liweijie d9b10a3f05 教学楼管理功能新增 2026-09-15 18:38:37 +08:00
liweijie 6e767947f7 专业添加导入模板下载和数据上传 2026-09-15 17:43:34 +08:00
liweijie c7397ad457 专业保存提示错误,前后端数据类型不一致导致的 2026-09-15 17:15:06 +08:00
zhaichao 5903f0c590 教学大纲下载功能 2026-09-15 16:13:06 +08:00
zhaichao 5d928bd303 教学大纲停用改删除 2026-09-15 16:06:16 +08:00
liweijie 9312327112 新增教员页面,下拉框乱码修复,保存报错修复 2026-09-15 15:54:06 +08:00
liweijie 3905e5cb54 教学任务书填报 2026-09-15 14:44:16 +08:00
liweijie e8a58b19fe 通过AI比对原操作文档,生成系统功能完善方案,根据方案进行增补,完善从学期新增到最终的排课功能 2026-09-15 14:42:43 +08:00
liweijie 5187435285 学期新增的时候校验校历功能点添加,否则会有大量的数据重复生成 2026-09-14 17:24:56 +08:00
liweijie 52a04dbf60 1、正课与学期关系关联;
2、天假删除保护;
3、教学任务计划增加了「结束发布」。已发布或库里的「已发布」都可以结束;结束后写入结束时间,任务书和班次课程任务只读
4、班次学期操作内容调整修改;
2026-09-14 16:30:52 +08:00
zhaichao 30f2182453 忽略配置 2026-09-10 17:56:11 +08:00
zhaichao afa561a7a4 仓库配置 2026-09-10 17:52:03 +08:00
zhaichao 345f425a1d 前端文件 2026-09-10 17:42:46 +08:00
liumengyu 255a0e56a5 bug修复 2026-09-10 17:31:19 +08:00
liumengyu 407f89a603 bug修复 2026-08-28 19:45:32 +08:00
liumengyu 770d32a625 bug修复 2026-08-28 17:34:56 +08:00
liumengyu a43561af8d bug修复 2026-08-26 09:56:12 +08:00
810 changed files with 101967 additions and 2210 deletions
+52
View File
@@ -0,0 +1,52 @@
# OS
.DS_Store
Thumbs.db
Desktop.ini
# IDE / editor
.idea/
*.iml
.vscode/
*.swp
*.swo
*~
# Java / Maven
target/
*.class
*.jar
!backend/DmJdbcDriver8.jar
hs_err_pid*
replay_pid*
# Node / Vue
node_modules/
dist/
frontend/dist/
.cache/
.temp/
# Logs
*.log
logs/
# Env / local secrets
.env
.env.*
!.env.example
*.local
# Test / coverage
coverage/
.nyc_output/
htmlcov/
# Local deploy / agent state
deploy/
.reasonix/
reasonix.toml
.workbuddy/
# Agent scratch (screenshot/temp working dirs, local maven repo)
output/*/working/
m2repo/
-10
View File
@@ -1,10 +0,0 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# 已忽略包含查询文件的默认文件夹
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
-15
View File
@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="DM" uuid="a3a7e92a-b8da-4229-8b83-5db11f9db9a9">
<driver-ref>9fcb59ee-b3c5-470d-89df-ad01e7cabb15</driver-ref>
<imported>true</imported>
<configured-by-url>true</configured-by-url>
<remarks>$PROJECT_DIR$/backend/roomroot-admin/src/main/resources/application-druid.yml</remarks>
<auto-commit>false</auto-commit>
<jdbc-driver>dm.jdbc.driver.DmDriver</jdbc-driver>
<jdbc-url>jdbc:dm://10.1.1.17:5236?schema=JIAOWU&amp;useUnicode=true&amp;characterEncoding=utf-8</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourcePerFileMappings">
<file url="file://$PROJECT_DIR$/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/mapper/SSDKSQMapper.xml" value="a3a7e92a-b8da-4229-8b83-5db11f9db9a9" />
</component>
</project>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

@@ -1,8 +0,0 @@
{
"topic_20260818-025043_e469238a6cc39459": {
"stage": 3,
"userTurns": 3,
"basisHash": "ab28583a1084bba5",
"updatedAt": 1787024624634
}
}
-3
View File
@@ -1,3 +0,0 @@
{
"topic_20260818-025043_e469238a6cc39459": 1787021443129
}
@@ -1,3 +0,0 @@
{
"topic_20260818-025043_e469238a6cc39459": "auto"
}
-3
View File
@@ -1,3 +0,0 @@
{
"topic_20260818-025043_e469238a6cc39459": "在JYSController中,教研…"
}
@@ -1,2 +0,0 @@
{"sequence":1,"timestamp":"2026-08-18T11:50:58.8315719+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-1","session_id":"20260818-025043.151598500-session","state":"running","runtime_state":"alive"}
{"sequence":2,"timestamp":"2026-08-18T11:51:29.838828+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-1","session_id":"20260818-025043.151598500-session","state":"succeeded","runtime_state":"exited"}
@@ -1 +0,0 @@
{"schema_version":1,"task_id":"20260818-025043.151598500-session--bash-1","job_id":"bash-1","session_id":"20260818-025043.151598500-session","state":"succeeded","runtime_state":"exited","runtime_lease_until":"0001-01-01T00:00:00Z","version":8,"created_at":"2026-08-18T11:50:58.8315719+08:00","updated_at":"2026-08-18T11:51:29.838828+08:00"}
@@ -1,2 +0,0 @@
{"sequence":1,"timestamp":"2026-08-18T11:52:59.6491318+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-2","session_id":"20260818-025043.151598500-session","state":"running","runtime_state":"alive"}
{"sequence":2,"timestamp":"2026-08-18T11:53:12.5470012+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-2","session_id":"20260818-025043.151598500-session","state":"failed","runtime_state":"exited","error_code":"job_failed"}
@@ -1 +0,0 @@
{"schema_version":1,"task_id":"20260818-025043.151598500-session--bash-2","job_id":"bash-2","session_id":"20260818-025043.151598500-session","state":"failed","runtime_state":"exited","runtime_lease_until":"0001-01-01T00:00:00Z","version":4,"created_at":"2026-08-18T11:52:59.6491318+08:00","updated_at":"2026-08-18T11:53:12.5470012+08:00","error_code":"job_failed"}
@@ -1,2 +0,0 @@
{"sequence":1,"timestamp":"2026-08-18T11:55:22.4260602+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-3","session_id":"20260818-025043.151598500-session","state":"running","runtime_state":"alive"}
{"sequence":2,"timestamp":"2026-08-18T11:55:48.4568907+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-3","session_id":"20260818-025043.151598500-session","state":"succeeded","runtime_state":"exited"}
@@ -1 +0,0 @@
{"schema_version":1,"task_id":"20260818-025043.151598500-session--bash-3","job_id":"bash-3","session_id":"20260818-025043.151598500-session","state":"succeeded","runtime_state":"exited","runtime_lease_until":"0001-01-01T00:00:00Z","version":7,"created_at":"2026-08-18T11:55:22.4260602+08:00","updated_at":"2026-08-18T11:55:48.4568907+08:00"}
@@ -1,2 +0,0 @@
{"sequence":1,"timestamp":"2026-08-18T11:56:26.9971307+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-4","session_id":"20260818-025043.151598500-session","state":"running","runtime_state":"alive"}
{"sequence":2,"timestamp":"2026-08-18T11:57:42.5597432+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-4","session_id":"20260818-025043.151598500-session","state":"cancelled","runtime_state":"exited","error_code":"job_failed"}
@@ -1 +0,0 @@
{"schema_version":1,"task_id":"20260818-025043.151598500-session--bash-4","job_id":"bash-4","session_id":"20260818-025043.151598500-session","state":"cancelled","runtime_state":"exited","runtime_lease_until":"0001-01-01T00:00:00Z","version":17,"created_at":"2026-08-18T11:56:26.9971307+08:00","updated_at":"2026-08-18T11:57:42.5597432+08:00","error_code":"job_failed"}
@@ -1,2 +0,0 @@
{"sequence":1,"timestamp":"2026-08-18T15:59:13.8456942+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-5","session_id":"20260818-025043.151598500-session","state":"running","runtime_state":"alive"}
{"sequence":2,"timestamp":"2026-08-18T15:59:39.9995233+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-5","session_id":"20260818-025043.151598500-session","state":"succeeded","runtime_state":"exited"}
@@ -1 +0,0 @@
{"schema_version":1,"task_id":"20260818-025043.151598500-session--bash-5","job_id":"bash-5","session_id":"20260818-025043.151598500-session","state":"succeeded","runtime_state":"exited","runtime_lease_until":"0001-01-01T00:00:00Z","version":7,"created_at":"2026-08-18T15:59:13.8456942+08:00","updated_at":"2026-08-18T15:59:39.9995233+08:00"}
@@ -1,2 +0,0 @@
{"sequence":1,"timestamp":"2026-08-18T15:59:54.7700222+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-6","session_id":"20260818-025043.151598500-session","state":"running","runtime_state":"alive"}
{"sequence":2,"timestamp":"2026-08-18T16:01:27.1609364+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-6","session_id":"20260818-025043.151598500-session","state":"cancelled","runtime_state":"exited","error_code":"job_failed"}
@@ -1 +0,0 @@
{"schema_version":1,"task_id":"20260818-025043.151598500-session--bash-6","job_id":"bash-6","session_id":"20260818-025043.151598500-session","state":"cancelled","runtime_state":"exited","runtime_lease_until":"0001-01-01T00:00:00Z","version":20,"created_at":"2026-08-18T15:59:54.7700222+08:00","updated_at":"2026-08-18T16:01:27.1609364+08:00","error_code":"job_failed"}
@@ -1,2 +0,0 @@
{"sequence":1,"timestamp":"2026-08-20T10:07:19.1030303+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-7","session_id":"20260818-025043.151598500-session","state":"running","runtime_state":"alive"}
{"sequence":2,"timestamp":"2026-08-20T10:08:07.4924999+08:00","event_type":"state_change","task_id":"20260818-025043.151598500-session--bash-7","session_id":"20260818-025043.151598500-session","state":"succeeded","runtime_state":"exited"}
@@ -1 +0,0 @@
{"schema_version":1,"task_id":"20260818-025043.151598500-session--bash-7","job_id":"bash-7","session_id":"20260818-025043.151598500-session","state":"succeeded","runtime_state":"exited","runtime_lease_until":"0001-01-01T00:00:00Z","version":11,"created_at":"2026-08-20T10:07:19.1030303+08:00","updated_at":"2026-08-20T10:08:07.4924999+08:00"}
-4
View File
@@ -1,4 +0,0 @@
# Maven 编译产物
target/
**/target/
*.class
+1 -1
View File
@@ -9,7 +9,7 @@
<version>3.9.2</version> <version>3.9.2</version>
<name>roomroot</name> <name>roomroot</name>
<description>风影随行管理系统</description> <description>教务管理系统</description>
<properties> <properties>
<roomroot.version>3.9.2</roomroot.version> <roomroot.version>3.9.2</roomroot.version>
+7
View File
@@ -37,6 +37,13 @@
<version>8.1.2.192</version> <version>8.1.2.192</version>
</dependency> </dependency>
<!-- openGauss 数据库驱动包 -->
<dependency>
<groupId>org.opengauss</groupId>
<artifactId>opengauss-jdbc</artifactId>
<version>6.0.3-og</version>
</dependency>
<!-- 核心模块--> <!-- 核心模块-->
<dependency> <dependency>
<groupId>com.roomroot</groupId> <groupId>com.roomroot</groupId>
@@ -5,6 +5,8 @@ import com.roomroot.jwgl.service.BuildService;
import com.roomroot.jwgl.unit.PageQuery; import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult; import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.unit.Result; import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.build.BuildDeleteResultVO;
import com.roomroot.jwgl.vo.build.BuildImportResultVO;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -40,6 +42,15 @@ public class BuildController {
return Result.success(); return Result.success();
} }
/**
* 批量删除教学楼(已绑定教学场地的跳过不删,暂定)
*/
@PostMapping("/batchDelete")
public Result<BuildDeleteResultVO> batchDelete(@RequestBody List<String> ids) {
BuildDeleteResultVO result = buildService.batchDelete(ids);
return Result.success(result.getMessage(), result);
}
/** /**
* 更新教学楼 * 更新教学楼
*/ */
@@ -77,9 +88,9 @@ public class BuildController {
* 导入Excel文件 * 导入Excel文件
*/ */
@PostMapping("/import") @PostMapping("/import")
public Result<Integer> importExcel(@RequestParam("file") MultipartFile file) { public Result<BuildImportResultVO> importExcel(@RequestParam("file") MultipartFile file) {
int count = buildService.importExcel(file); BuildImportResultVO result = buildService.importExcel(file);
return Result.success("导入成功", count); return Result.success(result.getMessage(), result);
} }
/** /**
@@ -0,0 +1,65 @@
package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.dto.calendar.ClassCalendarApplyDTO;
import com.roomroot.jwgl.dto.calendar.ClassCalendarBatchSaveDTO;
import com.roomroot.jwgl.dto.calendar.ClassCalendarEventDTO;
import com.roomroot.jwgl.service.ClassEventCalendarService;
import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.calendar.ClassCalendarResyncVO;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import java.util.List;
/**
* 班历(假期表)。与课程任务接口 /classCalendar 分开。
*/
@RestController
@RequestMapping("/class-calendar")
public class ClassEventCalendarController {
@Resource
private ClassEventCalendarService classEventCalendarService;
@GetMapping("/list")
public Result<List<ClassCalendarEventDTO>> list(@RequestParam("xydxqbh") String xydxqbh) {
return Result.success(classEventCalendarService.listOrInherit(xydxqbh));
}
@PostMapping("/update")
public Result<Void> update(@RequestBody ClassCalendarEventDTO event) {
classEventCalendarService.update(event);
return Result.success();
}
/**
* 批量保存班历时间格(拖选区域一次提交,单事务 upsert;action=clear 恢复默认)
*/
@PostMapping("/batchSave")
public Result<Integer> batchSave(@RequestBody ClassCalendarBatchSaveDTO body) {
int saved = classEventCalendarService.batchSave(body);
return Result.success("已保存 " + saved + " 个时间格", saved);
}
/**
* 重新同步校历:confirm=false 返回差异预览,confirm=true 实际写入;
* force=true 时额外覆盖与校历不一致的已有格。
*/
@PostMapping("/resync")
public Result<ClassCalendarResyncVO> resync(@RequestParam("xydxqbh") String xydxqbh,
@RequestParam(value = "confirm", defaultValue = "false") boolean confirm,
@RequestParam(value = "force", defaultValue = "false") boolean force) {
return Result.success(classEventCalendarService.resync(xydxqbh, confirm, force));
}
@PostMapping("/apply")
public Result<Integer> apply(@RequestBody ClassCalendarApplyDTO body) {
return Result.success(classEventCalendarService.apply(
body.getSourceXydxqbh(), body.getTargetBhList(), body.getEventBhList()));
}
}
@@ -5,6 +5,8 @@ import com.roomroot.jwgl.service.ClassRoomCalendarService;
import com.roomroot.jwgl.unit.PageQuery; import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult; import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.unit.Result; import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.classroom.VenueLessonVO;
import com.roomroot.jwgl.vo.classroom.VenueScheduleItemVO;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -86,4 +88,60 @@ public class ClassRoomCalendarController {
public Result<List<JXCDL>> listByRq(@RequestParam("rq") String rq) { public Result<List<JXCDL>> listByRq(@RequestParam("rq") String rq) {
return Result.success(calendarService.listByRq(rq)); return Result.success(calendarService.listByRq(rq));
} }
/**
* 批量保存场地历事件(拖选区域写入,按 教室编号+日期+节次 判重覆盖)
*/
@PostMapping("/batchSave")
public Result<Integer> batchSave(@RequestBody List<JXCDL> list) {
int saved = calendarService.batchSave(list);
return Result.success("已保存 " + saved + " 个时间格事件", saved);
}
/**
* 按 ID 批量删除场地历事件(恢复可排)
*/
@PostMapping("/batchDelete")
public Result<Integer> batchDelete(@RequestBody List<String> ids) {
int deleted = calendarService.batchDelete(ids);
return Result.success("已删除 " + deleted + " 个时间格事件", deleted);
}
/**
* 按教室编号 + 日期范围查询场地历
*/
@GetMapping("/listByJsbhAndRange")
public Result<List<JXCDL>> listByJsbhAndRange(@RequestParam("jsbh") String jsbh,
@RequestParam(value = "start", required = false) String start,
@RequestParam(value = "end", required = false) String end) {
return Result.success(calendarService.listByJsbhAndRange(jsbh, start, end));
}
/**
* 查询场地在日期范围内已排课次(编辑器蓝格数据源)
*/
@GetMapping("/lessons")
public Result<List<VenueLessonVO>> listVenueLessons(@RequestParam("jsbh") String jsbh,
@RequestParam(value = "start", required = false) String start,
@RequestParam(value = "end", required = false) String end,
@RequestParam(value = "nd", required = false) Integer nd) {
return Result.success(calendarService.listVenueLessons(jsbh, start, end, nd));
}
/**
* 查询指定本场地为专用教室的班次(编辑器顶部横幅数据源)
*/
@GetMapping("/designatedTeams")
public Result<List<String>> listDesignatedTeams(@RequestParam("jsbh") String jsbh) {
return Result.success(calendarService.listDesignatedTeams(jsbh));
}
/**
* 场地占用总览:某日期+节次全部场地的占用状态
*/
@GetMapping("/venueSchedule")
public Result<List<VenueScheduleItemVO>> venueSchedule(@RequestParam("rq") String rq,
@RequestParam("jc") Integer jc) {
return Result.success(calendarService.venueSchedule(rq, jc));
}
} }
@@ -13,7 +13,7 @@ import java.util.Map;
* 学员队任务表控制器 * 学员队任务表控制器
*/ */
@RestController @RestController
@RequestMapping("/classCalendar") @RequestMapping({"/classCalendar", "/course-task"})
public class ClassSemesterCalendarController { public class ClassSemesterCalendarController {
@Resource @Resource
@@ -296,7 +296,11 @@ public class CourseRunningController {
} }
/** /**
* 查询当前教员可供调课的课次(学员队任务表 + 课表 + 课程表)。 * 查询当前教员可供调课的课次。
* <p>
* 返回值对齐 {@code /adjust/submit} 入参:除事由、备注等需用户填写的项外,
* 其余字段带出当前课次默认值。
* </p>
*/ */
@GetMapping("/adjust/lessons") @GetMapping("/adjust/lessons")
public Result<List<AdjustableLessonVO>> listAdjustableLessons( public Result<List<AdjustableLessonVO>> listAdjustableLessons(
@@ -6,14 +6,19 @@ import com.roomroot.jwgl.service.DisciplineService;
import com.roomroot.jwgl.unit.PageQuery; import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult; import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.unit.Result; import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.discipline.MajorImportResultVO;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/** /**
* 学科专业管理控制器 * 学科专业管理控制器
@@ -212,4 +217,36 @@ public class DisciplineManagementController {
cond.setTy(ty); cond.setTy(ty);
return Result.success(disciplineService.pageMajor(new PageQuery(pageNum, pageSize), cond)); return Result.success(disciplineService.pageMajor(new PageQuery(pageNum, pageSize), cond));
} }
/**
* 从 Excel 导入专业(.xls/.xlsx)。
* <p>
* 表头按专业导入模板的列名匹配(列顺序不限)。已存在的专业跳过、不覆盖库中已有数据;
* 校验不通过的行跳过并在结果明细中给出原因,合格行正常导入。
* </p>
*
* @param file 上传的 Excel 文件(form-data 字段名 file)
* @return 导入结果(新增/跳过/失败数量与明细)
*/
@PostMapping("/major/import")
public Result<MajorImportResultVO> importMajor(@RequestParam("file") MultipartFile file) throws Exception {
MajorImportResultVO result = disciplineService.importMajorExcel(file);
return Result.success(result.getMessage(), result);
}
/**
* 下载专业导入模板(xlsx),列头与导入解析保持一致。
*
* @param response 响应对象
*/
@GetMapping("/major/template")
public void downloadMajorTemplate(HttpServletResponse response) throws Exception {
byte[] bytes = disciplineService.buildMajorImportTemplate();
String fileName = "专业导入模板.xlsx";
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename="
+ URLEncoder.encode(fileName, StandardCharsets.UTF_8));
response.getOutputStream().write(bytes);
response.getOutputStream().flush();
}
} }
@@ -2,6 +2,8 @@ package com.roomroot.web.controller.jwgl;
import com.roomroot.common.exception.ServiceException; import com.roomroot.common.exception.ServiceException;
import com.roomroot.common.utils.file.FileUtils; import com.roomroot.common.utils.file.FileUtils;
import com.roomroot.jwgl.service.TeachingMaterialService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
@@ -23,6 +25,9 @@ public class DownloadController {
private static final String TEMPLATE_DIR = "file/"; private static final String TEMPLATE_DIR = "file/";
@Resource
private TeachingMaterialService teachingMaterialService;
/** /**
* 人才培养方案课程数据文件模板 * 人才培养方案课程数据文件模板
*/ */
@@ -56,11 +61,11 @@ public class DownloadController {
} }
/** /**
* 教材管理模板 * 教材管理模板(动态生成,与 /teachingMaterial/template 一致)
*/ */
@GetMapping("/teaching-material") @GetMapping("/teaching-material")
public void downloadTeachingMaterial(HttpServletResponse response) throws IOException { public void downloadTeachingMaterial(HttpServletResponse response) {
downloadTemplate(response, "教材管理.xls"); teachingMaterialService.downloadTemplate(response);
} }
/** /**
@@ -72,11 +77,156 @@ public class DownloadController {
} }
/** /**
* 联教连训管理模板 * 教员导入模板(动态生成:数据 sheet + 填写说明 sheet)。
* <p>列序与 /jys/teacher/import 解析一致:
* 教员编号、教员姓名、教研室代号、职称、专业技术职务等级、教员类别、
* 性别、手机号、身份证号、备注、序号、虚实类型。</p>
*/
@GetMapping("/jy")
public void downloadJy(HttpServletResponse response) throws IOException {
org.apache.poi.ss.usermodel.Workbook workbook = new org.apache.poi.xssf.usermodel.XSSFWorkbook();
try {
org.apache.poi.ss.usermodel.CellStyle headerStyle = workbook.createCellStyle();
org.apache.poi.ss.usermodel.Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerStyle.setFont(headerFont);
org.apache.poi.ss.usermodel.CellStyle requiredStyle = workbook.createCellStyle();
org.apache.poi.ss.usermodel.Font requiredFont = workbook.createFont();
requiredFont.setBold(true);
requiredFont.setColor(org.apache.poi.ss.usermodel.IndexedColors.RED.getIndex());
requiredStyle.setFont(requiredFont);
String[] headers = {"教员编号", "教员姓名*", "教研室代号*", "职称", "专业技术职务等级",
"教员类别", "性别", "手机号", "身份证号", "备注", "序号", "虚实类型"};
org.apache.poi.ss.usermodel.Sheet dataSheet = workbook.createSheet("教员");
org.apache.poi.ss.usermodel.Row headerRow = dataSheet.createRow(0);
for (int i = 0; i < headers.length; i++) {
org.apache.poi.ss.usermodel.Cell cell = headerRow.createCell(i);
cell.setCellValue(headers[i]);
cell.setCellStyle(headers[i].endsWith("*") ? requiredStyle : headerStyle);
dataSheet.setColumnWidth(i, 16 * 256);
}
String[][] instructions = {
{"教员编号", "选填", "留空则系统自动生成(JY+流水号);手填须唯一"},
{"教员姓名", "必填", "文本"},
{"教研室代号", "必填", "教研室表中的教研室代号(非名称),必须已存在"},
{"职称", "选填", "文本,如:讲师、副教授"},
{"专业技术职务等级", "选填", "文本,如:初级、中级、高级"},
{"教员类别", "选填", "文本,如:专业技术军官"},
{"性别", "选填", "数字:1=男,0=女"},
{"手机号", "选填", "文本"},
{"身份证号", "选填", "文本"},
{"备注", "选填", "文本"},
{"序号", "选填", "数字"},
{"虚实类型", "选填", "数字:0=实员"}
};
org.apache.poi.ss.usermodel.Sheet helpSheet = workbook.createSheet("填写说明");
org.apache.poi.ss.usermodel.Row titleRow = helpSheet.createRow(0);
org.apache.poi.ss.usermodel.Cell titleCell = titleRow.createCell(0);
titleCell.setCellValue("教员导入填写说明(红色表头列为必填;导入只写教员档案不建账号,账号用列表【对齐到用户表】批量开通)");
titleCell.setCellStyle(headerStyle);
String[] helpHeaders = {"列名", "是否必填", "填写说明"};
org.apache.poi.ss.usermodel.Row helpHeaderRow = helpSheet.createRow(1);
for (int i = 0; i < helpHeaders.length; i++) {
org.apache.poi.ss.usermodel.Cell cell = helpHeaderRow.createCell(i);
cell.setCellValue(helpHeaders[i]);
cell.setCellStyle(headerStyle);
}
for (int i = 0; i < instructions.length; i++) {
org.apache.poi.ss.usermodel.Row row = helpSheet.createRow(i + 2);
for (int j = 0; j < 3; j++) {
row.createCell(j).setCellValue(instructions[i][j]);
}
if ("必填".equals(instructions[i][1])) {
row.getCell(1).setCellStyle(requiredStyle);
}
}
helpSheet.setColumnWidth(0, 18 * 256);
helpSheet.setColumnWidth(1, 10 * 256);
helpSheet.setColumnWidth(2, 60 * 256);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
FileUtils.setAttachmentResponseHeader(response, "教员导入模板.xlsx");
workbook.write(response.getOutputStream());
response.getOutputStream().flush();
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new ServiceException("生成教员导入模板失败:" + e.getMessage());
} finally {
try {
workbook.close();
} catch (IOException ignored) {
}
}
}
/**
* 联教联训导入模板(动态生成:宋体表头 + 测试样例)。
* 列序与 ExcelParseUtil.parseKSBZXMExcel 一致。
*/ */
@GetMapping("/joint-training") @GetMapping("/joint-training")
public void downloadJointTraining(HttpServletResponse response) throws IOException { public void downloadJointTraining(HttpServletResponse response) throws IOException {
downloadTemplate(response, "联教连训管理.xls"); org.apache.poi.ss.usermodel.Workbook workbook = new org.apache.poi.xssf.usermodel.XSSFWorkbook();
try {
org.apache.poi.ss.usermodel.Font headerFont = workbook.createFont();
headerFont.setFontName("宋体");
headerFont.setBold(true);
headerFont.setFontHeightInPoints((short) 11);
org.apache.poi.ss.usermodel.CellStyle headerStyle = workbook.createCellStyle();
headerStyle.setFont(headerFont);
org.apache.poi.ss.usermodel.Font dataFont = workbook.createFont();
dataFont.setFontName("宋体");
dataFont.setFontHeightInPoints((short) 11);
org.apache.poi.ss.usermodel.CellStyle dataStyle = workbook.createCellStyle();
dataStyle.setFont(dataFont);
String[] headers = {
"序号", "补助项目名称", "性质", "依据", "开始日期", "结束日期",
"项目说明", "项目备注", "教研室名称", "补助教员姓名", "补助课时量", "课时量备注"
};
org.apache.poi.ss.usermodel.Sheet sheet = workbook.createSheet("联教联训");
org.apache.poi.ss.usermodel.Row headerRow = sheet.createRow(0);
for (int i = 0; i < headers.length; i++) {
org.apache.poi.ss.usermodel.Cell cell = headerRow.createCell(i);
cell.setCellValue(headers[i]);
cell.setCellStyle(headerStyle);
sheet.setColumnWidth(i, 18 * 256);
}
String[][] samples = {
{"1", "联教联训测试项目甲", "集中", "训练计划〔2026〕1号", "2026-03-01", "2026-03-10",
"联合教学演练", "导入测试样例1", "战术教研室", "张三", "16", "含备课课时"},
{"2", "联教联训测试项目乙", "分散", "训练计划〔2026〕2号", "2026-05-08", "2026-05-20",
"跨校区联训", "导入测试样例2", "射击教研室", "李四", "24", ""},
{"3", "联教联训测试项目丙", "集中", "训练计划〔2026〕3号", "2026-09-01", "2026-09-15",
"联训考核", "导入测试样例3", "指挥教研室", "王五", "12", "按天数核算"}
};
for (int r = 0; r < samples.length; r++) {
org.apache.poi.ss.usermodel.Row row = sheet.createRow(r + 1);
for (int c = 0; c < samples[r].length; c++) {
org.apache.poi.ss.usermodel.Cell cell = row.createCell(c);
cell.setCellValue(samples[r][c]);
cell.setCellStyle(dataStyle);
}
}
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
FileUtils.setAttachmentResponseHeader(response, "联教联训数据文件模板.xlsx");
workbook.write(response.getOutputStream());
response.getOutputStream().flush();
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new ServiceException("生成联教联训导入模板失败:" + e.getMessage());
} finally {
try {
workbook.close();
} catch (IOException ignored) {
}
}
} }
/** /**
@@ -344,8 +344,9 @@ public class ElectiveController {
public Result<SemesterInitVO> semesterInit( public Result<SemesterInitVO> semesterInit(
@RequestParam("xydbh") String xydbh, @RequestParam("xydbh") String xydbh,
@RequestParam(required = false) String presetKxrq, @RequestParam(required = false) String presetKxrq,
@RequestParam(required = false) String presetJsrq) { @RequestParam(required = false) String presetJsrq,
return Result.success(electiveService.getSemesterInit(xydbh, presetKxrq, presetJsrq)); @RequestParam(required = false) Integer xqdc) {
return Result.success(electiveService.getSemesterInit(xydbh, presetKxrq, presetJsrq, xqdc));
} }
/** /**
@@ -38,7 +38,7 @@ public class FacultyController {
*/ */
@PostMapping("/office/add") @PostMapping("/office/add")
public Result<Void> addOffice(@RequestBody JYSB entity) { public Result<Void> addOffice(@RequestBody JYSB entity) {
facultyService.addJYSB(entity); facultyService.addJYSB(entity, null);
return Result.success(); return Result.success();
} }
@@ -49,7 +49,7 @@ public class FacultyController {
*/ */
@PostMapping("/office/disable") @PostMapping("/office/disable")
public Result<Void> disableOffice(@RequestParam("jysdh") String jysdh) { public Result<Void> disableOffice(@RequestParam("jysdh") String jysdh) {
facultyService.disableJYSB(jysdh); facultyService.disableJYSB(jysdh, null);
return Result.success(); return Result.success();
} }
@@ -58,7 +58,7 @@ public class FacultyController {
*/ */
@PostMapping("/office/update") @PostMapping("/office/update")
public Result<Void> updateOffice(@RequestBody JYSB entity) { public Result<Void> updateOffice(@RequestBody JYSB entity) {
facultyService.updateJYSB(entity); facultyService.updateJYSB(entity, null);
return Result.success(); return Result.success();
} }
@@ -1,5 +1,7 @@
package com.roomroot.web.controller.jwgl; package com.roomroot.web.controller.jwgl;
import com.roomroot.common.core.domain.entity.SysUser;
import com.roomroot.common.utils.StringUtils;
import com.roomroot.jwgl.dto.faculty.AddTeacherDTO; import com.roomroot.jwgl.dto.faculty.AddTeacherDTO;
import com.roomroot.jwgl.dto.jys.ElectiveCourseBatchDTO; import com.roomroot.jwgl.dto.jys.ElectiveCourseBatchDTO;
import com.roomroot.jwgl.dto.jys.ElectiveCourseQuery; import com.roomroot.jwgl.dto.jys.ElectiveCourseQuery;
@@ -31,6 +33,7 @@ import com.roomroot.jwgl.vo.faculty.TeacherListVO;
import com.roomroot.jwgl.vo.jys.ElectiveCourseVO; import com.roomroot.jwgl.vo.jys.ElectiveCourseVO;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -59,14 +62,19 @@ public class JYSController {
@Resource @Resource
private TeachingTaskManageService teachingTaskManageService; private TeachingTaskManageService teachingTaskManageService;
@Resource
private com.roomroot.jwgl.service.OrgSyncService orgSyncService;
// ======================== 教研室管理 ======================== // ======================== 教研室管理 ========================
/** /**
* 新增教研室 * 新增教研室
*/ */
@PreAuthorize("@ss.hasPermi('teach:office:list')")
@PostMapping("/office/add") @PostMapping("/office/add")
public Result<Void> addOffice(@RequestBody JYSB entity) { public Result<Void> addOffice(@RequestBody JYSB entity,
facultyService.addJYSB(entity); @RequestParam(required = false) Boolean syncDept) {
facultyService.addJYSB(entity, syncDept);
return Result.success(); return Result.success();
} }
@@ -77,26 +85,56 @@ public class JYSController {
* 001 001 军事基础教研室 军基 基础部 * 001 001 军事基础教研室 军基 基础部
* @param jysdh 教研室代号 * @param jysdh 教研室代号
*/ */
@PreAuthorize("@ss.hasPermi('teach:office:list')")
@PostMapping("/office/disable") @PostMapping("/office/disable")
public Result<Void> disableOffice(@RequestParam("jysdh") String jysdh) { public Result<Void> disableOffice(@RequestParam("jysdh") String jysdh,
facultyService.disableJYSB(jysdh); @RequestParam(required = false) Boolean syncDept) {
facultyService.disableJYSB(jysdh, syncDept);
return Result.success(); return Result.success();
} }
/** /**
* 更新教研室 * 更新教研室
*/ */
@PreAuthorize("@ss.hasPermi('teach:office:list')")
@PostMapping("/office/update") @PostMapping("/office/update")
public Result<Void> updateOffice(@RequestBody JYSB entity) { public Result<Void> updateOffice(@RequestBody JYSB entity,
facultyService.updateJYSB(entity); @RequestParam(required = false) Boolean syncDeptName) {
facultyService.updateJYSB(entity, syncDeptName);
return Result.success(); return Result.success();
} }
/**
* 单个教研室补建/对齐组织部门(幂等:已关联则直接返回部门编号)。
*/
@PreAuthorize("@ss.hasPermi('teach:office:list')")
@PostMapping("/office/sync-dept")
public Result<Long> syncOfficeDept(@RequestParam("jysdh") String jysdh) {
JYSB entity = facultyService.getJYSBById(jysdh);
if (entity == null) {
return Result.error("教研室不存在:" + jysdh);
}
return Result.success(orgSyncService.ensureOfficeDept(entity));
}
/**
* 对齐组织部门:为教研室批量创建/复用组织部门(直接执行,幂等)。
* body:{ "ids": ["JYS01", ...] };ids 不传 = 全部教研室。
*/
@PreAuthorize("@ss.hasPermi('teach:office:list')")
@PostMapping("/org/align-dept")
public Result<com.roomroot.jwgl.vo.orgsync.OrgAlignResultVO> alignDepts(
@RequestBody(required = false) java.util.Map<String, List<String>> body) {
List<String> ids = body == null ? null : body.get("ids");
return Result.success(orgSyncService.alignDepts(ids));
}
/** /**
* 根据代号查询教研室详情 * 根据代号查询教研室详情
* *
* @param jysdh 教研室代号 * @param jysdh 教研室代号
*/ */
@PreAuthorize("@ss.hasPermi('teach:office:list')")
@GetMapping("/office/get") @GetMapping("/office/get")
public Result<JYSB> getOffice(@RequestParam("jysdh") String jysdh) { public Result<JYSB> getOffice(@RequestParam("jysdh") String jysdh) {
JYSB entity = facultyService.getJYSBById(jysdh); JYSB entity = facultyService.getJYSBById(jysdh);
@@ -113,13 +151,15 @@ public class JYSController {
* </ul> * </ul>
* </p> * </p>
*/ */
@PreAuthorize("@ss.hasPermi('teach:office:list')")
@GetMapping("/office/list") @GetMapping("/office/list")
public Result<PageResult<JYSB>> listOffice( public Result<PageResult<JYSB>> listOffice(
@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "20") Integer pageSize, @RequestParam(defaultValue = "20") Integer pageSize,
@RequestParam(required = false) String jysdh, @RequestParam(required = false) String jysdh,
@RequestParam(required = false) String jysmc, @RequestParam(required = false) String jysmc,
@RequestParam(required = false) String bx) { @RequestParam(required = false) String bx,
@RequestParam(required = false) String ty) {
PageQuery query = new PageQuery(); PageQuery query = new PageQuery();
query.setPageNum(pageNum); query.setPageNum(pageNum);
query.setPageSize(pageSize); query.setPageSize(pageSize);
@@ -127,6 +167,7 @@ public class JYSController {
cond.setJysdh(jysdh); cond.setJysdh(jysdh);
cond.setJysmc(jysmc); cond.setJysmc(jysmc);
cond.setBx(bx); cond.setBx(bx);
cond.setTy(StringUtils.hasText(ty) ? Integer.valueOf(ty) : null);
PageResult<JYSB> pageResult = facultyService.pageJYSB(query, cond); PageResult<JYSB> pageResult = facultyService.pageJYSB(query, cond);
return Result.success(pageResult); return Result.success(pageResult);
} }
@@ -140,9 +181,11 @@ public class JYSController {
* 未填写时返回"XX未填写";序号、停用、虚实类型等非空字段由后台自动填充。 * 未填写时返回"XX未填写";序号、停用、虚实类型等非空字段由后台自动填充。
* </p> * </p>
*/ */
@PreAuthorize("@ss.hasPermi('teach:office:list')")
@PostMapping("/office/import") @PostMapping("/office/import")
public Result<Integer> importOffice(@RequestParam("file") MultipartFile file) throws Exception { public Result<Integer> importOffice(@RequestParam("file") MultipartFile file,
int count = facultyService.importJYSBFromExcel(file); @RequestParam(required = false) Boolean syncDept) throws Exception {
int count = facultyService.importJYSBFromExcel(file, syncDept);
return Result.success("导入成功,共" + count + "条记录", count); return Result.success("导入成功,共" + count + "条记录", count);
} }
// ======================== 教员管理 ======================== // ======================== 教员管理 ========================
@@ -151,6 +194,7 @@ public class JYSController {
* 新增教员(同时写入教员表和教员属性表) * 新增教员(同时写入教员表和教员属性表)
* <p>教员属性中的非空字段由前端一并传入。</p> * <p>教员属性中的非空字段由前端一并传入。</p>
*/ */
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@PostMapping("/teacher/add") @PostMapping("/teacher/add")
public Result<Void> addTeacher(@RequestBody AddTeacherDTO dto) { public Result<Void> addTeacher(@RequestBody AddTeacherDTO dto) {
facultyService.addJYB(dto); facultyService.addJYB(dto);
@@ -162,16 +206,77 @@ public class JYSController {
* *
* @param jybh 教员编号 * @param jybh 教员编号
*/ */
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@PostMapping("/teacher/disable") @PostMapping("/teacher/disable")
public Result<Void> disableTeacher(@RequestParam("jybh") String jybh) { public Result<Void> disableTeacher(@RequestParam("jybh") String jybh) {
facultyService.disableJYB(jybh); facultyService.disableJYB(jybh);
return Result.success(); return Result.success();
} }
/**
* 复职(还原离职状态)教员
*
* @param jybh 教员编号
*/
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@PostMapping("/teacher/enable")
public Result<Void> enableTeacher(@RequestParam("jybh") String jybh) {
facultyService.enableJYB(jybh);
return Result.success();
}
/**
* 单个教员补建/对齐系统账号(幂等:已有账号直接返回用户编号)。
*/
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@PostMapping("/teacher/sync-user")
public Result<Long> syncTeacherUser(@RequestParam("jybh") String jybh,
@RequestParam(required = false) String loginName,
@RequestParam(required = false) String password,
@RequestParam(required = false) Long roleId) {
JYB entity = facultyService.getJYBById(jybh);
if (entity == null) {
return Result.error("教员不存在:" + jybh);
}
SysUser user = orgSyncService.ensureTeacherUser(entity, loginName, password, roleId);
String expected = StringUtils.hasText(loginName) ? loginName.trim() : jybh;
if (!expected.equals(user.getUserName())) {
return Result.success("登录名 " + expected + " 已被无关账号占用,已自动改用 "
+ user.getUserName(), user.getUserId());
}
return Result.success(user.getUserId());
}
/**
* 对齐到用户表:为无账号教员批量建账号(直接执行,幂等,逐条返回明细)。
* body:{ "ids": ["JY01", ...] };ids 不传 = 全部无账号教员。
*/
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@PostMapping("/teacher/align-user")
public Result<com.roomroot.jwgl.vo.orgsync.OrgAlignResultVO> alignUsers(
@RequestBody(required = false) java.util.Map<String, List<String>> body) {
List<String> ids = body == null ? null : body.get("ids");
return Result.success(orgSyncService.alignUsers(ids));
}
/**
* 一键对齐:先对齐组织部门、再对齐用户账号(同一事务,幂等)。
*/
@PreAuthorize("@ss.hasPermi('teach:office:list') and @ss.hasPermi('teach:teacher:list')")
@PostMapping("/org/align-apply")
public Result<java.util.Map<String, com.roomroot.jwgl.vo.orgsync.OrgAlignResultVO>> alignApply() {
java.util.Map<String, com.roomroot.jwgl.vo.orgsync.OrgAlignResultVO> result =
new java.util.LinkedHashMap<>();
result.put("dept", orgSyncService.alignDepts(null));
result.put("user", orgSyncService.alignUsers(null));
return Result.success(result);
}
/** /**
* 更新教员基本信息 * 更新教员基本信息
* <p>支持教学单位调整(修改教研室代号)、职称调整(修改职称、专业技术职务等级)。</p> * <p>支持教学单位调整(修改教研室代号)、职称调整(修改职称、专业技术职务等级)。</p>
*/ */
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@PostMapping("/teacher/update") @PostMapping("/teacher/update")
public Result<Void> updateTeacher(@RequestBody JYB entity) { public Result<Void> updateTeacher(@RequestBody JYB entity) {
facultyService.updateJYB(entity); facultyService.updateJYB(entity);
@@ -183,6 +288,7 @@ public class JYSController {
* *
* @param jybh 教员编号 * @param jybh 教员编号
*/ */
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@GetMapping("/teacher/get") @GetMapping("/teacher/get")
public Result<JYB> getTeacher(@RequestParam("jybh") String jybh) { public Result<JYB> getTeacher(@RequestParam("jybh") String jybh) {
JYB entity = facultyService.getJYBById(jybh); JYB entity = facultyService.getJYBById(jybh);
@@ -201,6 +307,7 @@ public class JYSController {
* </ul> * </ul>
* </p> * </p>
*/ */
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@GetMapping("/teacher/list") @GetMapping("/teacher/list")
public Result<PageResult<TeacherListVO>> listTeacher( public Result<PageResult<TeacherListVO>> listTeacher(
@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "1") Integer pageNum,
@@ -208,7 +315,8 @@ public class JYSController {
@RequestParam(required = false) String jyxm, @RequestParam(required = false) String jyxm,
@RequestParam(required = false) String jysdh, @RequestParam(required = false) String jysdh,
@RequestParam(required = false) String zc, @RequestParam(required = false) String zc,
@RequestParam(required = false) String jylb) { @RequestParam(required = false) String jylb,
@RequestParam(required = false) Integer lzzt) {
PageQuery query = new PageQuery(); PageQuery query = new PageQuery();
query.setPageNum(pageNum); query.setPageNum(pageNum);
query.setPageSize(pageSize); query.setPageSize(pageSize);
@@ -217,15 +325,26 @@ public class JYSController {
cond.setJysdh(jysdh); cond.setJysdh(jysdh);
cond.setZc(zc); cond.setZc(zc);
cond.setJylb(jylb); cond.setJylb(jylb);
cond.setLzzt(lzzt);
PageResult<TeacherListVO> pageResult = facultyService.pageJYBDetail(query, cond); PageResult<TeacherListVO> pageResult = facultyService.pageJYBDetail(query, cond);
return Result.success(pageResult); return Result.success(pageResult);
} }
/**
* 去重职称列表(职称检索下拉数据源,职称无字典表)
*/
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@GetMapping("/teacher/zc-options")
public Result<java.util.List<String>> teacherZcOptions() {
return Result.success(facultyService.listDistinctZc());
}
/** /**
* 教员数据文件导入(.xls/.xlsx) * 教员数据文件导入(.xls/.xlsx)
* <p>表头顺序:教员编号, 教员姓名, 教研室代号, 职称, 专业技术职务等级, 教员类别, * <p>表头顺序:教员编号, 教员姓名, 教研室代号, 职称, 专业技术职务等级, 教员类别,
* 性别, 手机号, 身份证号, 备注, 序号, 虚实类型。教员编号不填自动创建,离职状态默认 0。</p> * 性别, 手机号, 身份证号, 备注, 序号, 虚实类型。教员编号不填自动创建,离职状态默认 0。</p>
*/ */
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@PostMapping("/teacher/import") @PostMapping("/teacher/import")
public Result<Integer> importTeacher(@RequestParam("file") MultipartFile file) throws Exception { public Result<Integer> importTeacher(@RequestParam("file") MultipartFile file) throws Exception {
int count = facultyService.importJYBFromExcel(file); int count = facultyService.importJYBFromExcel(file);
@@ -235,6 +354,7 @@ public class JYSController {
/** /**
* 导出全部在职教员到 Excel(.xlsx)。 * 导出全部在职教员到 Excel(.xlsx)。
*/ */
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@GetMapping("/teacher/export") @GetMapping("/teacher/export")
public void exportTeacher(HttpServletResponse response) throws Exception { public void exportTeacher(HttpServletResponse response) throws Exception {
facultyService.exportJYBExcel(response); facultyService.exportJYBExcel(response);
@@ -247,6 +367,7 @@ public class JYSController {
* *
* @param jybh 教员编号 * @param jybh 教员编号
*/ */
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@GetMapping("/teacher/attribute/get") @GetMapping("/teacher/attribute/get")
public Result<JYSX> getTeacherAttribute(@RequestParam("jybh") String jybh) { public Result<JYSX> getTeacherAttribute(@RequestParam("jybh") String jybh) {
JYSX entity = facultyService.getJYSXByJYBH(jybh); JYSX entity = facultyService.getJYSXByJYBH(jybh);
@@ -257,6 +378,7 @@ public class JYSController {
* 更新教员属性 * 更新教员属性
* <p>支持岗位调整(修改职务、职务时间)和技术等级调整(修改技术等级、技术等级时间)。</p> * <p>支持岗位调整(修改职务、职务时间)和技术等级调整(修改技术等级、技术等级时间)。</p>
*/ */
@PreAuthorize("@ss.hasPermi('teach:teacher:list')")
@PostMapping("/teacher/attribute/update") @PostMapping("/teacher/attribute/update")
public Result<Void> updateTeacherAttribute(@RequestBody JYSX entity) { public Result<Void> updateTeacherAttribute(@RequestBody JYSX entity) {
facultyService.updateJYSX(entity); facultyService.updateJYSX(entity);
@@ -272,6 +394,7 @@ public class JYSController {
* @param entity 课表实体 * @param entity 课表实体
* @return 操作结果 * @return 操作结果
*/ */
@PreAuthorize("@ss.hasPermi('teach:subject:list')")
@PostMapping("/kb/add") @PostMapping("/kb/add")
public Result<Void> addKb(@RequestBody KB entity) { public Result<Void> addKb(@RequestBody KB entity) {
kbService.add(entity); kbService.add(entity);
@@ -285,6 +408,7 @@ public class JYSController {
* @param kbh 课编号 * @param kbh 课编号
* @return 操作结果 * @return 操作结果
*/ */
@PreAuthorize("@ss.hasPermi('teach:subject:list')")
@PostMapping("/kb/delete") @PostMapping("/kb/delete")
public Result<Void> deleteKb(@RequestParam("kbh") String kbh) { public Result<Void> deleteKb(@RequestParam("kbh") String kbh) {
kbService.delete(kbh); kbService.delete(kbh);
@@ -297,6 +421,7 @@ public class JYSController {
* @param entity 课表实体(须含课编号) * @param entity 课表实体(须含课编号)
* @return 操作结果 * @return 操作结果
*/ */
@PreAuthorize("@ss.hasPermi('teach:subject:list')")
@PostMapping("/kb/update") @PostMapping("/kb/update")
public Result<Void> updateKb(@RequestBody KB entity) { public Result<Void> updateKb(@RequestBody KB entity) {
kbService.update(entity); kbService.update(entity);
@@ -309,6 +434,7 @@ public class JYSController {
* @param kbh 课编号 * @param kbh 课编号
* @return 课表详情 * @return 课表详情
*/ */
@PreAuthorize("@ss.hasPermi('teach:subject:list')")
@GetMapping("/kb/get") @GetMapping("/kb/get")
public Result<KB> getKb(@RequestParam("kbh") String kbh) { public Result<KB> getKb(@RequestParam("kbh") String kbh) {
return Result.success(kbService.getByKbh(kbh)); return Result.success(kbService.getByKbh(kbh));
@@ -328,6 +454,7 @@ public class JYSController {
* @param jc 简称(模糊,可选) * @param jc 简称(模糊,可选)
* @return 分页结果 * @return 分页结果
*/ */
@PreAuthorize("@ss.hasPermi('teach:subject:list')")
@GetMapping("/kb/list") @GetMapping("/kb/list")
public Result<PageResult<KB>> listKb( public Result<PageResult<KB>> listKb(
@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "1") Integer pageNum,
@@ -359,6 +486,7 @@ public class JYSController {
* 支持按授课教员、课程科目名称、可选班次年级、选修班名称、选择课状态、培训层次筛选。 * 支持按授课教员、课程科目名称、可选班次年级、选修班名称、选择课状态、培训层次筛选。
* </p> * </p>
*/ */
@PreAuthorize("@ss.hasPermi('teach:elective:list')")
@GetMapping("/elective/list") @GetMapping("/elective/list")
public Result<PageResult<ElectiveCourseVO>> listElective( public Result<PageResult<ElectiveCourseVO>> listElective(
@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "1") Integer pageNum,
@@ -382,6 +510,7 @@ public class JYSController {
/** /**
* 新建选修课。 * 新建选修课。
*/ */
@PreAuthorize("@ss.hasPermi('teach:elective:list')")
@PostMapping("/elective/add") @PostMapping("/elective/add")
public Result<Void> addElective(@RequestBody ElectiveCourseSaveDTO dto) { public Result<Void> addElective(@RequestBody ElectiveCourseSaveDTO dto) {
electiveCourseService.add(dto); electiveCourseService.add(dto);
@@ -391,6 +520,7 @@ public class JYSController {
/** /**
* 所选批量开放报名。 * 所选批量开放报名。
*/ */
@PreAuthorize("@ss.hasPermi('teach:elective:list')")
@PostMapping("/elective/batch-open") @PostMapping("/elective/batch-open")
public Result<Integer> batchOpenElective(@RequestBody ElectiveCourseBatchDTO dto) { public Result<Integer> batchOpenElective(@RequestBody ElectiveCourseBatchDTO dto) {
int count = electiveCourseService.batchOpenRegistration(dto == null ? null : dto.getBhList()); int count = electiveCourseService.batchOpenRegistration(dto == null ? null : dto.getBhList());
@@ -400,6 +530,7 @@ public class JYSController {
/** /**
* 所选批量取消开放报名。 * 所选批量取消开放报名。
*/ */
@PreAuthorize("@ss.hasPermi('teach:elective:list')")
@PostMapping("/elective/batch-cancel-open") @PostMapping("/elective/batch-cancel-open")
public Result<Integer> batchCancelOpenElective(@RequestBody ElectiveCourseBatchDTO dto) { public Result<Integer> batchCancelOpenElective(@RequestBody ElectiveCourseBatchDTO dto) {
int count = electiveCourseService.batchCancelOpenRegistration(dto == null ? null : dto.getBhList()); int count = electiveCourseService.batchCancelOpenRegistration(dto == null ? null : dto.getBhList());
@@ -409,6 +540,7 @@ public class JYSController {
/** /**
* 批量停止报名。 * 批量停止报名。
*/ */
@PreAuthorize("@ss.hasPermi('teach:elective:list')")
@PostMapping("/elective/batch-stop") @PostMapping("/elective/batch-stop")
public Result<Integer> batchStopElective(@RequestBody ElectiveCourseBatchDTO dto) { public Result<Integer> batchStopElective(@RequestBody ElectiveCourseBatchDTO dto) {
int count = electiveCourseService.batchStopRegistration(dto == null ? null : dto.getBhList()); int count = electiveCourseService.batchStopRegistration(dto == null ? null : dto.getBhList());
@@ -418,6 +550,7 @@ public class JYSController {
/** /**
* 所选批量根据学员反向确定班次范围。 * 所选批量根据学员反向确定班次范围。
*/ */
@PreAuthorize("@ss.hasPermi('teach:elective:list')")
@PostMapping("/elective/batch-reverse-range") @PostMapping("/elective/batch-reverse-range")
public Result<Integer> batchReverseRangeElective(@RequestBody ElectiveCourseBatchDTO dto) { public Result<Integer> batchReverseRangeElective(@RequestBody ElectiveCourseBatchDTO dto) {
int count = electiveCourseService.batchReverseClassRange(dto == null ? null : dto.getBhList()); int count = electiveCourseService.batchReverseClassRange(dto == null ? null : dto.getBhList());
@@ -427,6 +560,7 @@ public class JYSController {
/** /**
* 下载选修班列表。 * 下载选修班列表。
*/ */
@PreAuthorize("@ss.hasPermi('teach:elective:list')")
@GetMapping("/elective/export") @GetMapping("/elective/export")
public void exportElective( public void exportElective(
@RequestParam(required = false) String jyxm, @RequestParam(required = false) String jyxm,
@@ -449,6 +583,7 @@ public class JYSController {
/** /**
* 下载选修班学员名单 Excel。 * 下载选修班学员名单 Excel。
*/ */
@PreAuthorize("@ss.hasPermi('teach:elective:list')")
@GetMapping("/elective/students/export-excel") @GetMapping("/elective/students/export-excel")
public void exportElectiveStudentExcel(@RequestParam("bhList") List<String> bhList, public void exportElectiveStudentExcel(@RequestParam("bhList") List<String> bhList,
HttpServletResponse response) { HttpServletResponse response) {
@@ -458,6 +593,7 @@ public class JYSController {
/** /**
* 下载选修班学员名单 Word。 * 下载选修班学员名单 Word。
*/ */
@PreAuthorize("@ss.hasPermi('teach:elective:list')")
@GetMapping("/elective/students/export-word") @GetMapping("/elective/students/export-word")
public void exportElectiveStudentWord(@RequestParam("bhList") List<String> bhList, public void exportElectiveStudentWord(@RequestParam("bhList") List<String> bhList,
HttpServletResponse response) { HttpServletResponse response) {
@@ -469,6 +605,7 @@ public class JYSController {
/** /**
* 上传选修课数据。 * 上传选修课数据。
*/ */
@PreAuthorize("@ss.hasPermi('teach:elective:list')")
@PostMapping("/elective/import") @PostMapping("/elective/import")
public Result<Integer> importElective(@RequestParam("file") MultipartFile file) throws Exception { public Result<Integer> importElective(@RequestParam("file") MultipartFile file) throws Exception {
int count = electiveCourseService.importData(file); int count = electiveCourseService.importData(file);
@@ -481,6 +618,7 @@ public class JYSController {
* 分页查询教学任务列表。 * 分页查询教学任务列表。
* <p>含教研室数、学员队数、合班前后课程任务数和学时。未传年度时按当前学期。</p> * <p>含教研室数、学员队数、合班前后课程任务数和学时。未传年度时按当前学期。</p>
*/ */
@PreAuthorize("@ss.hasPermi('teach:taskPlan:list')")
@GetMapping("/task/list") @GetMapping("/task/list")
public Result<PageResult<TeachingTaskVO>> listTask( public Result<PageResult<TeachingTaskVO>> listTask(
@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "1") Integer pageNum,
@@ -500,6 +638,7 @@ public class JYSController {
/** /**
* 教学任务详情(含教研室任务书、学员队两个页签)。 * 教学任务详情(含教研室任务书、学员队两个页签)。
*/ */
@PreAuthorize("@ss.hasPermi('teach:taskPlan:list')")
@GetMapping("/task/get") @GetMapping("/task/get")
public Result<TeachingTaskDetailVO> getTask(@RequestParam("bh") String bh) { public Result<TeachingTaskDetailVO> getTask(@RequestParam("bh") String bh) {
return Result.success(teachingTaskManageService.getDetail(bh)); return Result.success(teachingTaskManageService.getDetail(bh));
@@ -509,6 +648,7 @@ public class JYSController {
* 新增教学任务。 * 新增教学任务。
* <p>机关发布;关联学员队后按专业教学计划和课表归属教研室生成教研室任务书。</p> * <p>机关发布;关联学员队后按专业教学计划和课表归属教研室生成教研室任务书。</p>
*/ */
@PreAuthorize("@ss.hasPermi('teach:taskPlan:list')")
@PostMapping("/task/add") @PostMapping("/task/add")
public Result<Void> addTask(@RequestBody TeachingTaskSaveDTO dto) { public Result<Void> addTask(@RequestBody TeachingTaskSaveDTO dto) {
teachingTaskManageService.add(dto); teachingTaskManageService.add(dto);
@@ -518,6 +658,7 @@ public class JYSController {
/** /**
* 编辑教学任务。 * 编辑教学任务。
*/ */
@PreAuthorize("@ss.hasPermi('teach:taskPlan:list')")
@PostMapping("/task/update") @PostMapping("/task/update")
public Result<Void> updateTask(@RequestBody TeachingTaskSaveDTO dto) { public Result<Void> updateTask(@RequestBody TeachingTaskSaveDTO dto) {
teachingTaskManageService.update(dto); teachingTaskManageService.update(dto);
@@ -527,6 +668,7 @@ public class JYSController {
/** /**
* 删除教学任务(同时逻辑删除教研室任务书,并解除学员队关联)。 * 删除教学任务(同时逻辑删除教研室任务书,并解除学员队关联)。
*/ */
@PreAuthorize("@ss.hasPermi('teach:taskPlan:list')")
@PostMapping("/task/delete") @PostMapping("/task/delete")
public Result<Void> deleteTask(@RequestParam("bh") String bh) { public Result<Void> deleteTask(@RequestParam("bh") String bh) {
teachingTaskManageService.delete(bh); teachingTaskManageService.delete(bh);
@@ -536,15 +678,27 @@ public class JYSController {
/** /**
* 发布教学任务,并同步发布关联的教研室任务书。 * 发布教学任务,并同步发布关联的教研室任务书。
*/ */
@PreAuthorize("@ss.hasPermi('teach:taskPlan:list')")
@PostMapping("/task/publish") @PostMapping("/task/publish")
public Result<Integer> publishTask(@RequestParam("bh") String bh) { public Result<Integer> publishTask(@RequestParam("bh") String bh) {
int count = teachingTaskManageService.publish(bh); int count = teachingTaskManageService.publish(bh);
return Result.success("已发布,同步教研室任务书 " + count + " 份", count); return Result.success("已发布,同步教研室任务书 " + count + " 份", count);
} }
/**
* 结束发布。结束后任务书和课程任务只读。
*/
@PreAuthorize("@ss.hasPermi('teach:taskPlan:list')")
@PostMapping("/task/endPublish")
public Result<Void> endPublishTask(@RequestParam("bh") String bh) {
teachingTaskManageService.endPublish(bh);
return Result.success();
}
/** /**
* 教研室任务书列表。 * 教研室任务书列表。
*/ */
@PreAuthorize("@ss.hasPermi('teach:taskPlan:list')")
@GetMapping("/task/office-book/list") @GetMapping("/task/office-book/list")
public Result<List<TeachingOfficeBookVO>> listTaskOfficeBooks(@RequestParam("jxrwbh") String jxrwbh) { public Result<List<TeachingOfficeBookVO>> listTaskOfficeBooks(@RequestParam("jxrwbh") String jxrwbh) {
return Result.success(teachingTaskManageService.listOfficeBooks(jxrwbh)); return Result.success(teachingTaskManageService.listOfficeBooks(jxrwbh));
@@ -553,6 +707,7 @@ public class JYSController {
/** /**
* 教研室任务书详细(该教研室在本任务下的课程任务)。 * 教研室任务书详细(该教研室在本任务下的课程任务)。
*/ */
@PreAuthorize("@ss.hasPermi('teach:taskPlan:list')")
@GetMapping("/task/office-book/courses") @GetMapping("/task/office-book/courses")
public Result<List<TeachingOfficeBookCourseVO>> listTaskOfficeBookCourses( public Result<List<TeachingOfficeBookCourseVO>> listTaskOfficeBookCourses(
@RequestParam("jxrwbh") String jxrwbh, @RequestParam("jxrwbh") String jxrwbh,
@@ -563,6 +718,7 @@ public class JYSController {
/** /**
* 教学任务已关联学员队。 * 教学任务已关联学员队。
*/ */
@PreAuthorize("@ss.hasPermi('teach:taskPlan:list')")
@GetMapping("/task/squad/list") @GetMapping("/task/squad/list")
public Result<List<TeachingTaskSquadVO>> listTaskSquads(@RequestParam("jxrwbh") String jxrwbh) { public Result<List<TeachingTaskSquadVO>> listTaskSquads(@RequestParam("jxrwbh") String jxrwbh) {
return Result.success(teachingTaskManageService.listBoundSquads(jxrwbh)); return Result.success(teachingTaskManageService.listBoundSquads(jxrwbh));
@@ -571,6 +727,7 @@ public class JYSController {
/** /**
* 某学期可选学员队(未占用或占用当前任务)。年度、学期第次为空时取当前学期。 * 某学期可选学员队(未占用或占用当前任务)。年度、学期第次为空时取当前学期。
*/ */
@PreAuthorize("@ss.hasPermi('teach:taskPlan:list')")
@GetMapping("/task/squad/available") @GetMapping("/task/squad/available")
public Result<List<TeachingTaskSquadVO>> listAvailableTaskSquads( public Result<List<TeachingTaskSquadVO>> listAvailableTaskSquads(
@RequestParam(required = false) Integer nd, @RequestParam(required = false) Integer nd,
@@ -1,17 +1,26 @@
package com.roomroot.web.controller.jwgl; package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.dto.kcb.TimetableGridQuery;
import com.roomroot.jwgl.dto.kcb.TimetableQuery; import com.roomroot.jwgl.dto.kcb.TimetableQuery;
import com.roomroot.jwgl.entity.KCB; import com.roomroot.jwgl.entity.KCB;
import com.roomroot.jwgl.service.KCBService; import com.roomroot.jwgl.service.KCBService;
import com.roomroot.jwgl.service.TimetableGridService;
import com.roomroot.jwgl.unit.PageQuery; import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult; import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.unit.Result; import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.kcb.ClassTimetableVO; import com.roomroot.jwgl.vo.kcb.ClassTimetableVO;
import com.roomroot.jwgl.vo.kcb.DailyWeeklyTimetableRangeVO;
import com.roomroot.jwgl.vo.kcb.DailyWeeklyTimetableVO; import com.roomroot.jwgl.vo.kcb.DailyWeeklyTimetableVO;
import com.roomroot.jwgl.vo.kcb.FreePeriodsVO;
import com.roomroot.jwgl.vo.kcb.TimetableGridVO;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
/** /**
@@ -24,6 +33,9 @@ public class KCBController {
@Resource @Resource
private KCBService kcbService; private KCBService kcbService;
@Resource
private TimetableGridService timetableGridService;
/** /**
* 新增 * 新增
*/ */
@@ -77,19 +89,29 @@ public class KCBController {
} }
/** /**
* 今日课表。未传年度时按当前时间取本学期,可按队别班次筛选。 * 今日课表。可连续点上一天 / 下一天。
* <p>
* 首次不传参数查当天。之后把返回的 {@code rq} 回传,并传 offset:-1 上一天,1 下一天。
* </p>
*/ */
@GetMapping("/today/list") @GetMapping("/today/list")
public Result<List<DailyWeeklyTimetableVO>> listToday(TimetableQuery cond) { public Result<DailyWeeklyTimetableRangeVO> listToday(
return Result.success(kcbService.listToday(cond)); @RequestParam(value = "rq", required = false) String rq,
@RequestParam(value = "offset", required = false) Integer offset) {
return Result.success(kcbService.listToday(rq, offset));
} }
/** /**
* 本周课表(周一至周日)。未传年度时按当前时间取本学期,可按队别班次筛选。 * 本周课表(周一至周日)。可连续点上一周 / 下一周。
* <p>
* 首次不传参数查本周。之后把返回的 {@code rq} 回传,并传 offset:-1 上一周,1 下一周。
* </p>
*/ */
@GetMapping("/week/list") @GetMapping("/week/list")
public Result<List<DailyWeeklyTimetableVO>> listWeek(TimetableQuery cond) { public Result<DailyWeeklyTimetableRangeVO> listWeek(
return Result.success(kcbService.listWeek(cond)); @RequestParam(value = "rq", required = false) String rq,
@RequestParam(value = "offset", required = false) Integer offset) {
return Result.success(kcbService.listWeek(rq, offset));
} }
/** /**
@@ -123,4 +145,47 @@ public class KCBController {
public void exportClassCourses(TimetableQuery cond, HttpServletResponse response) { public void exportClassCourses(TimetableQuery cond, HttpServletResponse response) {
kcbService.exportClassCourses(cond, response); kcbService.exportClassCourses(cond, response);
} }
/**
* 周次横版课表网格(手册一第12章)。
* <p>dim=semester|team|teacher|room,id 为对应编号;可传 mbbh 套用课表模板。</p>
*/
@GetMapping("/grid")
public Result<TimetableGridVO> grid(TimetableGridQuery query) {
return Result.success(timetableGridService.grid(query));
}
/**
* 网格课表矩阵 Excel 导出(每周一个 sheet,节次 × 星期)。
*/
@GetMapping("/grid/export")
public ResponseEntity<byte[]> exportGrid(TimetableGridQuery query) {
byte[] bytes = timetableGridService.exportGrid(query);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
String name = "课表_" + query.getDim() + ".xlsx";
headers.setContentDispositionFormData("attachment",
new String(name.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
return ResponseEntity.ok().headers(headers).body(bytes);
}
/**
* 有课/无课时段查询:按日期给出 busy(有课节次)与 free(无课节次)。
* <p>dim=semester|team|teacher|room,id 为对应编号;start/end 缺省本周。</p>
*/
@GetMapping("/freeSlots")
public Result<FreePeriodsVO> freeSlots(TimetableGridQuery query) {
return Result.success(timetableGridService.freePeriods(query));
}
/**
* 课次综合查询:按 年度/学期/学员队/教员/教室/教研室/学员 组合过滤课次日历。
* <p>学员账号只看本队;教员只看本人;教研室只看本室课程。</p>
*/
@GetMapping("/lessons")
public Result<List<DailyWeeklyTimetableVO>> listLessons(TimetableQuery cond,
@RequestParam(value = "start", required = false) String start,
@RequestParam(value = "end", required = false) String end) {
return Result.success(kcbService.listLessons(cond, start, end));
}
} }
@@ -0,0 +1,63 @@
package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.entity.KCBMBB;
import com.roomroot.jwgl.service.KCBMBService;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.unit.Result;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import java.util.List;
/**
* 课表模版管理(手册一第12章;CRUD + 启停 + 下拉选项)
*/
@RestController
@RequestMapping("/kcbmb")
public class KCBMBController {
@Resource
private KCBMBService kcbmbService;
@GetMapping("/list")
public Result<PageResult<KCBMBB>> list(PageQuery query, @RequestParam(required = false) String mbmc) {
return Result.success(kcbmbService.page(query, mbmc));
}
@GetMapping("/get")
public Result<KCBMBB> get(@RequestParam("bh") String bh) {
return Result.success(kcbmbService.get(bh));
}
/** 可用模板下拉(课表生成页套用选择) */
@GetMapping("/options")
public Result<List<KCBMBB>> options() {
return Result.success(kcbmbService.options());
}
@PostMapping("/add")
public Result<Void> add(@RequestBody KCBMBB tpl) {
kcbmbService.add(tpl);
return Result.success();
}
@PostMapping("/update")
public Result<Void> update(@RequestBody KCBMBB tpl) {
kcbmbService.update(tpl);
return Result.success();
}
@PostMapping("/delete")
public Result<Void> delete(@RequestParam("bh") String bh) {
kcbmbService.delete(bh);
return Result.success();
}
/** 启用/停用模版 */
@PostMapping("/toggle")
public Result<Void> toggle(@RequestParam("bh") String bh, @RequestParam("enabled") boolean enabled) {
kcbmbService.toggle(bh, enabled);
return Result.success();
}
}
@@ -195,6 +195,17 @@ public class KSController {
return Result.success(ksService.pageHourStatistics(new PageQuery(pageNum, pageSize), cond)); return Result.success(ksService.pageHourStatistics(new PageQuery(pageNum, pageSize), cond));
} }
/**
* 课时核算:按指定自然年的已排课次聚合生成课时统计表(覆盖该年数据)。
* 仅教务人员可执行。
*
* @param year 自然年(可选,默认当前年)
*/
@PostMapping("/hour-stat/recalculate")
public Result<Integer> recalcHourStatistics(@RequestParam(required = false) Integer year) {
return Result.success(ksService.recalcHourStatistics(year));
}
/** /**
* 导出课时统计 Excel。 * 导出课时统计 Excel。
*/ */
@@ -198,7 +198,7 @@ public class LogController {
@GetMapping("/teaching-log/download-template") @GetMapping("/teaching-log/download-template")
public void downloadTemplate(HttpServletResponse response) { public void downloadTemplate(HttpServletResponse response) {
try { try {
java.io.InputStream is = getClass().getClassLoader().getResourceAsStream("template/导入教学日志模板.xls"); java.io.InputStream is = getClass().getClassLoader().getResourceAsStream("file/导入教学日志模板.xls");
if (is == null) { if (is == null) {
response.setStatus(404); response.setStatus(404);
return; return;
@@ -0,0 +1,109 @@
package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.service.MyBusinessService;
import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.kcb.ClassTimetableVO;
import com.roomroot.jwgl.vo.kcb.DailyWeeklyTimetableVO;
import com.roomroot.jwgl.vo.kcb.TimetableGridVO;
import com.roomroot.jwgl.vo.mybusiness.MyCourseTaskVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
* 「我的教学」角色视图接口(阶段 C)。
*
* <p>教员/教研室/学员维度全部由服务端按登录身份解析,
* 不接受调用方传入他人编号。</p>
*/
@RestController
@RequestMapping("/my")
public class MyBusinessController {
@Autowired
private MyBusinessService myBusinessService;
// ==================== 教员 ====================
/** 本教员课程任务 */
@GetMapping("/teacher/courses")
public Result<List<MyCourseTaskVO>> teacherCourses(@RequestParam(value = "nd", required = false) Integer nd,
@RequestParam(value = "xqdc", required = false) Integer xqdc) {
return Result.success(myBusinessService.teacherCourses(nd, xqdc));
}
/** 本教员实施计划(默认本周) */
@GetMapping("/teacher/lessons")
public Result<List<DailyWeeklyTimetableVO>> teacherLessons(@RequestParam(value = "start", required = false) String start,
@RequestParam(value = "end", required = false) String end,
@RequestParam(value = "nd", required = false) Integer nd) {
return Result.success(myBusinessService.teacherLessons(start, end, nd));
}
/** 本教员课表网格 */
@GetMapping("/teacher/grid")
public Result<TimetableGridVO> teacherGrid(@RequestParam(value = "mbbh", required = false) String mbbh,
@RequestParam(value = "start", required = false) String start,
@RequestParam(value = "end", required = false) String end,
@RequestParam(value = "nd", required = false) Integer nd) {
return Result.success(myBusinessService.teacherGrid(mbbh, start, end, nd));
}
// ==================== 教研室 ====================
/** 今日本室计划 */
@GetMapping("/office/today")
public Result<List<DailyWeeklyTimetableVO>> officeToday(@RequestParam(value = "rq", required = false) String rq,
@RequestParam(value = "offset", required = false) Integer offset) {
return Result.success(myBusinessService.officeToday(rq, offset));
}
/** 本室课程 */
@GetMapping("/office/courses")
public Result<List<ClassTimetableVO>> officeCourses(@RequestParam(value = "nd", required = false) Integer nd,
@RequestParam(value = "xqdc", required = false) Integer xqdc) {
return Result.success(myBusinessService.officeCourses(nd, xqdc));
}
/** 本室教员清单 */
@GetMapping("/office/teachers")
public Result<List<Map<String, Object>>> officeTeachers() {
return Result.success(myBusinessService.officeTeachers());
}
// ==================== 学员 ====================
/** 本学员队课程列表 */
@GetMapping("/student/courses")
public Result<List<ClassTimetableVO>> studentCourses(@RequestParam(value = "nd", required = false) Integer nd,
@RequestParam(value = "xqdc", required = false) Integer xqdc) {
return Result.success(myBusinessService.studentCourses(nd, xqdc));
}
/** 本学员队课次(默认本周) */
@GetMapping("/student/lessons")
public Result<List<DailyWeeklyTimetableVO>> studentLessons(@RequestParam(value = "start", required = false) String start,
@RequestParam(value = "end", required = false) String end) {
return Result.success(myBusinessService.studentLessons(start, end));
}
/** 本学员队课表网格 */
@GetMapping("/student/grid")
public Result<TimetableGridVO> studentGrid(@RequestParam(value = "mbbh", required = false) String mbbh,
@RequestParam(value = "start", required = false) String start,
@RequestParam(value = "end", required = false) String end,
@RequestParam(value = "nd", required = false) Integer nd) {
return Result.success(myBusinessService.studentGrid(mbbh, start, end, nd));
}
/** 本学员队干部清单 */
@GetMapping("/team/cadres")
public Result<List<Map<String, Object>>> teamCadres() {
return Result.success(myBusinessService.teamCadres());
}
}
@@ -0,0 +1,211 @@
package com.roomroot.web.controller.jwgl;
import com.roomroot.common.exception.ServiceException;
import com.roomroot.jwgl.dto.scheduling.SchedulingArrangeRequest;
import com.roomroot.jwgl.dto.scheduling.SchedulingCellOpRequest;
import com.roomroot.jwgl.dto.scheduling.SchedulingCourseEditRequest;
import com.roomroot.jwgl.dto.scheduling.SchedulingMoveRequest;
import com.roomroot.jwgl.service.RunningCoursePublishService;
import com.roomroot.jwgl.service.SchedulingWindowService;
import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.scheduling.SchedulingViewVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 实施排课窗口 Controller(阶段 5.3)。
*
* <p>组合查询 + 写操作:安排所选节次 / 删除所选节次 / 删除课程全部节次 / 彻底删除运行课程。
* 硬冲突格忽略(双占、校历/班历/场地历/教员历不可排);软提示(配当周次不符、非正课)随返回值给出。</p>
*/
@RestController
@RequestMapping("/schedulingWindow")
public class SchedulingWindowController {
@Autowired
private SchedulingWindowService schedulingWindowService;
@Autowired
private RunningCoursePublishService runningCoursePublishService;
/**
* 导出排课窗视图 Excel:每周一个 sheet(节次×星期网格,阶段 E4)。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:list')")
@GetMapping("/export")
public ResponseEntity<byte[]> export(@RequestParam("xydxqbh") String xydxqbh) {
byte[] bytes = schedulingWindowService.exportView(xydxqbh);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment",
new String("排课窗口.xlsx".getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
return ResponseEntity.ok().headers(headers).body(bytes);
}
/**
* 排课窗组合视图:班次头 + 课程列表(排满标绿)+ 周次×星期×节次格子。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:list')")
@GetMapping("/view")
public Result<SchedulingViewVO> view(@RequestParam("xydxqbh") String xydxqbh) {
return Result.success(schedulingWindowService.view(xydxqbh));
}
/**
* 安排所选节次。硬冲突格忽略并列出,软提示格照常安排并给出提示。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:edit')")
@PostMapping("/arrange")
public Result<Map<String, Object>> arrange(@RequestBody SchedulingArrangeRequest request) {
return Result.success(schedulingWindowService.arrange(request));
}
/**
* 拖拽移动课次:把 from 格的课次平移到 to 格(阶段 E4)。
* 目标格走与 arrange 相同的硬冲突校验;软提示照常移动并返回 warning。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:edit')")
@PostMapping("/move")
public Result<Map<String, Object>> move(@RequestBody SchedulingMoveRequest request) {
return Result.success(schedulingWindowService.moveLesson(request));
}
/**
* 删除所选节次:仅删除该课程在这些格上的课次;已提交实施计划的课次拒绝。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:edit')")
@PostMapping("/deleteCells")
public Result<Integer> deleteCells(@RequestBody SchedulingCellOpRequest request) {
return Result.success(schedulingWindowService.deleteCells(request));
}
/**
* 删除课程全部节次(课程仍留在列表)。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:edit')")
@PostMapping("/clearCourse")
public Result<Integer> clearCourse(@RequestParam("sskcbh") String sskcbh) {
return Result.success(schedulingWindowService.clearCourse(sskcbh));
}
/**
* 彻底删除运行课程:课次与列表项一起删,编制侧任务保留(教员不可用)。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:edit')")
@PostMapping("/deleteCourse")
public Result<Integer> deleteCourse(@RequestParam("sskcbh") String sskcbh) {
return Result.success(schedulingWindowService.deleteCourse(sskcbh));
}
/**
* 排课日志查询:按课程(可叠加操作类型)。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:list')")
@GetMapping("/logs")
public Result<List<Map<String, Object>>> logs(@RequestParam("sskcbh") String sskcbh,
@RequestParam(value = "czlx", required = false) String czlx) {
return Result.success(schedulingWindowService.logs(sskcbh, czlx));
}
/**
* 编辑课程教学任务信息(手册 12.3.1):学时/周课时/课程简称/责任教员/默认场地。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:edit')")
@PostMapping("/course/update")
public Result<Map<String, Object>> updateCourse(@RequestBody SchedulingCourseEditRequest request) {
return Result.success(schedulingWindowService.updateCourse(request));
}
/**
* 教学班次(合班)当前列表 + 候选班次(手册 12.3.2.2)。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:list')")
@GetMapping("/course/teams")
public Result<Map<String, Object>> courseTeams(@RequestParam("sskcbh") String sskcbh) {
return Result.success(schedulingWindowService.courseTeams(sskcbh));
}
/**
* 教学保障选项:保障类别 + 保障资源(含总量与计量单位,手册 12.3.2.5)。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:list')")
@GetMapping("/support/options")
public Result<Map<String, Object>> supportOptions() {
return Result.success(schedulingWindowService.supportOptions());
}
/**
* 批量发布【运行课表】(手册 12.1):把班次学期的课程任务发布为运行课程。
*
* <p>发布前要求教学任务已发布未结束、责任教员与默认场地齐备;逐个班次独立事务,
* 单个失败不影响其它班次,失败原因逐条返回。</p>
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:edit')")
@PostMapping("/publish")
public Result<List<Map<String, Object>>> publish(@RequestBody PublishRequest request) {
return Result.success(batchPublish(request, true));
}
/**
* 批量删除【运行课表】(手册 12.2):撤回该班次学期的运行课程,已排课次一并删除。
*/
@PreAuthorize("@ss.hasPermi('teach:schedulingWindow:edit')")
@PostMapping("/withdraw")
public Result<List<Map<String, Object>>> withdraw(@RequestBody PublishRequest request) {
return Result.success(batchPublish(request, false));
}
/** 批量发布/撤回公共实现 */
private List<Map<String, Object>> batchPublish(PublishRequest request, boolean publish) {
if (request == null || request.getXydxqbhs() == null || request.getXydxqbhs().isEmpty()) {
throw new ServiceException("请选择要操作的班次学期", 400);
}
List<Map<String, Object>> results = new ArrayList<>();
for (String xydxqbh : request.getXydxqbhs()) {
Map<String, Object> item = new HashMap<>();
item.put("xydxqbh", xydxqbh);
try {
int count = publish
? runningCoursePublishService.publish(xydxqbh)
: runningCoursePublishService.withdraw(xydxqbh);
item.put("success", true);
item.put("count", count);
item.put("message", publish ? ("已发布 " + count + " 条运行课程") : ("已删除 " + count + " 条运行课程"));
} catch (Exception e) {
item.put("success", false);
item.put("count", 0);
item.put("message", e.getMessage() == null ? "操作失败" : e.getMessage());
}
results.add(item);
}
return results;
}
/** 批量发布/删除请求体 */
public static class PublishRequest {
private List<String> xydxqbhs;
public List<String> getXydxqbhs() {
return xydxqbhs;
}
public void setXydxqbhs(List<String> xydxqbhs) {
this.xydxqbhs = xydxqbhs;
}
}
}
@@ -20,11 +20,13 @@ public class SemesterCalendarController {
private SemesterCalendarService semesterCalendarService; private SemesterCalendarService semesterCalendarService;
/** /**
* 新增学期校历 * 预生成学期校历(幂等)。nd 为 6 位学期代号,为空时后端按日期在「学期」表反查。
*/ */
@PostMapping("/add") @PostMapping("/add")
public Result<Void> add(@RequestParam("startDate") String startDate,@RequestParam("endDate") String endDate) { public Result<Void> add(@RequestParam("startDate") String startDate,
semesterCalendarService.add(startDate,endDate); @RequestParam("endDate") String endDate,
@RequestParam(value = "nd", required = false) Integer nd) {
semesterCalendarService.add(startDate, endDate, nd);
return Result.success(); return Result.success();
} }
@@ -42,6 +44,11 @@ public class SemesterCalendarController {
*/ */
@PostMapping("/update") @PostMapping("/update")
public Result<Void> update(@RequestBody XQXLB xqxlb) { public Result<Void> update(@RequestBody XQXLB xqxlb) {
if(xqxlb.getBh() == null || xqxlb.getBh().trim().isEmpty()){
return Result.error(200,"编号不得为空");
}
semesterCalendarService.update(xqxlb); semesterCalendarService.update(xqxlb);
return Result.success(); return Result.success();
} }
@@ -3,6 +3,9 @@ package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.entity.XYXX; import com.roomroot.jwgl.entity.XYXX;
import com.roomroot.jwgl.entity.XYDNDXQJBXXB; import com.roomroot.jwgl.entity.XYDNDXQJBXXB;
import com.roomroot.jwgl.entity.XYDB; import com.roomroot.jwgl.entity.XYDB;
import com.roomroot.jwgl.entity.XYDQB;
import com.roomroot.jwgl.entity.KB;
import com.roomroot.jwgl.entity.PXRW;
import com.roomroot.jwgl.entity.XYXJYDSQB; import com.roomroot.jwgl.entity.XYXJYDSQB;
import com.roomroot.jwgl.entity.XYXJYJJGB; import com.roomroot.jwgl.entity.XYXJYJJGB;
import com.roomroot.jwgl.entity.XYXJYJTJB; import com.roomroot.jwgl.entity.XYXJYJTJB;
@@ -44,8 +47,22 @@ public class StudentRecordsController {
@Resource @Resource
private ClassSemesterService classSemesterService; private ClassSemesterService classSemesterService;
/**
* 校验培训:按主体培训任务 0/1 查询培训任务。
*
* @param ztpxrw 主体培训任务,0-否,1-是
*/
@GetMapping("/training-tasks")
public Result<List<PXRW>> listTrainingTasks(@RequestParam("ztpxrw") Integer ztpxrw) {
return Result.success(studentRecordsService.listTrainingTasks(ztpxrw));
}
// ======================== 学员信息维护 ======================== // ======================== 学员信息维护 ========================
/**
* 新增学员。
* <p>编号由后台生成 UUID;学号按当前班次编号查学员队期表的学号前缀、学号位数顺序生成,保证不重复。</p>
*/
@PostMapping("/add") @PostMapping("/add")
public Result<Void> add(@RequestBody XYXX xyxx) { public Result<Void> add(@RequestBody XYXX xyxx) {
studentRecordsService.add(xyxx); studentRecordsService.add(xyxx);
@@ -69,11 +86,33 @@ public class StudentRecordsController {
return Result.success(studentRecordsService.getById(bh)); return Result.success(studentRecordsService.getById(bh));
} }
/**
* 分页查询学员信息。
* <p>回显年级、专业、班次、考试情况、不及格门数、管理机构。
* 当前班次编号关联学员队表、专业表、学员课程成绩。</p>
*/
@GetMapping("/list") @GetMapping("/list")
public Result<PageResult<XYXX>> list(PageQuery query, XYXX xyxx) { public Result<PageResult<XYXX>> list(PageQuery query, XYXX xyxx) {
return Result.success(studentRecordsService.pageList(query, xyxx)); return Result.success(studentRecordsService.pageList(query, xyxx));
} }
/**
* 学员队期下拉选项(编号+名称),供学员信息表单选择学员队期编号。
*/
@GetMapping("/period-options")
public Result<List<XYDQB>> periodOptions() {
return Result.success(studentRecordsService.listPeriodOptions());
}
/**
* 课程科目下拉选项(课编号+课名称),供学员成绩查询等页面使用。
* 与 /jys/kb/list 不同,本接口不带教研室权限要求。
*/
@GetMapping("/kb-options")
public Result<List<KB>> kbOptions() {
return Result.success(studentRecordsService.listKbOptions());
}
// ======================== 学员信息批量导入 ======================== // ======================== 学员信息批量导入 ========================
/** /**
@@ -381,25 +420,110 @@ public class StudentRecordsController {
return Result.success(count); return Result.success(count);
} }
/**
* 未毕业、且该年度学期尚未建立班次学期信息的班次。
*/
@GetMapping("/semester/creatableClasses")
public Result<List<XYDB>> creatableClasses(@RequestParam("nd") Integer nd,
@RequestParam("xqdc") Integer xqdc) {
return Result.success(classSemesterService.listCreatableClasses(nd, xqdc));
}
/**
* 按学校学期带出开学/结束日期。
*/
@GetMapping("/semester/presetDates")
public Result<Map<String, String>> presetDates(@RequestParam("nd") Integer nd,
@RequestParam("xqdc") Integer xqdc) {
return Result.success(classSemesterService.presetDates(nd, xqdc));
}
/**
* 为符合条件的全部班次创建班次学期,返回实际创建数。
*/
@PostMapping("/semester/batchCreate")
public Result<Integer> batchCreate(@RequestBody Map<String, Object> params) {
Integer nd = asInt(params.get("nd"));
Integer xqdc = asInt(params.get("xqdc"));
String kxrq = asText(params.get("kxrq"));
String jsrq = asText(params.get("jsrq"));
int count = classSemesterService.batchCreateEligible(
nd,
xqdc,
kxrq == null ? null : java.time.LocalDate.parse(kxrq),
jsrq == null ? null : java.time.LocalDate.parse(jsrq));
return Result.success(count);
}
/**
* 学期级预设合班,只改预设编班号。
*/
@PostMapping("/semester/batchWaveMerge")
public Result<Integer> batchWaveMerge(@RequestBody Map<String, Object> params) {
return Result.success(classSemesterService.batchWaveMerge(asBhList(params)));
}
/**
* 学期级预设拆班,所选班次各自独立成波。
*/
@PostMapping("/semester/batchWaveSplit")
public Result<Integer> batchWaveSplit(@RequestBody Map<String, Object> params) {
return Result.success(classSemesterService.batchWaveSplit(asBhList(params)));
}
private Integer asInt(Object value) {
if (value == null || "".equals(value)) {
return null;
}
if (value instanceof Number) {
return ((Number) value).intValue();
}
return Integer.valueOf(String.valueOf(value));
}
private String asText(Object value) {
if (value == null) {
return null;
}
String text = String.valueOf(value).trim();
return text.isEmpty() ? null : text;
}
@SuppressWarnings("unchecked")
private List<String> asBhList(Map<String, Object> params) {
Object raw = params.get("bhList");
if (!(raw instanceof List)) {
return List.of();
}
return (List<String>) raw;
}
// ======================== 课程成绩查询 ======================== // ======================== 课程成绩查询 ========================
/** /**
* 分页查询学员的课程成绩列表。 * 分页查询学员的课程成绩列表。
* <p>默认不传参数则全部分页展示;可按学员编号、年度筛选;年度不传时默认展示最新年度(最大年度)的数据。</p> * <p>
* 按课程编号、学员队编号、学号、年度筛选。学号通过学员编号关联学员信息表匹配。
* </p>
* *
* @param pageNum 页码(默认1) * @param pageNum 页码(默认1)
* @param pageSize 每页条数(默认20) * @param pageSize 每页条数(默认20)
* @param xybh 学员编号(可选) * @param kcbh 课程编号(对应成绩表科目编号,可选)
* @param xydbh 学员队编号(可选)
* @param xh 学号(可选,关联学员信息表)
* @param nd 年度(可选) * @param nd 年度(可选)
*/ */
@GetMapping("/grades") @GetMapping("/grades")
public Result<PageResult<XYKCCJ>> getGrades( public Result<PageResult<XYKCCJ>> getGrades(
@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "20") Integer pageSize, @RequestParam(defaultValue = "20") Integer pageSize,
@RequestParam(required = false) String kcbh,
@RequestParam(required = false) String xydbh,
@RequestParam(required = false) String xh,
@RequestParam(required = false) String xybh, @RequestParam(required = false) String xybh,
@RequestParam(required = false) Integer nd) { @RequestParam(required = false) Integer nd) {
return Result.success(studentRecordsService.pageCourseGrades( return Result.success(studentRecordsService.pageCourseGrades(
new PageQuery(pageNum, pageSize), xybh, nd)); new PageQuery(pageNum, pageSize), kcbh, xydbh, xh, xybh, nd));
} }
/** /**
@@ -124,21 +124,19 @@ public class StudentTeamTaskController {
/** /**
* 自动生成必修课程 * 自动生成必修课程
* <p> * <p>
* 根据学员队编号从学员队表获取专业代号, * 按学员队学期编号定位目标班次学期,由它反查学员队编号、学期第次与年度,
* 再根据专业代号和学期第次查询专业教学计划表, * 再按专业代号 + 学期第次查专业教学计划表补齐必修课程。
* 为当前班次自动生成必修课程,插入到学员队任务表。
* 已存在的课程(按课编号判断)不会重复添加。 * 已存在的课程(按课编号判断)不会重复添加。
* </p> * </p>
* *
* @param xydbh 学员队编号 * @param xydxqbh 学员队学期编号
* @param xqdc 学期第次
* @return 新增数量 * @return 新增数量
*/ */
@PostMapping("/autoGenerateRequiredCourses") @PostMapping("/autoGenerateRequiredCourses")
public Result<Integer> autoGenerateRequiredCourses( public Result<Integer> autoGenerateRequiredCourses(@RequestParam("xydxqbh") String xydxqbh) {
@RequestParam("xydbh") String xydbh, // 必须按「班次学期编号」定位:同一学员队在多个年度可能有学期第次相同的班次学期,
@RequestParam("xqdc") Integer xqdc) { // 只传 (学员队编号, 学期第次) 无法区分学年,会把课程任务写进别的年度。
int count = studentTeamTaskService.autoGenerateRequiredCourses(xydbh, xqdc); int count = studentTeamTaskService.autoGenerateRequiredCourses(xydxqbh);
return Result.success(count); return Result.success(count);
} }
@@ -159,4 +157,47 @@ public class StudentTeamTaskController {
List<String> newBhList = studentTeamTaskService.copy(bhList, newXydbh); List<String> newBhList = studentTeamTaskService.copy(bhList, newXydbh);
return Result.success(newBhList); return Result.success(newBhList);
} }
@PostMapping("/batchAutoGenerate")
public Result<Integer> batchAutoGenerate(@RequestBody List<String> xydxqbhList) {
return Result.success(studentTeamTaskService.batchAutoGenerate(xydxqbhList));
}
@GetMapping("/planCourses")
public Result<List<com.roomroot.jwgl.vo.PlanCourseVO>> planCourses(
@RequestParam("xydxqbh") String xydxqbh,
@RequestParam(value = "otherOnly", defaultValue = "true") boolean otherOnly) {
return Result.success(studentTeamTaskService.listPlanCourses(xydxqbh, otherOnly));
}
@PostMapping("/addFromLibrary")
public Result<Void> addFromLibrary(@RequestParam("xydxqbh") String xydxqbh,
@RequestParam("kbh") String kbh) {
studentTeamTaskService.addFromLibrary(xydxqbh, kbh);
return Result.success();
}
@PostMapping("/addFromPlan")
public Result<Void> addFromPlan(@RequestParam("xydxqbh") String xydxqbh,
@RequestParam("planBh") String planBh) {
studentTeamTaskService.addFromPlan(xydxqbh, planBh);
return Result.success();
}
@PostMapping("/syncFromPlan")
public Result<Integer> syncFromPlan(@RequestBody List<String> bhList) {
return Result.success(studentTeamTaskService.syncFromPlan(bhList));
}
@PostMapping("/batchDelete")
public Result<Integer> batchDelete(@RequestBody List<String> bhList) {
return Result.success(studentTeamTaskService.batchDeleteGuarded(bhList));
}
@PostMapping("/paste")
public Result<Integer> paste(@RequestBody Map<String, Object> params) {
List<String> bhList = (List<String>) params.get("bhList");
String targetXydxqbh = (String) params.get("targetXydxqbh");
return Result.success(studentTeamTaskService.pasteToSemester(bhList, targetXydxqbh));
}
} }
@@ -0,0 +1,50 @@
package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.entity.DBVersion;
import com.roomroot.jwgl.entity.JCSJB;
import com.roomroot.jwgl.service.ClassPeriodService;
import com.roomroot.jwgl.service.SystemSettingsService;
import com.roomroot.jwgl.unit.Result;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import java.util.List;
/**
* 教务系统参数(DBVersion 单行,阶段 E1)。
*
* <p>当前开放字段:显示78节(xs78j)、显示晚上(xsws)、显示夜间(xsyj)、
* 教学要点名称(jxydmc)。更新只写非空字段。</p>
*/
@RestController
@RequestMapping("/systemSettings")
public class SystemSettingsController {
@Autowired
private SystemSettingsService systemSettingsService;
@Autowired
private ClassPeriodService classPeriodService;
/** 读取系统参数 */
@GetMapping("/get")
public Result<DBVersion> get() {
return Result.success(systemSettingsService.get());
}
/** 节次段字典:节次时间表的双节次行,供日历编辑器渲染节次列 */
@GetMapping("/periodSlots")
public Result<List<JCSJB>> periodSlots() {
return Result.success(classPeriodService.slotRows());
}
/** 更新系统参数(只写非空字段) */
@PostMapping("/update")
public Result<DBVersion> update(@RequestBody DBVersion settings) {
return Result.success(systemSettingsService.update(settings));
}
}
@@ -0,0 +1,133 @@
package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.dto.taskbook.TaskBookBatchFillRequest;
import com.roomroot.jwgl.dto.taskbook.TaskBookBatchRoomRequest;
import com.roomroot.jwgl.dto.taskbook.TaskBookBatchTeacherRequest;
import com.roomroot.jwgl.dto.taskbook.TaskBookBhListRequest;
import com.roomroot.jwgl.dto.taskbook.TaskBookFillRequest;
import com.roomroot.jwgl.dto.taskbook.TaskBookRoomRequest;
import com.roomroot.jwgl.dto.taskbook.TaskBookTeacherRequest;
import com.roomroot.jwgl.service.TaskBookFillService;
import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.taskbook.TaskBookRowVO;
import org.springframework.beans.factory.annotation.Autowired;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
* 教研室任务书填报 Controller(阶段 4)。
*
* <p>把已生成的课程任务确认成「可以排课的运行对象」:合班、责任教员、默认场地。</p>
*/
@RestController
@RequestMapping("/taskBookFill")
public class TaskBookFillController {
@Autowired
private TaskBookFillService taskBookFillService;
/**
* 填报列表:某教学任务下全部课程任务行(排序 课程→责任教员→课次,含合班分组号)。
*/
@GetMapping("/list")
public Result<List<TaskBookRowVO>> list(@RequestParam("jxrwbh") String jxrwbh,
@RequestParam(value = "jybh", required = false) String jybh) {
return Result.success(taskBookFillService.list(jxrwbh, jybh));
}
/**
* 手动合班:所选行写入同一编组;科目/学时/课类型/成绩分制不同则拒绝并说明。
*/
@PostMapping("/merge")
public Result<Integer> merge(@RequestBody TaskBookBhListRequest request) {
return Result.success(taskBookFillService.merge(request));
}
/**
* 按预设合班:按课程科目分组,组内按预设编班号写入同一编组。
*/
@PostMapping("/mergeByPreset")
public Result<List<Map<String, Object>>> mergeByPreset(@RequestBody TaskBookBhListRequest request) {
return Result.success(taskBookFillService.mergeByPreset(request));
}
/**
* 拆班:所选行编组置 0。
*/
@PostMapping("/split")
public Result<Integer> split(@RequestBody TaskBookBhListRequest request) {
return Result.success(taskBookFillService.split(request));
}
/**
* 责任教员指定:mode = unit(责任单位教员)/ academy(全院教员)/ plan(应用教研室计划教员)。
* 同合班组其它行同步。
*/
@PostMapping("/setTeacher")
public Result<Integer> setTeacher(@RequestBody TaskBookTeacherRequest request) {
return Result.success(taskBookFillService.setTeacher(request));
}
/**
* 场地指定:useSpecial=true 使用班次专用教室;否则按 jsbh 指定其它教室。同合班组同步。
*/
@PostMapping("/setRoom")
public Result<Integer> setRoom(@RequestBody TaskBookRoomRequest request) {
return Result.success(taskBookFillService.setRoom(request));
}
/**
* 填报字段:计划教员 / 场地(同合班同步)/ 排课建议 / 课次序号。
*/
@PostMapping("/fill")
public Result<Integer> fill(@RequestBody TaskBookFillRequest request) {
return Result.success(taskBookFillService.fill(request));
}
/**
* 批量指定责任教员:对每行执行与 setTeacher 相同的校验与合班组同步。
*/
@PostMapping("/batchSetTeacher")
public Result<Integer> batchSetTeacher(@RequestBody TaskBookBatchTeacherRequest request) {
return Result.success(taskBookFillService.batchSetTeacher(request));
}
/**
* 批量指定场地:对每行执行与 setRoom 相同的校验与合班组同步。
*/
@PostMapping("/batchSetRoom")
public Result<Integer> batchSetRoom(@RequestBody TaskBookBatchRoomRequest request) {
return Result.success(taskBookFillService.batchSetRoom(request));
}
/**
* 批量填报:对所选行统一应用填报字段(仅写非空),单事务。
*/
@PostMapping("/batchFill")
public Result<Integer> batchFill(@RequestBody TaskBookBatchFillRequest request) {
return Result.success(taskBookFillService.batchFill(request));
}
/**
* 行级删除:所选课程任务行逻辑删除;已发布到运行课表的班次须先撤回。
*/
@PostMapping("/deleteRows")
public Result<Integer> deleteRows(@RequestBody TaskBookBhListRequest request) {
return Result.success(taskBookFillService.deleteRows(request));
}
/**
* 教研室跨任务汇总:该教研室全部任务书(附教学任务名称/年度/状态)。
*/
@GetMapping("/officeSummary")
public Result<List<Map<String, Object>>> officeSummary(@RequestParam("jysdh") String jysdh) {
return Result.success(taskBookFillService.officeSummary(jysdh));
}
}
@@ -0,0 +1,85 @@
package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.entity.JYL;
import com.roomroot.jwgl.service.JYLService;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.unit.Result;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 教员历控制器(阶段 5.1)。排课冲突同时读取场地历与教员历。
*/
@RestController
@RequestMapping("/teacherCalendar/jyl")
public class TeacherCalendarController {
@Resource
private JYLService jylService;
/** 新增教员历 */
@PostMapping("/add")
public Result<Void> add(@RequestBody JYL jyl) {
jylService.add(jyl);
return Result.success();
}
/** 删除教员历(软删) */
@PostMapping("/delete")
public Result<Void> delete(@RequestParam("bh") String bh) {
jylService.delete(bh);
return Result.success();
}
/** 更新教员历 */
@PostMapping("/update")
public Result<Void> update(@RequestBody JYL jyl) {
jylService.update(jyl);
return Result.success();
}
/** 根据编号查询 */
@GetMapping("/get")
public Result<JYL> getById(@RequestParam("bh") String bh) {
return Result.success(jylService.getById(bh));
}
/** 分页查询 */
@GetMapping("/list")
public Result<PageResult<JYL>> list(PageQuery query, JYL jyl) {
return Result.success(jylService.pageList(query, jyl));
}
/** 查询全部 */
@GetMapping("/all")
public Result<List<JYL>> all(JYL jyl) {
return Result.success(jylService.list(jyl));
}
/** 按教员编号查询 */
@GetMapping("/listByJybh")
public Result<List<JYL>> listByJybh(@RequestParam("jybh") String jybh) {
return Result.success(jylService.listByJybh(jybh));
}
/** 按日期查询 */
@GetMapping("/listByRq")
public Result<List<JYL>> listByRq(@RequestParam("rq") String rq) {
return Result.success(jylService.listByRq(rq));
}
/** 批量保存教员历(教员历编辑器整片提交,按 教员+日期+节次 幂等覆盖) */
@PostMapping("/batchSave")
public Result<Integer> batchSave(@RequestBody List<JYL> list) {
return Result.success(jylService.batchSave(list));
}
/** 批量删除教员历(本表无 del_flag,物理删除) */
@PostMapping("/batchDelete")
public Result<Integer> batchDelete(@RequestBody List<String> bhs) {
return Result.success(jylService.batchDelete(bhs));
}
}
@@ -0,0 +1,93 @@
package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.dto.allocation.AllocationGroupRequest;
import com.roomroot.jwgl.dto.allocation.AllocationSaveItem;
import com.roomroot.jwgl.service.TeachingAllocationService;
import com.roomroot.jwgl.vo.allocation.AllocationViewVO;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* 教学配当 Controller(阶段 3)。
*
* <p>配当只做排课粗约束(周学时分布、同开同结),不直接写实施课程表。</p>
*/
@RestController
@RequestMapping("/teachingAllocation")
public class TeachingAllocationController {
@Autowired
private TeachingAllocationService teachingAllocationService;
/**
* 配当编辑器视图:周轴(每周可排正课)+ 任务行(含铺学时建议)。
*/
@GetMapping("/view")
public Result<AllocationViewVO> view(@RequestParam("xydxqbh") String xydxqbh) {
return Result.success(teachingAllocationService.view(xydxqbh));
}
/**
* 保存配当:单条(列表 1 个元素)或多选批量;元素 saveGroup=true 时整编组同开同结。
*/
@PostMapping("/save")
public Result<Integer> save(@RequestBody List<AllocationSaveItem> items) {
return Result.success(teachingAllocationService.save(items));
}
/**
* 优选序数上移/下移(direction: up/down),返回归一化后的任务编号顺序。
*/
@PostMapping("/move")
public Result<List<String>> move(@RequestParam("xydxqbh") String xydxqbh,
@RequestParam("bh") String bh,
@RequestParam("direction") String direction) {
return Result.success(teachingAllocationService.move(xydxqbh, bh, direction));
}
/**
* 编组管理面板:同科目全部开课班次。
*/
@GetMapping("/groups")
public Result<List<Map<String, Object>>> groups(@RequestParam("kbh") String kbh) {
return Result.success(teachingAllocationService.groups(kbh));
}
/**
* 编组管理:把所选任务统一改编组号。
*/
@PostMapping("/setGroup")
public Result<Integer> setGroup(@RequestBody AllocationGroupRequest request) {
return Result.success(teachingAllocationService.setGroup(request));
}
/**
* 自动排布:按铺学时建议把计算起始周回填到 pdqsz。
* onlyMissing=true(辅助排布)只补未设起始周的任务;body 可选传任务编号列表限定范围。
*/
@PostMapping("/autoArrange")
public Result<Integer> autoArrange(@RequestParam("xydxqbh") String xydxqbh,
@RequestParam(value = "onlyMissing", defaultValue = "false") boolean onlyMissing,
@RequestBody(required = false) List<String> bhList) {
return Result.success(teachingAllocationService.autoArrange(xydxqbh, bhList, onlyMissing));
}
/**
* 导出配当 Excel(支持批量:xydxqbh 逗号分隔)。
*/
@GetMapping("/export")
public void export(@RequestParam("xydxqbh") String xydxqbh, HttpServletResponse response) throws Exception {
teachingAllocationService.exportExcel(Arrays.asList(xydxqbh.split(",")), response);
}
}
@@ -92,11 +92,8 @@ public class TeachingPlanController {
* 下载教学实施计划导入模板 * 下载教学实施计划导入模板
*/ */
@GetMapping("/template") @GetMapping("/template")
public ResponseEntity<org.springframework.core.io.Resource> downloadTemplate() throws IOException { public ResponseEntity<byte[]> downloadTemplate() throws Exception {
ClassPathResource resource = new ClassPathResource("template/教学实施计划导入模板.xlsx"); byte[] bytes = teachingPlanService.buildImportTemplate();
if (!resource.exists()) {
return ResponseEntity.notFound().build();
}
String fileName = URLEncoder.encode("教学实施计划导入模板.xlsx", "UTF-8"); String fileName = URLEncoder.encode("教学实施计划导入模板.xlsx", "UTF-8");
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
@@ -105,6 +102,6 @@ public class TeachingPlanController {
return ResponseEntity.ok() return ResponseEntity.ok()
.headers(headers) .headers(headers)
.body(resource); .body(bytes);
} }
} }
@@ -81,15 +81,33 @@ public class TeachingTaskController {
} }
/** /**
* 发布教学任务及教研室任务书 * 批量发布教学任务及教研室任务书
* 根据教学任务编号修改状态为"发布",并批量更新所有关联的教研室任务书状态为"发布" * 逐个任务置"发布"并同步教研室任务书;任一校验失败(已结束/任务书未生成)整批回滚。
* *
* @param bh 教学任务编号 * @param bhList 教学任务编号列表
* @return 更新数量 * @return 更新的教研室任务书行数合计
*/ */
@PostMapping("/batchPublish") @PostMapping("/batchPublish")
public Result<Integer> batchPublish(@RequestParam("bh") String bh) { public Result<Integer> batchPublish(@RequestBody List<String> bhList) {
int count = teachingTaskService.batchPublish(bh); int count = teachingTaskService.batchPublish(bhList);
return Result.success(count); return Result.success(count);
} }
/**
* 结束发布。结束后教研室不能再改任务书和课程任务。
*/
@PostMapping("/endPublish")
public Result<Void> endPublish(@RequestParam("bh") String bh) {
teachingTaskService.endPublish(bh);
return Result.success();
}
/**
* 导出教学任务书 Excel(该教学任务下全部教研室任务书课程明细)。
*/
@GetMapping("/exportTaskBook")
public void exportTaskBook(jakarta.servlet.http.HttpServletResponse response,
@RequestParam("bh") String bh) throws Exception {
teachingTaskService.exportTaskBook(response, bh);
}
} }
@@ -1,5 +1,6 @@
package com.roomroot.web.controller.jwgl; package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.entity.JXGLJG;
import com.roomroot.jwgl.entity.ZYB; import com.roomroot.jwgl.entity.ZYB;
import com.roomroot.jwgl.service.TrainingProgramService; import com.roomroot.jwgl.service.TrainingProgramService;
import com.roomroot.jwgl.unit.PageQuery; import com.roomroot.jwgl.unit.PageQuery;
@@ -10,6 +11,7 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import java.util.List;
/** /**
* 培养方案管理控制器 * 培养方案管理控制器
@@ -87,6 +89,7 @@ public class TrainingProgramController {
* <li>zydm — 专业代码(模糊匹配)</li> * <li>zydm — 专业代码(模糊匹配)</li>
* <li>pxlx — 培训类型(精确匹配,用于版本筛选)</li> * <li>pxlx — 培训类型(精确匹配,用于版本筛选)</li>
* <li>pxcc — 培训层次(精确匹配)</li> * <li>pxcc — 培训层次(精确匹配)</li>
* <li>ty — 停用(精确匹配)</li>
* </ul> * </ul>
* </p> * </p>
* *
@@ -105,7 +108,8 @@ public class TrainingProgramController {
@RequestParam(required = false) String zymc, @RequestParam(required = false) String zymc,
@RequestParam(required = false) String zydm, @RequestParam(required = false) String zydm,
@RequestParam(required = false) String pxlx, @RequestParam(required = false) String pxlx,
@RequestParam(required = false) String pxcc) { @RequestParam(required = false) String pxcc,
@RequestParam(required = false) Boolean ty) {
PageQuery query = new PageQuery(); PageQuery query = new PageQuery();
query.setPageNum(pageNum); query.setPageNum(pageNum);
query.setPageSize(pageSize); query.setPageSize(pageSize);
@@ -114,14 +118,23 @@ public class TrainingProgramController {
cond.setZydm(zydm); cond.setZydm(zydm);
cond.setPxlx(pxlx); cond.setPxlx(pxlx);
cond.setPxcc(pxcc); cond.setPxcc(pxcc);
cond.setTy(ty);
PageResult<ZYB> pageResult = trainingProgramService.pageList(query, cond); PageResult<ZYB> pageResult = trainingProgramService.pageList(query, cond);
return Result.success(pageResult); return Result.success(pageResult);
} }
/**
* 培养方案目录导入模板(仅表头,含学年制、学期数等必填列)。
*/
@GetMapping("/template")
public void downloadTemplate(HttpServletResponse response) throws Exception {
trainingProgramService.exportZYBTemplate(response);
}
/** /**
* 培养方案(专业)数据文件导入(.xls/.xlsx)。 * 培养方案(专业)数据文件导入(.xls/.xlsx)。
* <p>表头顺序:专业代号, 专业名称, 专业代码, 专业版本, 培训类型, 培训层次, 学年制, * <p>按列名匹配:专业代号, 专业名称, 专业代码, 专业版本, 培训类型, 培训层次, 学年制,
* 学期数, 专业方向, 专业备注, 学员类别, 简称, 培训类型2。专业代号不填自动生成。</p> * 学期数, 专业方向, 专业备注, 学员类别, 简称, 培训类型2。专业代号不填自动生成;学年制、学期数必填。</p>
*/ */
@PostMapping("/import") @PostMapping("/import")
public Result<Integer> importData(@RequestParam("file") MultipartFile file) throws Exception { public Result<Integer> importData(@RequestParam("file") MultipartFile file) throws Exception {
@@ -136,4 +149,12 @@ public class TrainingProgramController {
public void exportData(HttpServletResponse response) throws Exception { public void exportData(HttpServletResponse response) throws Exception {
trainingProgramService.exportZYBExcel(response); trainingProgramService.exportZYBExcel(response);
} }
/**
* 教学管理机构下拉选项(来自教学管理机构表,提交编号、展示名称)。
*/
@GetMapping("/teaching-organizations")
public Result<List<JXGLJG>> listTeachingOrganizations() {
return Result.success(trainingProgramService.listTeachingOrganizations());
}
} }
@@ -2,6 +2,8 @@ package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.entity.ZYJXJHB; import com.roomroot.jwgl.entity.ZYJXJHB;
import com.roomroot.jwgl.service.ZYJXJHBService; import com.roomroot.jwgl.service.ZYJXJHBService;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.unit.Result; import com.roomroot.jwgl.unit.Result;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -79,27 +81,46 @@ public class ZYJXJHBController {
* @param ty 停用标识(0-正常,1-停用) * @param ty 停用标识(0-正常,1-停用)
*/ */
@GetMapping("/listByZydhAndTy") @GetMapping("/listByZydhAndTy")
public Result<List<ZYJXJHB>> listByZydhAndTy(@RequestParam("zydh") String zydh, public Result<PageResult<ZYJXJHB>> listByZydhAndTy(
@RequestParam("ty") Integer ty) { @RequestParam(defaultValue = "1") Integer pageNum,
return Result.success(zyjxjhbService.listByZydhAndTy(zydh, ty)); @RequestParam(defaultValue = "20") Integer pageSize,
@RequestParam(required = false) String zydh,
@RequestParam(required = false) Integer ty) {
return Result.success(zyjxjhbService.pageByZydhAndTy(
new PageQuery(pageNum, pageSize), zydh, ty));
} }
/** /**
* 专业教学计划表数据文件导入(.xls/.xlsx)。 * 专业教学计划表数据文件导入(.xls/.xlsx)。
* <p>表头顺序:专业代号, 课编号, 学期第次, 课类型, 学时, 学分, 周课时, 课程定位, * <p>按表头名匹配列(列位置不限),推荐使用 /template 下载的模板填写。
* 模块, 成绩分制, 理论学时, 实践学时, 考试课时, 教研室代号, 简称。编号由系统自动生成。</p> * 必填列:专业代号、课编号、学期第次、课类型、学时;
* "专业代号+课编号+学期第次"已存在的行跳过,校验失败行返回行级明细。</p>
*/ */
@PostMapping("/import") @PostMapping("/import")
public Result<Integer> importData(@RequestParam("file") MultipartFile file) throws Exception { public Result<com.roomroot.jwgl.vo.syllabus.SyllabusImportResultVO> importData(
int count = zyjxjhbService.importZYJXJHBFromExcel(file); @RequestParam("file") MultipartFile file) throws Exception {
return Result.success("导入成功,共" + count + "条", count); com.roomroot.jwgl.vo.syllabus.SyllabusImportResultVO result = zyjxjhbService.importExcel(file);
return Result.success(result.getMessage(), result);
}
/**
* 下载教学大纲导入模板(数据 sheet + 填写说明 sheet)。
*/
@GetMapping("/template")
public void downloadTemplate(HttpServletResponse response) throws Exception {
zyjxjhbService.downloadTemplate(response);
} }
/** /**
* 导出专业教学计划到 Excel(.xlsx)。 * 导出专业教学计划到 Excel(.xlsx)。
* <p>专业代号、停用标识可选,与列表筛选条件一致。</p>
*/ */
@GetMapping("/export") @GetMapping("/export")
public void exportData(HttpServletResponse response) throws Exception { public void exportData(
zyjxjhbService.exportZYJXJHBExcel(response); HttpServletResponse response,
@RequestParam(required = false) String zydh,
@RequestParam(required = false) Integer ty,
@RequestParam(required = false) List<String> bhList) throws Exception {
zyjxjhbService.exportZYJXJHBExcel(response, zydh, ty, bhList);
} }
} }
@@ -3,10 +3,10 @@ spring:
datasource: datasource:
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
# 达梦连接串:ip:端口,schema指定默认模式 # 达梦连接串:ip:端口,schema指定默认模式
url: jdbc:dm://10.1.1.17:5236?schema=JIAOWU&useUnicode=true&characterEncoding=utf-8 url: jdbc:opengauss://10.1.1.17:5436/jwgl?currentSchema=jwgl&batchMode=off&stringtype=unspecified
username: JIAOWU username: jwgl
password: Jiaowu123 password: Jiaowu123
driver-class-name: dm.jdbc.driver.DmDriver driver-class-name: org.opengauss.Driver
# Druid 基础参数 # Druid 基础参数
druid: druid:
@@ -29,7 +29,7 @@ spring:
# 配置一个连接在池中最大生存的时间,单位是毫秒 # 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000 maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效 # 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL validationQuery: SELECT 1
testWhileIdle: true testWhileIdle: true
testOnBorrow: false testOnBorrow: false
testOnReturn: false testOnReturn: false
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$" dumb="true">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
</component>
</module>
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$" dumb="true">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
</component>
</module>
@@ -0,0 +1,40 @@
package com.roomroot.framework.config;
import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tools.jackson.databind.ext.javatime.deser.LocalDateTimeDeserializer;
import tools.jackson.databind.json.JsonMapper;
import tools.jackson.databind.module.SimpleModule;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
/**
* 兼容前端常用的 {@code yyyy-MM-dd HH:mm:ss} 与 ISO {@code yyyy-MM-ddTHH:mm:ss}。
*/
@Configuration
public class JacksonConfig {
@Bean
public JsonMapperBuilderCustomizer flexibleLocalDateTimeCustomizer() {
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.optionalStart()
.optionalStart().appendLiteral('T').optionalEnd()
.optionalStart().appendLiteral(' ').optionalEnd()
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.optionalEnd()
.parseDefaulting(java.time.temporal.ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(java.time.temporal.ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(java.time.temporal.ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
return (JsonMapper.Builder builder) -> {
SimpleModule module = new SimpleModule("FlexibleLocalDateTime");
module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
builder.addModule(module);
};
}
}
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$" dumb="true">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
</component>
</module>
@@ -0,0 +1,18 @@
package com.roomroot.jwgl.dto.allocation;
import lombok.Data;
import java.util.List;
/**
* 教学配当 - 编组管理改编组号请求。
*/
@Data
public class AllocationGroupRequest {
/** 任务编号列表(必填) */
private List<String> bhList;
/** 目标配档编组号(必填,&gt;=0) */
private Integer pdbz;
}
@@ -0,0 +1,34 @@
package com.roomroot.jwgl.dto.allocation;
import lombok.Data;
/**
* 教学配当 - 单条保存项。
*
* <p>字段为 null 表示不修改。{@code saveGroup=true} 时按「同科目 + 同配档编组 + 同学期代号」
* 把同组各班次任务一起改(同开同结),限定在同一学期代号内防止跨学期串改。</p>
*/
@Data
public class AllocationSaveItem {
/** 任务编号(必填) */
private String bh;
/** 配档序号(优选序数) */
private Integer pdxh;
/** 配档起始周 */
private Integer pdqsz;
/** 配档按周:0=连排 1=按周 */
private Integer pdaz;
/** 配档占正课时间 */
private Integer pdzzksj;
/** 配档编组 */
private Integer pdbz;
/** 是否保存整个编组 */
private Boolean saveGroup;
}
@@ -0,0 +1,16 @@
package com.roomroot.jwgl.dto.calendar;
import lombok.Data;
import java.util.List;
/**
* 把班历事件应用到其它班次。eventBhList 为空时复制整个班历。
*/
@Data
public class ClassCalendarApplyDTO {
private String sourceXydxqbh;
private List<String> targetBhList;
private List<String> eventBhList;
}
@@ -0,0 +1,22 @@
package com.roomroot.jwgl.dto.calendar;
import lombok.Data;
import java.util.List;
/**
* 班历批量保存入参。一次拖选产生的所有时间格在单事务内 upsert。
*/
@Data
public class ClassCalendarBatchSaveDTO {
/**
* 学员队学期编号(班次学期)
*/
private String xydxqbh;
/**
* 时间格列表。cell.action = "clear" 表示恢复默认(清名称、可排课)。
*/
private List<ClassCalendarEventDTO> cells;
}
@@ -0,0 +1,29 @@
package com.roomroot.jwgl.dto.calendar;
import lombok.Data;
/**
* 班历时间格。日期用 yyyy-MM-dd,便于复用校历编辑器。
*/
@Data
public class ClassCalendarEventDTO {
private String bh;
private Integer nd;
private String xydbh;
private String xydxqbh;
private String jqsj;
private String jqmc;
private Boolean jc;
private String bz;
private Boolean kpk;
private Boolean bzxs;
private Boolean zdpk;
private Boolean zk;
private String courseClass;
/**
* 批量保存动作:"clear" 表示恢复默认(清名称、可排课);空或其它值按事件内容写入。
*/
private String action;
}
@@ -0,0 +1,32 @@
package com.roomroot.jwgl.dto.discipline;
import com.roomroot.jwgl.entity.ZYB;
import lombok.Data;
/**
* 专业(专业表)导入行解析结果。
* <p>
* 保留 Excel 中的原始行号,便于把校验失败原因定位到具体行。
* </p>
*/
@Data
public class MajorImportRowDTO {
/**
* Excel 行号(1 起始,含表头行)。
*/
private int rowNum;
/**
* 该行解析出的专业实体。
*/
private ZYB entity;
public MajorImportRowDTO() {
}
public MajorImportRowDTO(int rowNum, ZYB entity) {
this.rowNum = rowNum;
this.entity = entity;
}
}
@@ -16,4 +16,16 @@ public class AddTeacherDTO {
/** 教员属性信息(含职务、技术等级、学历学位等非空字段) */ /** 教员属性信息(含职务、技术等级、学历学位等非空字段) */
private JYSX attributes; private JYSX attributes;
/** 是否同时创建系统账号 */
private Boolean createUser;
/** 登录名(空则取教员编号) */
private String loginName;
/** 初始密码明文(空则取统一初始值) */
private String password;
/** 角色ID(空则取默认教员角色 101) */
private Long roleId;
} }
@@ -0,0 +1,32 @@
package com.roomroot.jwgl.dto.faculty;
import com.roomroot.jwgl.entity.JYB;
import lombok.Data;
/**
* 教员(教员表)导入行解析结果。
* <p>
* 保留 Excel 中的原始行号,便于把校验失败原因定位到具体行。
* </p>
*/
@Data
public class TeacherImportRowDTO {
/**
* Excel 行号(1 起始,含表头行)。
*/
private int rowNum;
/**
* 该行解析出的教员实体。
*/
private JYB entity;
public TeacherImportRowDTO() {
}
public TeacherImportRowDTO(int rowNum, JYB entity) {
this.rowNum = rowNum;
this.entity = entity;
}
}
@@ -35,6 +35,9 @@ public class ElectiveCourseSaveDTO {
/** 教室编号 */ /** 教室编号 */
private String jsbh; private String jsbh;
/** 教材名称(按名称匹配教材信息,写入课程教材关联) */
private String jcmc;
/** 计划人数 */ /** 计划人数 */
private Integer rs; private Integer rs;
@@ -0,0 +1,30 @@
package com.roomroot.jwgl.dto.kcb;
import lombok.Data;
/**
* 课表网格查询参数(手册一第12章 课表生成)。
* <p>dim 维度:semester 班次学期 / team 学员队 / teacher 教员 / room 教室。
* id 为对应维度主键(xydxqbh / xydbh / jybh / jsbh)。</p>
*/
@Data
public class TimetableGridQuery {
/** 维度:semester | team | teacher | room */
private String dim;
/** 维度目标编号 */
private String id;
/** 年度(校历/备注取数用;semester 维度自动从班次学期带出) */
private Integer nd;
/** 起始日期 yyyy-MM-dd;空时 semester 取学期范围,其它维度取本周 */
private String start;
/** 结束日期 yyyy-MM-dd */
private String end;
/** 课表模板编号(可选;套用模板显示开关:78节/晚上/夜间/选修/天数) */
private String mbbh;
}
@@ -2,8 +2,10 @@ package com.roomroot.jwgl.dto.kcb;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* 今日 / 本周 / 班次课表查询条件。 * 班次课表查询条件。
* <p>未传年度、学期时按当前时间取本学期。</p> * <p>未传年度、学期时按当前时间取本学期。</p>
*/ */
@Data @Data
@@ -20,4 +22,19 @@ public class TimetableQuery {
/** 学员队名称(队别班次模糊) */ /** 学员队名称(队别班次模糊) */
private String xydmc; private String xydmc;
/** 教员编号(主讲/辅讲/责任教员任一命中) */
private String jybh;
/** 教室编号(课次场地或课程默认场地任一命中) */
private String jsbh;
/** 教研室代号(按课程归属教研室过滤) */
private String jysdh;
/** 学员编号(服务端解析为其所在学员队后按队过滤) */
private String xybh;
/** 教员编号集合(教研室等批量范围过滤用) */
private List<String> jybhs;
} }
@@ -0,0 +1,78 @@
package com.roomroot.jwgl.dto.scheduling;
import lombok.Data;
import java.util.List;
/**
* 安排所选节次请求(阶段 5.3)。
*/
@Data
public class SchedulingArrangeRequest {
private String xydxqbh;
/** 实施_课程编号 */
private String sskcbh;
/** 教学内容(课题) */
private String jxnr;
/** 教学要点 */
private String jxyd;
/** 教学方法,默认 理论讲授 */
private String jxff;
/** 节次调节:0 默认(一节 2 学时)/ -1 / +1 */
private Integer jcdj;
/** 教学保障备注 */
private String jxbzbz;
/** 用车信息 */
private String ycxx;
/** 班组模式:合班全部 / 分组等 */
private String bzms;
/** 场地(教室编号),缺省用课程的默认场地 */
private String jsbh;
/** 主讲教员,缺省用课程责任教员 */
private String jybh;
/** 教学班次(学员队编号,本课程默认全部合班班次,可临时增删) */
private List<String> xydbhs;
/** 辅讲教员编号(可多个) */
private List<String> fzjybhs;
/** 教学场地(可多场地),为空则用 jsbh / 课程默认场地 */
private List<String> jsbhs;
/** 教学保障需求(结构化:类别→资源→数量) */
private List<Support> supports;
/** 所选格子 */
private List<Cell> cells;
/** 教学保障需求项 */
@Data
public static class Support {
/** 保障提供明细编号(保障资源库) */
private String bztgmxbh;
/** 需求数量 */
private Integer sl;
/** 备注 */
private String bz;
}
@Data
public static class Cell {
/** 日期 yyyy-MM-dd */
private String rq;
/** 节次 */
private Integer jc;
}
}
@@ -0,0 +1,17 @@
package com.roomroot.jwgl.dto.scheduling;
import lombok.Data;
import java.util.List;
/**
* 删除所选节次请求(阶段 5.3)。仅删除该课程在这些格上的课次。
*/
@Data
public class SchedulingCellOpRequest {
/** 实施_课程编号 */
private String sskcbh;
private List<SchedulingArrangeRequest.Cell> cells;
}
@@ -0,0 +1,31 @@
package com.roomroot.jwgl.dto.scheduling;
import lombok.Data;
/**
* 排课窗口内「编辑课程教学任务信息」请求(手册 12.3.1)。
*
* <p>只允许改运行编制的可调项:学时、周课时、课程简称、责任教员、默认场地。
* 课程简称写回学员队任务表(编制侧)后运行课程同步显示。</p>
*/
@Data
public class SchedulingCourseEditRequest {
/** 实施_课程编号 */
private String sskcbh;
/** 学时 */
private Integer xs;
/** 周课时 */
private Integer zks;
/** 课程简称 */
private String jc;
/** 责任教员编号 */
private String jybh;
/** 默认教学场地(教室编号) */
private String jsbh;
}
@@ -0,0 +1,20 @@
package com.roomroot.jwgl.dto.scheduling;
import lombok.Data;
/**
* 拖拽移动课次请求(阶段 E4):把课程在 from 格的课次平移到 to 格。
* 目标格沿用 arrange 的硬冲突校验;软提示(配当周次不符)照常移动并返回 warning。
*/
@Data
public class SchedulingMoveRequest {
/** 实施_课程编号 */
private String sskcbh;
/** 源格(已有课次) */
private SchedulingArrangeRequest.Cell from;
/** 目标格 */
private SchedulingArrangeRequest.Cell to;
}
@@ -0,0 +1,30 @@
package com.roomroot.jwgl.dto.taskbook;
import lombok.Data;
import java.util.List;
/**
* 批量填报请求:对所选课程任务行统一应用填报字段(仅写非空字段)。
*/
@Data
public class TaskBookBatchFillRequest {
/** 课程任务编号列表 */
private List<String> bhList;
/** 教研室计划教员编号 */
private String jysjhjybh;
/** 场地编号(useSpecial=true 时忽略,取班次专用教室) */
private String jsbh;
/** 使用班次专用教室 */
private Boolean useSpecial;
/** 排课建议(教研室计划备注) */
private String jysjhbz;
/** 课次序号 */
private Integer kcxh;
}
@@ -0,0 +1,21 @@
package com.roomroot.jwgl.dto.taskbook;
import lombok.Data;
import java.util.List;
/**
* 批量指定场地请求。
*/
@Data
public class TaskBookBatchRoomRequest {
/** 课程任务编号列表 */
private List<String> bhList;
/** 教室编号(useSpecial=false 时必传) */
private String jsbh;
/** true=使用各行班次专用教室(忽略 jsbh,取各班次学期.专用教室编号) */
private Boolean useSpecial;
}
@@ -0,0 +1,26 @@
package com.roomroot.jwgl.dto.taskbook;
import lombok.Data;
import java.util.List;
/**
* 批量指定责任教员请求。
*/
@Data
public class TaskBookBatchTeacherRequest {
/** 课程任务编号列表 */
private List<String> bhList;
/**
* 指定方式:
* unit — 责任单位教员(教员必须属于各行教研室 jysdh);
* academy — 全院教员(任意在职教员);
* plan — 应用各行教研室计划教员(jybh = 各行 jysjhjybh)。
*/
private String mode;
/** 责任教员编号(mode=unit / academy 时必传) */
private String jybh;
}
@@ -0,0 +1,15 @@
package com.roomroot.jwgl.dto.taskbook;
import lombok.Data;
import java.util.List;
/**
* 任务书批量操作请求(合班 / 按预设合班 / 拆班)。
*/
@Data
public class TaskBookBhListRequest {
/** 课程任务编号列表 */
private List<String> bhList;
}
@@ -0,0 +1,25 @@
package com.roomroot.jwgl.dto.taskbook;
import lombok.Data;
/**
* 教研室填报字段请求(阶段 4:计划教员 / 场地 / 排课建议)。
*/
@Data
public class TaskBookFillRequest {
/** 课程任务编号 */
private String bh;
/** 教研室计划教员编号 */
private String jysjhjybh;
/** 场地(教室编号;非空时同合班行同步) */
private String jsbh;
/** 排课建议(教研室计划备注) */
private String jysjhbz;
/** 课次序号(课序设置;非空时写入) */
private Integer kcxh;
}
@@ -0,0 +1,19 @@
package com.roomroot.jwgl.dto.taskbook;
import lombok.Data;
/**
* 场地指定请求(阶段 4)。
*/
@Data
public class TaskBookRoomRequest {
/** 课程任务编号 */
private String bh;
/** 教室编号(useSpecial=false 时必传) */
private String jsbh;
/** true=使用班次专用教室(忽略 jsbh,取班次学期.专用教室编号) */
private Boolean useSpecial;
}
@@ -0,0 +1,24 @@
package com.roomroot.jwgl.dto.taskbook;
import lombok.Data;
/**
* 责任教员指定请求(阶段 4:三种指定方式)。
*/
@Data
public class TaskBookTeacherRequest {
/** 课程任务编号 */
private String bh;
/**
* 指定方式:
* unit — 责任单位教员(教员必须属于该行教研室 jysdh);
* academy — 全院教员(任意在职教员);
* plan — 应用教研室计划教员(jybh = 该行 jysjhjybh)。
*/
private String mode;
/** 责任教员编号(mode=unit / academy 时必传) */
private String jybh;
}
@@ -1,7 +1,6 @@
package com.roomroot.jwgl.entity; package com.roomroot.jwgl.entity;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.*;
import com.roomroot.jwgl.unit.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -11,9 +10,8 @@ import java.time.LocalDateTime;
* 班次课堂教学日志_授课教员 * 班次课堂教学日志_授课教员
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@TableName("班次课堂教学日志_授课教员") @TableName("班次课堂教学日志_授课教员")
public class BCKTJXRZSKJY extends BaseEntity { public class BCKTJXRZSKJY {
@TableId(value = "编号", type = IdType.INPUT) @TableId(value = "编号", type = IdType.INPUT)
private String bh; private String bh;
@@ -3,7 +3,6 @@ package com.roomroot.jwgl.entity;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.roomroot.jwgl.unit.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -13,9 +12,8 @@ import java.time.LocalDateTime;
* 班次学期教材需求表 * 班次学期教材需求表
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@TableName("班次学期教材需求表") @TableName("班次学期教材需求表")
public class BCXQJCXQB extends BaseEntity { public class BCXQJCXQB {
/** /**
* 编号 * 编号
@@ -3,7 +3,6 @@ package com.roomroot.jwgl.entity;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.roomroot.jwgl.unit.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -13,9 +12,8 @@ import java.time.LocalDateTime;
* 补考 * 补考
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@TableName("补考") @TableName("补考")
public class BK extends BaseEntity { public class BK {
/** /**
* 编号 * 编号
@@ -3,7 +3,6 @@ package com.roomroot.jwgl.entity;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.roomroot.jwgl.unit.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -11,9 +10,8 @@ import lombok.EqualsAndHashCode;
* 补考地点表 * 补考地点表
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@TableName("补考地点表") @TableName("补考地点表")
public class BKDDB extends BaseEntity { public class BKDDB {
/** /**
* 编号 * 编号

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