# 网上培训课程 — 技术方案 > 依据:同目录 `网上培训课程功能需求.md`。本模块**只读**,数据**复用** `biz_tech_resource`(视频课程、已发布);**不新建业务表**、不提供增删改发布接口。 --- ## 1. 技术架构 | 项 | 说明 | | --- | --- | | **后端** | RuoYi **v3.9.2**(**springboot2** 分支):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid | | **数据库** | MySQL **5.7.39**,InnoDB,`utf8mb4` | | **前端** | 若依 Vue2(本期可后做;字段 **小驼峰**) | | **代码包(建议)** | `com.ruoyi.web.modules.technology`(与「实战业务培训」同目录) | **分层**:`BizOnlineTrainingCourseController` → `IBizOnlineTrainingCourseService` / `Impl` → `BizOnlineTrainingCourseMapper` + XML → 只读 **VO**(`OnlineTrainingCourseVo`)。 **数据策略** | 场景 | 行为 | | --- | --- | | 列表 / 详情 | **实时查询** `biz_tech_resource`,固定 `resource_type=004008`(视频课程)、`publish_status=1`、`del_flag=0` | | 维护课程 | 仍走 `/techService/techResource`(畜牧科技资源管理) | | 列表排序 | `create_time DESC, id DESC` | | 列表筛选 | `courseTitle` → `resource_name` **LIKE**;`courseTopic` → `course_topic` **=** | | 详情不存在 / 已下架 | `ServiceException`「该课程已下线或不存在」 | --- ## 2. 数据库设计 ### 2.1 复用表 `biz_tech_resource`(不新增表) 网上培训课程**不单独建表**;纳入记录即源表中已发布的视频课程行。 | 本模块语义 | 源表字段 | 说明 | | --- | --- | --- | | 课程标题 | `resource_name` | `varchar(64)` | | 课程简介 | `introduction` | `varchar(500)` | | 课程主题 | `course_topic` | `varchar(32)` | | 视频 | `video_file_url` / `video_file_path` | `varchar(512)` | | 封面 | `cover_file_url` / `cover_file_path` | 选填 | | 发布时间 | `publish_time` | 详情可选展示 | | 审计 | `create_time` / `update_time` 等 | 若依惯例 | **固定查询条件(列表、详情均须满足)** ```text resource_type = '004008' AND publish_status = 1 AND del_flag = '0' ``` **索引(已有,无需本期变更)**:`idx_type (resource_type)`、`idx_publish (publish_status)`、`idx_del (del_flag)`、`idx_name (resource_name)`。若线上列表量大,可评审复合索引 `(resource_type, publish_status, del_flag, create_time)`。 ### 2.2 源表结构摘要(实施参考) 表 DDL 见 `sql/biz_tech_resource.sql`;网上培训课程仅使用其中视频课程相关列,完整定义见《畜牧科技资源管理 — 技术方案》。 ### 2.3 枚举(代码常量) | 常量 | 值 | 说明 | | --- | --- | --- | | `RESOURCE_TYPE_VIDEO` | `4` | 视频课程(复用 `TechResourceRules`) | | `PUBLISH_STATUS_PUBLISHED` | `1` | 已发布 | | `DEL_FLAG_NORMAL` | `'0'` | 未删除 | **课程主题**:存 `biz_tech_resource.course_topic` 资讯类别编码(`parentCode=005`、`categoryType=8`,如 `005001` 基础养殖)。下拉选项来自 `GET /category/informationCategory/children?parentCode=005&categoryType=8`;接口 `courseTopics` 另合并库内已发布课程的去重编码。 --- ## 3. 接口设计 **统一响应**:`AjaxResult`(`code` / `msg` / `data`)或分页 `TableDataInfo`(`rows` / `total`)。 **权限标识**:`techService:onlineTrainingCourse:list|query` **Base Path**:`/techService/onlineTrainingCourse` | # | 说明 | Method | URI | 权限 | | --- | --- | --- | --- | --- | | 3.1 | 分页列表 | GET | `/techService/onlineTrainingCourse/list` | `list` | | 3.2 | 详情 | GET | `/techService/onlineTrainingCourse/{id}` | `query` | | 3.3 | 课程主题下拉 | GET | `/techService/onlineTrainingCourse/courseTopics` | `list` | > **本期无** POST / PUT / DELETE / 发布 / 下架。 ### 3.1 分页列表 **Query** | 参数 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `pageNum` / `pageSize` | int | N | 默认 `1` / `20` | | `courseTitle` | string | N | 课程标题,对 `resource_name` **模糊**;trim 后空则不过滤 | | `courseTopic` | string | N | 课程主题,对 `course_topic` **精确**;空则不过滤 | **`rows` 元素(`OnlineTrainingCourseListVo`,驼峰)** | 字段 | 来源 | 说明 | | --- | --- | --- | | `id` | `id` | 主键 | | `courseTitle` | `resource_name` | 课程标题 | | `courseIntro` | `introduction` | 课程简介(列表可原样返回,前端摘要) | | `courseTopic` | `course_topic` | 课程主题 | | `videoFileName` | `video_file_path` | 取路径最后一段文件名;无则「已上传」 | | `createTime` | `create_time` | 可选,供排序核对 | **列表 SQL 不返回**:`video_file_url`(详情再看)、`cover_*`(减轻列表负载)。 ### 3.2 详情 **Path**:`id` — `biz_tech_resource.id` **`data`(`OnlineTrainingCourseDetailVo`)** | 字段 | 来源 | 说明 | | --- | --- | --- | | `id` | `id` | | | `courseTitle` | `resource_name` | | | `courseIntro` | `introduction` | 全文 | | `courseTopic` | `course_topic` | | | `videoFileUrl` | `video_file_url` | 播放地址 | | `videoFilePath` | `video_file_path` | | | `videoFileName` | 派生 | 同列表 | | `coverFileUrl` | `cover_file_url` | 可空 | | `coverFilePath` | `cover_file_path` | 可空 | | `publishTime` | `publish_time` | 可空 | | `createTime` / `updateTime` | 审计字段 | 建议返回 | **校验**:查询结果须满足 **§2.1** 三条件;否则 `ServiceException`「该课程已下线或不存在」。 ### 3.3 课程主题下拉 **响应 `data`**:`InformationCategoryItemVo[]`,按 `category_code` 升序。 | 字段 | 说明 | | --- | --- | | `code` | 资讯类别编码(如 `005001`) | | `name` | 类别名称(如 `基础养殖`) | **SQL 逻辑**:`selectDistinctCourseTopics` 从 `biz_information_category` 查询 `parent_code='005'`、`category_type='8'` 的下级,返回 `category_code`、`category_name`。 ### 3.4 Mapper 约定 - 独立 `BizOnlineTrainingCourseMapper.xml`,**只读** `selectList`、`selectById`、`selectDistinctCourseTopics`。 - **禁止** 在本模块 XML 中写 insert/update/delete。 - 列表 `WHERE` 固定 **§2.1** + 动态 `courseTitle` / `courseTopic`。 - 详情 `WHERE id = #{id}` + **§2.1**(一条 SQL 即可,无行则 Service 抛异常)。 ### 3.5 Service 要点 | 类 | 职责 | | --- | --- | | `OnlineTrainingCourseRules` | 固定类型/发布态/删除标记常量;`videoFileName(path)` 工具 | | `BizOnlineTrainingCourseServiceImpl` | 列表分页、详情、主题列表;Entity → Vo 映射 | **不依赖** `TechResourceValidation`(无写操作);可读 `TechResourceRules.RESOURCE_TYPE_VIDEO` 等常量,避免魔法数。 --- ## 4. 菜单与权限(示例) | 类型 | 名称 | 权限标识 | | --- | --- | --- | | 菜单 | 网上培训课程 | `techService:onlineTrainingCourse:list` | | 按钮 | 查询 | `techService:onlineTrainingCourse:query` | 组件路径(建议):`techService/onlineTrainingCourse/index`(挂在「科技平台与服务」目录下)。 **菜单 SQL**:本期仅 `list`、`query` 两个按钮权限;**无** add/edit/remove。 --- ## 5. 与畜牧科技资源管理的关系 | 项 | 约定 | | --- | --- | | 写操作 | 仅 `/techService/techResource`,`resourceType=4` | | 发布生效 | 源库 `publish_status=1` 后,本模块 list/detail 立即可见 | | 下架/删除 | 源库下架或 `del_flag=2` 后,本模块查不到;详情返回 **§3.2** 异常文案 | | 字段长度/附件规则 | 以源库 `TechResourceValidation` 为准,本模块不重复校验 | --- ## 6. 交付清单 - [ ] `OnlineTrainingCourseVo`(list/detail)、`OnlineTrainingCourseRules` - [ ] `BizOnlineTrainingCourseMapper` + `mapper/technology/BizOnlineTrainingCourseMapper.xml` - [ ] `IBizOnlineTrainingCourseService` / `Impl`、`BizOnlineTrainingCourseController` - [ ] 菜单权限 SQL(`onlineTrainingCourse:list|query`) - [ ] 单元测试:文件名解析、纳入条件过滤(Mock Mapper) - [ ] MockMvc:list 筛选、`/{id}` 成功与下线失败、`courseTopics` - [ ] **无需** `sql/biz_online_training_course.sql` --- ## 7. 修订记录 | 版本 | 说明 | | --- | --- | | 1.0 | 初稿:复用 `biz_tech_resource`;只读 list/detail/courseTopics;包路径 `technology`;Base `/techService/onlineTrainingCourse` |