# 课程资源分享(门户侧)API 文档(对齐 RuoYi 格式) 更新时间:2025-11-07 ## 概览 - 业务说明:面向登录用户的课程资源浏览与“我的资源”管理。公开列表仅展示“已通过(1)”资源;个人可新增/编辑/删除/提交上架/下架。 - 角色与权限:登录(`isAuthenticated()`);所有写操作在服务层强约束“仅作者本人可操作”。 - 依赖表:`tb_course_resource`、`tb_course`、`tb_major` - 环境信息: - baseURL:`http://localhost:8080` - 认证:`Authorization: Bearer `(登录后获取) ## 领域模型与约束 - 核心字段(简表): - `id`(bigint) 主键 - `majorId`(bigint) 专业ID;`majorName` 冗余名 - `courseId`(bigint) 课程ID;`courseName` 冗余名 - `resourceName`(string) 资源名称(必填,≤100) - `resourceType`(int) 0文件 1外链 - 文件类:`fileUrl`(string) 必填、`fileHash`(string) 必填、`fileSize`(long) 建议填 - 外链类:`linkUrl`(string) 必填 - `description`(string) 资源说明(≤2000) - `status`(int) 0待审 1通过 2驳回 3下架 - 审核:`auditBy/auditTime/auditReason`;最佳:`isBest/bestBy/bestTime` - 统计:`downloadCount/lastDownloadTime` - 作者:`uploaderId/uploaderName` - 审计:`create_by/create_time/update_by/update_time/del_flag` - 状态流转: - 新增 → 待审(0) - 待审(0) → 通过(1)/驳回(2) - 通过(1) → 下架(3) - 驳回/下架(2/3) → 待审(0)(提交上架或管理端“上线”) - 资源约束: - 仅允许压缩包(zip/rar/7z/tar/gz/bz2/xz)或外链;强烈建议通过上传网关获取 `fileUrl` 与 `fileHash`。 - 唯一性:同一课程(`courseId`)下,`fileHash`(文件型)或 `linkUrl`(外链型)唯一,避免重复提交。 - 大小:文件 ≤100MB;由上传网关与服务层共同控制。 ## 分页/过滤/排序(通用) - 分页:`pageNum`、`pageSize`;默认 1/10 - 过滤:`majorId`、`courseId`、`resourceName`(模糊)/`courseName`(模糊)/`status`(我的列表) - 排序:`orderByColumn` + `isAsc`(遵循 RuoYi 约定);默认“最佳优先 + ID 倒序”。 ## 路由清单 ### 专业列表(门户) - 方法:GET - 路径:`/portal/major/list` - 权限:登录 - 请求参数(query,可选): - `majorName`(string) 模糊匹配 - `pageNum`(int) 默认 1 - `pageSize`(int) 默认 10 - 返回:`{ code:200, rows:[Major], total:n }` ### 课程列表(门户) - 方法:GET - 路径:`/portal/course/list` - 权限:登录 - 请求参数(query,可选): - `majorId`(long) 所属专业 - `courseName`(string) 模糊匹配 - `pageNum`(int) 默认 1 - `pageSize`(int) 默认 10 - 返回:`{ code:200, rows:[Course], total:n }` ### 资源列表(仅已通过) - 方法:GET - 路径:`/portal/resource/list` - 权限:登录 - 请求参数(query,可选): - `majorId`(long) - `courseId`(long) - `resourceName`(string) 模糊 - `courseName`(string) 模糊 - `pageNum`(int) 默认 1 - `pageSize`(int) 默认 10 - 返回示例: ```json { "code": 200, "rows": [ { "id": 101, "resourceName": "算法作业参考", "status": 1, "isBest": 0, "majorName": "计算机", "courseName": "数据结构" } ], "total": 1 } ``` ### 资源详情 - 方法:GET - 路径:`/portal/resource/{id}` - 权限:登录 - 规则:若资源非“已通过(1)”,仅作者本人可见;否则返回 `{ code:500, msg:"资源不存在或未上架" }`。 - 成功示例:`{ "code":200, "data": { "id":101, "status":1, "downloadCount":3 } }` ### 下载(计数 + 302 重定向) - 方法:GET - 路径:`/portal/resource/{id}/download` - 权限:登录 - 行为:返回 HTTP 302,`Location` 指向 `fileUrl`(文件)或 `linkUrl`(外链)。仅“已通过(1)”允许下载;否则返回 HTTP 404。 ### 榜单(下载 TopN) - 方法:GET - 路径:`/portal/resource/top` - 权限:登录 - 请求参数(query): - `scope`(string) `global|major|course`,默认 global - `majorId`(long) 当 `scope=major` 必填 - `courseId`(long) 当 `scope=course` 必填 - `days`(int) 统计窗口天数,默认 7 - `limit`(int) 返回条数,默认 10 - 返回:`{ code:200, data: [Resource] }` ### 我的资源列表(全状态) - 方法:GET - 路径:`/portal/resource/my/list` - 权限:登录 - 请求参数(query,可选): - - `status`(int) 0/1/2/3 - 其余同“资源列表” - 返回:仅当前登录用户上传的资源,所有状态。 ### 新增资源(进入待审) - 方法:POST - 路径:`/portal/resource` - 权限:登录 - 请求体(json,文件型示例): ```json { "majorId": 1, "courseId": 11, "resourceName": "算法作业参考", "resourceType": 0, "fileUrl": "https://oss.example.com/resource/demo.zip", "fileHash": "sha256:...", "fileSize": 3456789, "description": "仅供学习参考" } ``` - 请求体(json,外链型示例): ```json { "majorId": 1, "courseId": 11, "resourceName": "算法资料外链", "resourceType": 1, "linkUrl": "https://pan.example.com/xxx" } ``` - 返回:`{ "code":200, "data": { "id": 101 } }` - 备注:建议先调用上传网关 `POST /portal/upload/oss?scene=resource.archive` 获取 `fileUrl`(同时获取文件哈希)。 ### 编辑资源(仅作者;编辑后回待审) - 方法:PUT - 路径:`/portal/resource` - 权限:登录 - 请求体:包含 `id` 及需更新字段;服务端将 `status` 重置为 0。 - 失败语义:若非作者、或当前为“通过(1)”未下架 → 返回 `{ code:500, msg: '...' }`。 ### 删除资源(仅作者;待审/驳回/下架可删) - 方法:DELETE - 路径:`/portal/resource/{id}` - 权限:登录 - 返回:`{ "code": 200 }` ### 提交上架(转待审) - 方法:PUT - 路径:`/portal/resource/{id}/online` - 权限:登录 - 行为:将状态置为“待审(0)”,仅当当前状态为“驳回/下架(2/3)”时成功。 ### 下架(仅作者或有权者) - 方法:PUT - 路径:`/portal/resource/{id}/offline` - 权限:登录 - 请求体(json,可选):`{ "reason": "不再维护/内容更新" }` - 行为:仅当当前状态为“通过(1)”时成功。 ## 错误码与语义 - 401 未授权:未携带/过期 token - 403 越权:非作者进行写操作 - 404 不存在或未上架:下载在非作者且非“通过(1)”时;详情为 `{ code:500, msg }` 错误 - 409 状态冲突:如“已通过请先下架再编辑/删除”等(部分接口以 500 + msg 表达) - 500 业务失败:唯一约束冲突、参数非法等(返回明确 `msg`) ## 上传与校验(OSS) - 推荐使用门户上传网关:`POST /portal/upload/oss` - 建议参数:`scene=resource.archive` - 可选:`dir`(子目录)、`publicUrl`(是否返回公开URL,默认 true) - 校验:扩展名仅限 `zip/rar/7z/tar/gz/bz2/xz`;大小 ≤100MB;返回对象含 `url`、`hash` 等关键字段 ## 备注 - 分页与排序:沿用 RuoYi 通用分页;默认按“最佳优先、ID倒序”。 - 幂等与约束: - 新增对“同课程+文件哈希/外链 URL”有唯一约束,避免重复提交。 - 编辑会将状态重置为“待审(0)”。 - Apifox 导入建议:将本模块放入“课程资源-门户”分组,环境 `local` baseURL=`http://localhost:8080`,统一设置 `Authorization` 变量。