Skip to main content

xj-study 学习中心模块

基于 Django 的学习中心微服务模块,采用 Model-Services-APIs 三层架构设计,与 xj-lexiconxj-exam 等模块保持完全一致的工程约定。本模块管理「学科 → 学习阶段 → 学习单元 → 单元任务 → 用户任务记录」五级学习层级,并支持通过外部考核接口回调记录学生测试结果。


一、目录结构

xj-study/
├── xj_study/
│   ├── apis/                       # API 层(视图 + 路由参数解析)
│   │   ├── study_subject_api.py        学科列表 / 详情
│   │   ├── study_stage_api.py          学习阶段列表 / 详情
│   │   ├── study_unit_api.py           学习单元列表 / 详情
│   │   ├── study_task_api.py           单元任务 列表 / 详情 / 新增 / 修改
│   │   └── study_user_task_api.py      用户任务记录 列表 / 详情 / 开启 / 提交
│   ├── services/                  # 业务逻辑层(查询/分页/过滤/写库)
│   │   ├── study_subject_service.py
│   │   ├── study_stage_service.py
│   │   ├── study_unit_service.py
│   │   ├── study_task_service.py
│   │   └── study_user_task_service.py
│   ├── utils/                     # 工具层(与 xj-lexicon 同步)
│   │   ├── custom_response.py         util_response 统一响应封装
│   │   ├── custom_tool.py             format_params_handle 字段过滤
│   │   ├── j_transform_type.py        JTransformType 类型强制转换
│   │   ├── request_params_wrapper.py  request_params_wrapper 参数解析装饰器
│   │   └── parse_json.py             JSON 字符串解析
│   ├── __init__.py
│   ├── apps.py                    # AppConfig:name='xj_study',sort=14
│   ├── admin.py                   # 后台注册(5 个模型)
│   ├── models.py                  # 数据模型定义
│   └── urls.py                    # 子路由分发
├── __init__.py
└── README.md

三层职责

职责 约定
Model 仅定义数据结构与字段 不写业务方法
Service 全部业务逻辑:参数校验、过滤白名单、分页、时间格式化、关联嵌套查询、写库 @staticmethod,统一返回 (result, error) 元组;不直接接触 request/response
API 视图层:解析请求参数、调 Service、统一响应 继承 APIView@request_params_wrapper 注入 request_paramsutil_response() 返回

二、数据模型层级

StudySubject(学科)
  └── StudyStage(学习阶段/册)        FK→subject
        └── StudyUnit(学习单元)       FK→stage
              └── StudyTask(单元任务)   FK→unit,含 exam_url / thread_id 外部考核回调字段
                    └── StudyUserTask(用户任务记录)FK→task,user_id/user_uuid 不挂用户外键

StudyUserTask 与用户系统不使用外键,仅以 user_id + user_uuid 关联外部用户服务,便于跨服务解耦。task_snapshot 字段以 JSON 存储学生测试原始数据。


三、宿主项目注册

本模块作为独立可安装包,挂载到宿主项目 supreme-django-5.0。需在宿主完成以下三处配置(已完成):

1. main/settings.py —— 把模块根目录加入 sys.path

sys.path.append("D:/MyGitPkuac/xj-study")

2. config.ini[main] app_packages —— 注册 Django App

app_packages = [
             ...
             xj_lexicon,
             xj_study,
             xj_comment,
              ]

3. config.ini[main] main_url_patterns —— 注册路由前缀

main_url_patterns = [
              ...
              api/lexicon[/_] => xj_lexicon.urls,
              api/study[/_] => xj_study.urls,
              api/comment[/_] => xj_comment.urls,
               ]

注册后,所有接口统一以 /api/study/ 为前缀([/_] 同时兼容 /api/study_xxx 写法)。


四、统一响应协议

所有接口返回 util_response() 封装的 JSON:

{
  "err": 0,
  "data": { ... },
  "msg": "ok"
}
字段 含义
err 错误码,0 表示成功;非 0 时 data 通常为空
data 数据体(列表接口为分页对象,详情接口为单条记录)
msg 错误信息;成功为 ok,失败为具体错误描述

列表接口的 data 结构:

