依据:同目录
实战业务培训功能需求.md。培训主档 CRUD + 发布/下架 +training_status持久化 + 小程序报名/取消(biz_practical_training_member);封面复用若依/common/upload。
| 项 | 说明 |
|---|---|
| 后端 | RuoYi v3.9.2(springboot2 分支):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| 数据库 | MySQL 5.7.39,InnoDB,utf8mb4 |
| 前端 | 若依 Vue2;时间 yyyy-MM-dd HH:mm:ss;封面上传后提交 URL、存储路径 |
| 代码包(建议) | com.ruoyi.web.modules.techservice |
分层:Controller → Service(PracticalTrainingValidation、报名状态计算、发布状态机、替换封面删旧文件)→ Mapper/XML → domain。
业务摘要
| 场景 | 行为 |
|---|---|
| 新增「仅保存」 | publish_status=0,publish_time=NULL |
| 新增「保存并发布」 | Body saveAndPublish=true 或调发布接口;publish_status=1,publish_time=now() |
| 修改 / 删除 / 发布 | 仅 publish_status=0 且 del_flag=0 |
| 下架 | 仅 publish_status=1 且 now() < registration_start_time → publish_status=0,写 offline_time;保留 publish_time |
| 报名状态 | 列表/详情由 PracticalTrainingEnrollStatusResolver 按 §3.4 计算,不入库 |
| 实际报名人数 | 字段 actual_enrolled_count,默认 0;后续报名模块 UPDATE 汇总 |
| 列表排序 | training_time DESC, id DESC |
| 列表筛选 | trainingTopic 精确;startDate/endDate 对 DATE(training_time) 闭区间 |
biz_practical_training(实战业务培训)| 字段 | 类型 | 非空 | 默认值 | 说明 |
|---|---|---|---|---|
id |
bigint(20) |
Y | 自增 | 主键 |
training_topic |
varchar(64) |
Y | — | 培训主题(1~20 字) |
training_time |
datetime |
Y | — | 培训时间 |
training_intro |
varchar(500) |
Y | — | 培训简介 |
planned_head_count |
int(11) |
Y | — | 计划人数(正整数) |
training_location |
varchar(200) |
Y | — | 培训地点 |
expected_outcome |
text |
N | NULL | 预期成果 |
registration_start_time |
datetime |
Y | — | 报名开始时间 |
registration_end_time |
datetime |
Y | — | 报名截止时间 |
cover_file_url |
varchar(512) |
N | NULL | 封面 URL |
cover_file_path |
varchar(512) |
N | NULL | 封面存储路径 |
actual_enrolled_count |
int(11) |
Y | 0 |
实际报名人数(成员表汇总) |
training_status |
varchar(32) |
Y | 006001 |
培训状态字典 006 |
publish_status |
tinyint(4) |
Y | 0 |
0 未发布 1 已发布 |
publish_time |
datetime |
N | NULL | 发布时间(列表「发布日期」取日期部分) |
offline_time |
datetime |
N | NULL | 下架时间 |
del_flag |
char(1) |
Y | '0' |
0 存在 2 删除 |
create_by / create_time / update_by / update_time |
若依惯例 | — | — | 审计 |
remark |
varchar(500) |
N | NULL | 备注 |
索引:PRIMARY KEY (id);KEY idx_training_time (training_time);KEY idx_training_topic (training_topic);KEY idx_publish (publish_status);KEY idx_reg_start (registration_start_time);KEY idx_del_flag (del_flag)。
CREATE TABLE `biz_practical_training` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`training_topic` varchar(64) NOT NULL COMMENT '培训主题',
`training_time` datetime NOT NULL COMMENT '培训时间',
`training_intro` varchar(500) NOT NULL COMMENT '培训简介',
`planned_head_count` int(11) NOT NULL COMMENT '计划人数',
`training_location` varchar(200) NOT NULL COMMENT '培训地点',
`expected_outcome` text COMMENT '预期成果',
`registration_start_time` datetime NOT NULL COMMENT '报名开始时间',
`registration_end_time` datetime NOT NULL COMMENT '报名截止时间',
`cover_file_url` varchar(512) DEFAULT NULL COMMENT '封面URL',
`cover_file_path` varchar(512) DEFAULT NULL COMMENT '封面存储路径',
`actual_enrolled_count` int(11) NOT NULL DEFAULT '0' COMMENT '实际报名人数',
`publish_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0未发布 1已发布',
`publish_time` datetime DEFAULT NULL COMMENT '发布时间',
`offline_time` datetime DEFAULT NULL COMMENT '下架时间',
`del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '0存在 2删除',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`),
KEY `idx_training_time` (`training_time`),
KEY `idx_training_topic` (`training_topic`),
KEY `idx_publish` (`publish_status`),
KEY `idx_reg_start` (`registration_start_time`),
KEY `idx_del_flag` (`del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='实战业务培训';
发布状态 publish_status
| 值 | 标签 |
|---|---|
| 0 | 未发布 |
| 1 | 已发布 |
培训状态 training_status
| 编码 | 标签 |
|---|---|
006001 |
未开始 |
006002 |
报名中 |
006003 |
已报满 |
006004 |
已截止 |
管理端列表仍返回 enrollStatus(1–4)与 enrollStatusName,由 training_status 映射,兼容原前端。
biz_practical_training_member| 字段 | 说明 |
|---|---|
training_id |
关联主表 |
member_name |
报名人姓名 |
sys_user_id |
小程序用户 |
enroll_status |
0 已报名 1 已取消 |
enroll_time / cancel_time |
报名/取消时间 |
唯一约束:uk_training_user (training_id, sys_user_id)。
见 doc/app/实战业务培训/实战业务培训接口说明.md:GET /myEnroll/list、GET /myEnroll/{id}、POST /{id}/enroll、POST /{id}/cancelEnroll。
统一响应:AjaxResult / TableDataInfo。
权限标识:techService:practicalTraining:list|query|add|edit|remove|publish|offline
Base Path:/techService/practicalTraining
| # | 说明 | Method | URI | 权限 |
|---|---|---|---|---|
| 3.1 | 分页列表 | GET | /techService/practicalTraining/list |
list |
| 3.2 | 详情 | GET | /techService/practicalTraining/{id} |
query |
| 3.3 | 新增 | POST | /techService/practicalTraining |
add |
| 3.4 | 修改 | PUT | /techService/practicalTraining |
edit |
| 3.5 | 删除 | DELETE | /techService/practicalTraining/{ids} |
remove |
| 3.6 | 发布 | POST | /techService/practicalTraining/publish/{id} |
publish |
| 3.7 | 下架 | POST | /techService/practicalTraining/offline/{id} |
offline |
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNum / pageSize |
int | N | 默认 1 / 20 |
trainingTopic |
string | N | 培训主题精确匹配 |
startDate / endDate |
string | N | yyyy-MM-dd;DATE(training_time) 闭区间;起 > 止抛业务异常 |
列表行扩展(驼峰):除表字段外含 enrollStatus、enrollStatusName(§3.4);publishTime 格式化为日期供「发布日期」列。
data全业务字段 + enrollStatus / enrollStatusName + 审计字段;canOffline(boolean,是否允许下架,供前端控制按钮)。
| 字段 | 新增 | 修改 | 说明 |
|---|---|---|---|
id |
— | Y | 主键 |
trainingTopic |
Y | Y | 1~20 字 |
trainingTime |
Y | Y | yyyy-MM-dd HH:mm:ss |
trainingIntro |
Y | Y | trim 后非空;≤500 字 |
plannedHeadCount |
Y | Y | 整数 ≥1 |
trainingLocation |
Y | Y | 1~200 字 |
expectedOutcome |
N | N | 选填 |
registrationStartTime |
Y | Y | 须满足 §3.5 时间链 |
registrationEndTime |
Y | Y | 同上 |
coverFileUrl / coverFilePath |
N | N | 同时有或同时无 |
saveAndPublish |
N | — | 仅新增;true 时保存后发布 |
remark |
N | N | ≤500 字 |
IF publish_status = 0 → 006001
ELSE IF now >= registration_end_time → 006004
ELSE IF now < registration_start_time → 006001
ELSE IF actual_enrolled_count >= planned_head_count → 006003
ELSE IF registration_start <= now < registration_end → 006002
实现类:PracticalTrainingEnrollStatusResolver.resolveTrainingStatus(row, now);持久化:PracticalTrainingStatusSupport.refreshAndPersist。
PracticalTrainingValidation)| 项 | 规则 |
|---|---|
| 时间链 | registrationStartTime < registrationEndTime < trainingTime |
| 计划人数 | plannedHeadCount >= 1 |
| 封面 | 可空;有则 jpg,jpeg,png,≤10MB(与上传接口一致) |
| 发布/修改/删除 | 目标记录 publish_status=0 且 del_flag=0 |
| 下架 | publish_status=1 且 now() < registration_start_time;否则 ServiceException「报名已开始,不允许下架」 |
| 删除 | 若 actual_enrolled_count > 0 宜禁止(可选,评审) |
| 列表日期 | startDate ≤ endDate(均填时) |
| 操作 | 结果 |
|---|---|
| 发布 | publish_status=1,publish_time=now();再次校验 §3.5 |
| 下架 | publish_status=0,offline_time=now();不删封面;不清 publish_time |
del_flag='0'。del_flag='2'。publish_status=0(下架除外)。| 类型 | 名称 | 权限标识 |
|---|---|---|
| 菜单 | 实战业务培训 | techService:practicalTraining:list |
| 按钮 | 查询 | techService:practicalTraining:query |
| 按钮 | 新增 | techService:practicalTraining:add |
| 按钮 | 修改 | techService:practicalTraining:edit |
| 按钮 | 删除 | techService:practicalTraining:remove |
| 按钮 | 发布 | techService:practicalTraining:publish |
| 按钮 | 下架 | techService:practicalTraining:offline |
组件路径:techService/practicalTraining/index(「科技平台与服务」目录下)。
sql/biz_practical_training.sql、菜单权限 SQLBizPracticalTraining、Mapper/XML、Service、ControllerPracticalTrainingValidation、PracticalTrainingEnrollStatusResolver、PracticalTrainingRules| 版本 | 说明 |
|---|---|
| 1.0 | 初稿:biz_practical_training;CRUD+发布下架;报名状态计算;下架须早于报名开始;封面复用通用上传 |