# 课程资源分享(管理)API 文档(高质量版) ## 概览 - 业务说明:管理端对课程资源提供全生命周期治理:全量检索、审核(通过/驳回)、上下架、最佳推荐、下载(审核用途)与删除。与门户分离,避免按钮权限影响门户调用。 - 权限模型:基于 `manage:courseResource:*` 的按钮级权限;专业负责人(`major_lead`)仅能操作本专业范围内的资源(下载等已在服务端校验)。 - 依赖表:`tb_course_resource`、`tb_course`、`tb_major` - 基础信息: - baseURL:`http://localhost:8080` - 认证:`Authorization: Bearer `(管理员/专业负责人等) ## 领域模型与状态 - 字段见门户文档的“领域模型”小节;管理端可见所有状态,允许状态流转: - 待审(0) → 通过(1)/驳回(2) - 通过(1) → 下架(3) - 驳回/下架(2/3) → 待审(0)(通过“在线/online”入口) - 最佳推荐:`isBest=1`、`bestBy/bestTime` 记录;仅管理端可设置/取消。 ## 权限矩阵(按钮级) - 列表:`manage:courseResource:list` - 详情:`manage:courseResource:query` - 新增:`manage:courseResource:add` - 编辑:`manage:courseResource:edit` - 删除:`manage:courseResource:remove` - 通过:`manage:courseResource:approve` - 驳回:`manage:courseResource:reject` - 下架:`manage:courseResource:offline` - 上线(转待审):`manage:courseResource:online` - 下载:`manage:courseResource:download` - 最佳/取消最佳:`manage:courseResource:best` ## 查询/分页/过滤 - 分页:`pageNum/pageSize` - 过滤: - `status`(int) 0/1/2/3 - `majorId`(long)、`courseId`(long) - `uploaderId`(long) 或 `uploaderName`(string) - `resourceName`(string) 模糊、`courseName`(string) 模糊、`description`(string) 模糊 - 排序:`orderByColumn` + `isAsc`(默认按“最佳优先 + ID 倒序”) ## 接口清单与示例 ### 列表 - 方法:GET - 路径:`/manage/courseResource/list` - 权限:`manage:courseResource:list` - 请求参数(query,可选): - `status`(int) 0/1/2/3 - `majorId`(long)、`courseId`(long) - `uploaderId`(long) 或 `uploaderName`(string) - `resourceName`(string) 模糊、`courseName`(string) 模糊、`description`(string) 模糊 - `pageNum`(int) 默认 1、`pageSize`(int) 默认 10 - 返回示例: ```json { "code": 200, "rows": [ { "id": 101, "resourceName": "数据结构复习资料", "status": 0, "isBest": 0, "uploaderName": "student", "majorName": "计算机", "courseName": "数据结构" } ], "total": 1 } ``` ### 详情 - 方法:GET - 路径:`/manage/courseResource/{id}` - 权限:`manage:courseResource:query` ### 新增 / 编辑 / 删除 - 新增:POST `/manage/courseResource` | 权限:`manage:courseResource:add` - 编辑:PUT `/manage/courseResource` | 权限:`manage:courseResource:edit` - 删除:DELETE `/manage/courseResource/{ids}` | 权限:`manage:courseResource:remove` - 新增请求体(json,文件型示例): ```json { "majorId": 1, "courseId": 11, "resourceName": "数据结构复习资料", "resourceType": 0, "fileUrl": "https://...", "fileHash": "sha256:...", "fileSize": 3456789, "description": "章节要点与期末整理" } ``` - 编辑请求体(json,示例): ```json { "id": 101, "resourceName": "复习资料(更新)", "description": "补充历年题" } ``` - 说明与规则: - 新增时服务端自动补全:`uploaderId/uploaderName/createBy/createTime`,并置 `status=0`。 - 编辑会将 `status` 重置为 0;若非 admin/major_lead,且原状态为 1(通过),需先下架后再编辑。 - 删除按服务层约束执行;调用端传 `{ids}` 逗号分隔。 ### 审核通过 / 驳回 - 通过:PUT `/manage/courseResource/{id}/approve` | 权限:`manage:courseResource:approve` - 驳回:PUT `/manage/courseResource/{id}/reject` | 权限:`manage:courseResource:reject` - 驳回请求体:`{ "reason": "与课程不匹配" }` - 规则: - 通过:仅当当前状态为 `0(待審)` 或 `3(下架)` 时成功。 - 驳回:允许 `0/1/3`,会写入 `auditBy/auditTime/auditReason`。 - 违反将返回错误(通常为 `{ code:500, msg }`)。 ### 下架 / 上线(转待审) - 下架:PUT `/manage/courseResource/{id}/offline` | 权限:`manage:courseResource:offline`,Body:`{ "reason": "内容违规" }`(仅 `status=1` 时成功) - 上线:PUT `/manage/courseResource/{id}/online` | 权限:`manage:courseResource:online`(`status in (2,3)` → `0`) ### 最佳推荐 / 取消最佳 - 设为最佳:PUT `/manage/courseResource/{id}/best` | 权限:`manage:courseResource:best` - 取消最佳:PUT `/manage/courseResource/{id}/unbest` | 权限:`manage:courseResource:best` - 说明:基于表 `tb_course_resource_best` 维护,支持幂等多次设置与取消。 ### 下载(302) - 方法:GET - 路径:`/manage/courseResource/{id}/download` - 权限:`manage:courseResource:download` - 行为:302 跳转至 `fileUrl`/`linkUrl`,并计数; - 权限说明: - admin/major_lead 在任意状态可下载; - 若为 major_lead 且资源专业不在其范围,返回 HTTP 403; - 普通有按钮权限的用户仅可下载“已通过(1)”的资源(否则 404)。 ### 统计:上传趋势(折线图) - 方法:GET - 路径:`/manage/courseResource/stats/uploadTrend` - 权限:登录(isAuthenticated) - 请求参数(query): - `days`(int) 可选,默认 30,范围 1~365(含今天) - 返回示例: ```json { "code": 200, "msg": "操作成功", "data": [ { "day": "2025-11-01", "count": 12 }, { "day": "2025-11-02", "count": 7 } ] } ``` - 备注:按 `create_time` 聚合;无数据的日期数量为 0。 ### 统计:下载趋势(折线图) - 方法:GET - 路径:`/manage/courseResource/stats/downloadTrend` - 权限:登录(isAuthenticated) - 请求参数(query): - `days`(int) 可选,默认 30,范围 1~365(含今天) - 返回示例: ```json { "code": 200, "msg": "操作成功", "data": [ { "day": "2025-11-01", "count": 22 }, { "day": "2025-11-02", "count": 35 } ] } ``` - 备注:按 `tb_course_resource_log` 中 `action='DOWNLOAD'` 的 `create_time` 聚合;无数据的日期数量为 0。 ### 排行:资源下载Top(柱状图) - 方法:GET - 路径:`/manage/courseResource/stats/topResources` - 权限:登录(isAuthenticated) - 参数(query): - `limit`(int) 默认 5 - `days`(int) 默认 30(统计窗口,基于 `publish_time/last_download_time`) - 返回:`[{ id, resourceName, downloadCount }]` ### 排行:用户积分Top(柱状图) - 方法:GET - 路径:`/manage/courseResource/stats/topScoreUsers` - 权限:登录(isAuthenticated) - 参数(query): - `limit`(int) 默认 5 - 返回:`[{ userId, username, totalScore, rank? }]` ### 排行:用户下载Top(柱状图) - 方法:GET - 路径:`/manage/courseResource/stats/topDownloadUsers` - 权限:登录(isAuthenticated) - 参数(query):`limit`(int) 默认 5 - 返回:`[{ userId, username|nickname, passedCount }]`(passedCount 表示下载次数) ### 占比:上传·专业占比(饼图) - 方法:GET - 路径:`/manage/courseResource/stats/majorShare` - 权限:登录(isAuthenticated) - 参数:`days`(int) 默认 30 - 返回:`[{ id, name, value }]` ### 占比:上传·课程占比(饼图) - 方法:GET - 路径:`/manage/courseResource/stats/courseShare` - 权限:登录(isAuthenticated) - 参数:`days`(int) 默认 30 - 返回:`[{ id, name, value }]` ### 榜单 - 管理端不提供独立“榜单”接口;请使用门户端接口: - GET `/portal/resource/top?scope=global|major|course&days=7&limit=10[&majorId|&courseId]` ## 业务校验与错误码 - 唯一性:同一课程 + 文件哈希/外链 URL 不可重复;冲突返回 500 并附清晰 `msg`。 - 典型错误码: - 401 未授权:token 缺失/过期 - 403 权限不足:缺少对应 `manage:courseResource:*` - 404 不存在:资源不存在或已删除 - 409 冲突:状态不允许当前操作(如下架仅允许在已通过状态) - 500 业务失败:参数校验/唯一约束/服务异常 ## 上传与资产 - 管理端可复用统一上传接口:`POST /manage/upload/oss`(权限:`manage:upload:oss`) - 参数:`dir`(可选)、`publicUrl`(可选) - 返回:`data.url` 可直接作为 `fileUrl` ## 备注 - 排序默认“最佳优先 + ID 倒序”;榜单为下载数倒序。 - 编辑/上线/下线/审核严格受状态机约束,请参考上文各接口“规则”。 - Apifox 导入建议:将本模块放入“课程资源-管理”分组,环境 `local` baseURL=`http://localhost:8080`,统一设置 `Authorization` 变量。