{
  "page": 1,
  "size": 20,
  "total": 35,
  "list": [ ... ],
  "query": "SELECT ..."   // 实际执行的 SQL,便于调试
}

五、API 路由表

方法 路径 说明
GET /api/study/subject_list 学科列表
GET /api/study/subject_item 学科详情(含阶段列表)
GET /api/study/stage_list 学习阶段列表
GET /api/study/stage_item 学习阶段详情(含单元列表)
GET /api/study/unit_list 学习单元列表
GET /api/study/unit_item 学习单元详情(含任务列表)
GET /api/study/task_list 单元任务列表
GET /api/study/task_item 单元任务详情
POST /api/study/task_item 新增单元任务
PUT /api/study/task_item 修改单元任务
GET /api/study/user_task_list 用户任务记录列表
GET /api/study/user_task_item 用户任务记录详情
POST /api/study/user_task_start 开启一条用户任务记录
POST /api/study/user_task_submit 提交用户任务结果(回调)

@request_params_wrapper 装饰器兼容 GET query、POST form、application/jsontext/plain 多种请求格式,下列示例统一用 JSON Body 演示(GET 接口建议用 query string)。


六、API 调用示例

以下示例假设服务运行在 http://127.0.0.1:8000GET 请求参数既可走 query string,也可走 body;POST/PUT 走 JSON Body。

1. 学科列表

curl -G "http://127.0.0.1:8000/api/study/subject_list" \
  --data "page=1" --data "size=20" --data "sort=-sort" \
  --data "search=俄" --data "enable=true"

响应:

{
  "err": 0,
  "data": {
    "page": 1, "size": 20, "total": 2,
    "list": [
      { "id": 1, "name": "俄语", "enable": true, "subject_score": 0, "icon": "", "sort": 1, "create_time": "2026-08-31 10:00:00", "update_time": "2026-08-31 10:00:00" }
    ],
    "query": "SELECT ..."
  },
  "msg": "ok"
}

2. 学科详情(含关联阶段)

curl -G "http://127.0.0.1:8000/api/study/subject_item" --data "id=1"

响应:

{
  "err": 0,
  "data": {
    "id": 1, "name": "俄语", "enable": true, "subject_score": 0, "icon": "", "sort": 1,
    "create_time": "2026-08-31 10:00:00", "update_time": "2026-08-31 10:00:00",
    "stage_count": 2,
    "stage_list": [
      { "id": 1, "name": "第一册", "enable": true, "course_book": "...", "stage_score": 0, "icon": "", "sort": 1, "create_time": "...", "update_time": "..." }
    ]
  },
  "msg": "ok"
}

3. 学习阶段列表

curl -G "http://127.0.0.1:8000/api/study/stage_list" \
  --data "subject_id=1" --data "enable=true" --data "page=1" --data "size=20"

4. 学习阶段详情(含关联单元)

curl -G "http://127.0.0.1:8000/api/study/stage_item" --data "id=1"

5. 学习单元列表

curl -G "http://127.0.0.1:8000/api/study/unit_list" \
  --data "stage_id=1" --data "search=语音" --data "page=1" --data "size=20"

6. 学习单元详情(含关联任务)

curl -G "http://127.0.0.1:8000/api/study/unit_item" --data "id=10"

7. 单元任务列表

curl -G "http://127.0.0.1:8000/api/study/task_list" \
  --data "unit_id=10" --data "enable=true" --data "sort=-sort"

8. 单元任务详情

curl -G "http://127.0.0.1:8000/api/study/task_item" --data "id=100"

响应:

{
  "err": 0,
  "data": {
    "id": 100, "unit_id": 10, "name": "A1 听力测试",
    "exam_url": "https://exam.example.com/api/check", "thread_id": "th_abc123",
    "enable": true, "task_score": 100, "time_limit": 1800,
    "open_time": "2026-09-01 09:00:00", "close_time": "2026-09-01 11:00:00",
    "publish_time": "2026-08-31 18:00:00", "icon": "", "sort": 1,
    "create_time": "...", "update_time": "..."
  },
  "msg": "ok"
}

9. 新增单元任务(POST)

curl -X POST "http://127.0.0.1:8000/api/study/task_item" \
  -H "Content-Type: application/json" \
  -d '{
    "unit_id": 10,
    "name": "A1 听力测试",
    "exam_url": "https://exam.example.com/api/check",
    "thread_id": "th_abc123",
    "enable": true,
    "task_score": 100,
    "time_limit": 1800,
    "sort": 1
  }'

响应:

{ "err": 0, "data": { "id": 101 }, "msg": "ok" }

10. 修改单元任务(PUT)

curl -X PUT "http://127.0.0.1:8000/api/study/task_item" \
  -H "Content-Type: application/json" \
  -d '{ "id": 101, "time_limit": 2400, "task_score": 120 }'

响应:

{ "err": 0, "data": { "rows": 1 }, "msg": "ok" }

11. 用户任务记录列表

curl -G "http://127.0.0.1:8000/api/study/user_task_list" \
  --data "user_id=10086" --data "task_id=100" --data "is_pass=false"

12. 用户任务记录详情

curl -G "http://127.0.0.1:8000/api/study/user_task_item" --data "id=500"

13. 开启用户任务记录(POST)

学生进入作答时调用;若存在未完成记录将直接复用,不重复创建。

curl -X POST "http://127.0.0.1:8000/api/study/user_task_start" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": 10086,
    "user_uuid": "u-10086-xxxx",
    "task_id": 100
  }'

响应:

{ "err": 0, "data": { "id": 500 }, "msg": "ok" }

14. 提交用户任务结果(POST,外部考核回调)

外部考核系统阅卷完成后回调本接口,写入得分、是否通过及 task_snapshot 快照,并自动记录 finish_time

curl -X POST "http://127.0.0.1:8000/api/study/user_task_submit" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 500,
    "result_score": 85,
    "user_task_score": 15,
    "is_pass": true,
    "task_snapshot": {
      "questions": [
        { "qid": "Q1", "answer": "А", "correct": true },
        { "qid": "Q2", "answer": "Б", "correct": false }
      ],
      "duration": 1620
    }
  }'

响应:

{ "err": 0, "data": { "rows": 1 }, "msg": "ok" }

七、典型业务流程

  1. 管理员在后台配置 StudySubject → StudyStage → StudyUnit → StudyTask,并为每个任务填写 exam_url(外部考核回调地址)与 thread_id
  2. 学生打开单元,前端调 GET /api/study/unit_item 拿到 task_list
  3. 学生点击某任务,前端调 POST /api/study/user_task_start 创建/复用一条 StudyUserTask 记录,得到 record_id,并据 exam_url 跳转外部考核系统。
  4. 外部考核系统阅卷完成,按约定回调 POST /api/study/user_task_submit(带 record_idresult_scoreis_passtask_snapshot)。
  5. 前端轮询或拉取 GET /api/study/user_task_item 展示结果与快照。

八、数据库迁移

在宿主项目 supreme-django-5.0 根目录执行:

python manage.py makemigrations xj_study
python manage.py migrate

完成后可在 /administrator/ 后台看到「Ⅳ 学习中心」应用及其 5 个模型的管理界面。

Release files for xj-study 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for xj-study 0.1.0
File Size Uploaded
xj_study-0.1.0.tar.gz 37.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for xj-study 0.1.0
File Interpreter ABI Platform
xj_study-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 92.7 kB

Release files / xj_study-0.1.0.tar.gz

Download URL xj_study-0.1.0.tar.gz
Size 37.8 kB
Tags Source
SHA-256 checksum
How to use checksums
622305a4efa46d30396d2066ee098dc525079bacb7a3713687165e672f55e50b
BLAKE2b-256 checksum
How to use checksums
89ec545481852a41caeb2f188b9edee9df62b83ec2a165d686a18cd1128ca42c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.11

Release files / xj_study-0.1.0-py3-none-any.whl

Download URL xj_study-0.1.0-py3-none-any.whl
Size 54.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ae6d499e74d66f4ea651abcffa4234618e58461e9e24b445b0f4b6d84d5eafc7
BLAKE2b-256 checksum
How to use checksums
167397360a1b5cecab4eb5bfa13b5952a485aecc65ede33e8bfe175b2d41e41b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.11

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page