@sokeai/cli 1.0.39 → 1.0.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +1 -24
  2. package/package.json +2 -2
  3. package/scripts/build-binaries.sh +1 -30
  4. package/scripts/e2e-test.sh +63 -3
  5. package/scripts/install.js +52 -110
  6. package/scripts/local-test.js +10 -85
  7. package/scripts/local-test.sh +52 -7
  8. package/scripts/push.sh +12 -4
  9. package/scripts/release.sh +45 -8
  10. package/scripts/test-auto-detect.js +71 -48
  11. package/skills/README.md +0 -1
  12. package/skills/oss-upload/skill.md +50 -0
  13. package/skills/oss-upload/upload.py +355 -0
  14. package/skills/soke-assign/README.md +310 -0
  15. package/skills/soke-assign/SKILL.md +383 -0
  16. package/skills/soke-course/README.md +168 -92
  17. package/skills/soke-course/SKILL.md +372 -460
  18. package/skills/soke-exam/SKILL.md +565 -0
  19. package/skills/soke-exam/references/exam-get-exam-user.md +212 -0
  20. package/skills/soke-learning-map/SKILL.md +544 -0
  21. package/skills/soke-learning-profile/SKILL.md +0 -1
  22. package/skills/soke-lesson/README.md +53 -0
  23. package/skills/soke-lesson/SKILL.md +510 -0
  24. package/skills/soke-material/README.md +49 -0
  25. package/skills/soke-material/SKILL.md +390 -0
  26. package/scripts/ci/check-legacy-constants.sh +0 -27
  27. package/scripts/ci/check-yaml-env-whitelist.sh +0 -33
  28. package/scripts/mcp-stdout-scan.sh +0 -46
  29. package/scripts/regress-auth.sh +0 -56
  30. package/scripts/regress-baseline.md +0 -84
  31. package/scripts/test-local-reconcile.js +0 -55
  32. package/skills/soke-business-training-report/SKILL.md +0 -58
  33. package/skills/soke-course/SUMMARY.md +0 -236
  34. package/skills/soke-course/templates/batch-create-from-excel.md +0 -75
@@ -0,0 +1,565 @@
1
+ ---
2
+ name: soke-exam
3
+ summary: 授客考试管理(考试/题库/试题/试卷的创建、查询与管理),通过 soke-cli 操作
4
+ version: 1.1.0
5
+ description: "授客考试管理:创建和查询考试、题库、试题、试卷,管理考试用户和成绩。当用户需要创建考试、创建试题、管理题库、查询考试成绩、查看考试列表时使用。"
6
+ metadata:
7
+ requires:
8
+ bins: ["soke-cli"]
9
+ cliHelp: "soke-cli exam --help"
10
+ ---
11
+
12
+ # 考试管理 (exam)
13
+
14
+ **CRITICAL — 开始前 MUST 先用 Read 工具读取 [`../soke-shared/SKILL.md`](../soke-shared/SKILL.md),其中包含认证、配置、权限处理**
15
+
16
+ ## 核心概念
17
+
18
+ - **Exam(考试)**: 考试实体,包含标题、时间范围、状态等信息,通过 `uuid` 标识
19
+ - **Pool(题库)**: 存放试题的容器,通过 `uuid` 标识,包含一个或多个分类
20
+ - **Paper(试卷)**: 从题库按题型抽取试题生成的试卷,通过 `uuid` 标识
21
+ - **Question(试题)**: 单个题目,支持 7 种题型,通过 `uuid` 标识
22
+ - **ExamUser(考试用户)**: 用户的考试记录,包含成绩、状态、答题时间等
23
+ - **Category(分类)**: 题库分类 / 考试分类,支持层级结构
24
+
25
+ ## 资源关系
26
+
27
+ ```
28
+ Pool (题库)
29
+ ├── Category (题库分类)
30
+ └── Question (试题) × N
31
+ └── Paper (试卷) — 按题型从题库中抽取
32
+ └── Exam (考试) — 关联试卷,指派用户
33
+ └── ExamUser (考试用户记录)
34
+ ```
35
+
36
+ ## Shortcuts 总览
37
+
38
+ ### 查询类(读)
39
+
40
+ | Shortcut | 说明 |
41
+ |----------|------|
42
+ | [`+list-exams`](#list-exams) | 列出考试列表 |
43
+ | [`+get-exam`](#get-exam) | 获取单个考试详情 |
44
+ | [`+list-exam-users`](#list-exam-users) | 列出考试用户成绩列表 |
45
+ | [`+get-exam-user`](#get-exam-user) | 获取单个考试用户的详细成绩 |
46
+ | [`+list-categories`](#list-categories) | 列出考试分类(旧称) |
47
+ | [`+list-pool-categories`](#list-pool-categories) | 列出题库分类 |
48
+ | [`+list-pools`](#list-pools) | 列出题库列表 |
49
+ | [`+get-pool`](#get-pool) | 获取题库详情 |
50
+ | [`+list-questions`](#list-questions) | 获取试题列表 |
51
+ | [`+list-papers`](#list-papers) | 获取试卷列表 |
52
+ | [`+get-paper`](#get-paper) | 获取试卷详情 |
53
+ | [`+get-paper-questions`](#get-paper-questions) | 获取试卷试题列表 |
54
+ | [`+get-statistic-data`](#get-statistic-data) | 获取考试统计数据 |
55
+ | [`+list-user-list`](#list-user-list) | 获取考生用户列表 |
56
+
57
+ ### 创建/修改类(写)
58
+
59
+ | Shortcut | 说明 |
60
+ |----------|------|
61
+ | [`+create-pool-category`](#create-pool-category) | 创建题库分类 |
62
+ | [`+create-pool`](#create-pool) | 创建题库 |
63
+ | [`+update-pool`](#update-pool) | 更新题库 |
64
+ | [`+create-question`](#create-question) | 创建试题 |
65
+ | [`+create-paper`](#create-paper) | 创建试卷 |
66
+ | [`+update-paper`](#update-paper) | 更新试卷(支持发布) |
67
+ | [`+delete-paper`](#delete-paper) | 删除试卷 |
68
+ | [`+set-paper-score`](#set-paper-score) | 设置试卷分值 |
69
+ | [`+create-exam`](#create-exam) | 创建考试 |
70
+ | [`+update-exam`](#update-exam) | 更新考试 |
71
+ | [`+import-paper`](#import-paper) | 关联试卷到考试 |
72
+ | [`+assign-exam`](#assign-exam) | 指派考试给用户 |
73
+ | [`+get-assign`](#get-assign) | 查询考试指派情况 |
74
+
75
+ ---
76
+
77
+ ## 试题类型与格式
78
+
79
+ ### 7 种题型一览
80
+
81
+ | type 值 | 中文名 | choices | answer | 特殊说明 |
82
+ |---------|--------|---------|--------|---------|
83
+ | `single_choice` | 单选题 | 必传 | `["0"]` 索引数组 | 只有一个正确答案 |
84
+ | `determine` | 判断题 | 不需要 | `["0"]` 对 / `["1"]` 错 | 默认选项为对/错 |
85
+ | `choice` | 多选题 | 必传 | `["0","1"]` 索引数组 | 多个正确答案 |
86
+ | `uncertain_choice` | 不定项选择 | 必传 | `["0","2"]` 索引数组 | 答案数量不固定 |
87
+ | `fill` | 填空题 | 不需要 | **不传** | 见下方专节 |
88
+ | `essay` | 简答题 | 不需要 | 字符串 | 参考答案文本 |
89
+ | `material` | 材料题 | 不需要 | 字符串 | 类似简答 |
90
+
91
+ ### 填空题(fill)专节
92
+
93
+ **填空题答案嵌入在 title 中**,使用 `[[答案N]]` 标记(N 从 1 开始),**不传 `--answer` 参数**。
94
+
95
+ ```bash
96
+ # 正确:答案标记嵌入 title
97
+ soke-cli exam +create-question \
98
+ --type fill \
99
+ --title "鲁班是[[答案1]]国人,本名[[答案2]]。" \
100
+ --answer-type 1 \
101
+ --pool-id "<pool-uuid>" \
102
+ --score 5 --difficulty simple
103
+
104
+ # 错误:用 ______ 或其他标记 — 后端无法识别,报"答案为空"
105
+ soke-cli exam +create-question \
106
+ --type fill \
107
+ --title "鲁班是______国人" \ # ❌ 不是 [[答案N]]
108
+ ...
109
+ ```
110
+
111
+ **`--answer-type` 判卷方式**(`fill` 专属,不传时默认 `"1"`):
112
+
113
+ | 值 | 含义 |
114
+ |----|------|
115
+ | `1` | 完全一致(默认) |
116
+ | `2` | 仅顺序不一致 |
117
+ | `3` | 仅供参考 |
118
+
119
+ **常见错误**:
120
+ - 用 `______` / `___` / `(答案1)` 代替 `[[答案1]]` → 后端解析失败
121
+ - 传了 `--answer` 参数 → 对 fill 类型无效,会被忽略
122
+ - 不传 `--answer-type` → CLI 自动默认 `"1"`,一般不会出问题
123
+
124
+ ---
125
+
126
+ ## 命令详解
127
+
128
+ ### +create-exam
129
+
130
+ 创建考试。
131
+
132
+ ```bash
133
+ soke-cli exam +create-exam \
134
+ --title <考试标题> \
135
+ [--is-papers 1] \
136
+ [--source self] \
137
+ [--path '["<category_uuid>"]']
138
+ ```
139
+
140
+ | 参数 | 必需 | 说明 |
141
+ |------|------|------|
142
+ | `--title` | 是 | 考试标题,最大 50 字符 |
143
+ | `--is-papers` | 否 | 是否关联试卷:0=否 1=是(默认 0) |
144
+ | `--is-in` | 否 | 是否内部考试:0=否 1=是(默认 0) |
145
+ | `--is-offline` | 否 | 是否线下考试:0=否 1=是(默认 0) |
146
+ | `--set-time` | 否 | 是否设置考试时间(默认 0) |
147
+ | `--source` | 否 | 来源:self/mall/public(默认 self) |
148
+ | `--path` | 否 | 分类 ID 数组,JSON 格式 |
149
+
150
+ ---
151
+
152
+ ### +create-question
153
+
154
+ 创建试题。7 种题型有不同的参数要求,详见 [试题类型与格式](#试题类型与格式)。
155
+
156
+ ```bash
157
+ soke-cli exam +create-question \
158
+ --title <内容> \
159
+ --type <题型> \
160
+ --score <分值> \
161
+ --difficulty <难度> \
162
+ --pool-id <题库UUID> \
163
+ [--choices <JSON选项>] \
164
+ [--answer <JSON答案>] \
165
+ [--answer-type <判卷方式>] \
166
+ [--analysis <解析>]
167
+ ```
168
+
169
+ | 参数 | 必需 | 说明 |
170
+ |------|------|------|
171
+ | `--title` | 是 | 试题内容,fill 类型必须含 `[[答案N]]` |
172
+ | `--type` | 是 | 题型:single_choice/choice/uncertain_choice/determine/fill/essay/material |
173
+ | `--score` | 是 | 分值,必须大于 0 |
174
+ | `--difficulty` | 是 | 难度:simple/medium/hard |
175
+ | `--pool-id` | 是 | 所属题库 UUID |
176
+ | `--choices` | 条件 | 选择题必传,JSON 数组:`'[{"key":"A1","value":"A"}]'` |
177
+ | `--answer` | 条件 | 选择/判断题必传,fill 不传,简答/材料题为字符串 |
178
+ | `--answer-type` | 否 | fill 专属,默认 `1` |
179
+ | `--analysis` | 否 | 题目解析 |
180
+ | `--dept-id` | 否 | 部门 ID |
181
+ | `--dept-name` | 否 | 部门名称 |
182
+
183
+ ---
184
+
185
+ ### +create-pool
186
+
187
+ 创建题库。
188
+
189
+ ```bash
190
+ soke-cli exam +create-pool \
191
+ --title <题库名称> \
192
+ --path '["<category_uuid>"]' \
193
+ [--description <描述>] \
194
+ [--status 1]
195
+ ```
196
+
197
+ ---
198
+
199
+ ### +create-pool-category
200
+
201
+ 创建题库分类。
202
+
203
+ ```bash
204
+ soke-cli exam +create-pool-category --title <分类名称>
205
+ ```
206
+
207
+ ---
208
+
209
+ ### +create-paper
210
+
211
+ 从题库按题型抽取试题生成试卷。
212
+
213
+ ```bash
214
+ soke-cli exam +create-paper \
215
+ --title <试卷名称> \
216
+ --pool-id '["<pool_uuid>"]' \
217
+ --pattern questionType \
218
+ --type-metas '<JSON>'
219
+ ```
220
+
221
+ `--type-metas` 格式:
222
+ ```json
223
+ {
224
+ "single_choice": {"count": 1, "score": 5},
225
+ "determine": {"count": 1, "score": 2},
226
+ "choice": {"count": 1, "score": 5},
227
+ "essay": {"count": 1, "score": 10},
228
+ "uncertain_choice": {"count": 1, "score": 5},
229
+ "fill": {"count": 1, "score": 5}
230
+ }
231
+ ```
232
+
233
+ ---
234
+
235
+ ### +update-paper
236
+
237
+ 更新试卷,支持发布操作。**发布时必须同时传 `--title`,否则后端会将标题置空。**
238
+
239
+ ```bash
240
+ # 发布试卷(title 必传)
241
+ soke-cli exam +update-paper \
242
+ --paper-id <paper_uuid> \
243
+ --title <试卷名称> \
244
+ --action publish
245
+
246
+ # 仅更新标题
247
+ soke-cli exam +update-paper \
248
+ --paper-id <paper_uuid> \
249
+ --title <新标题>
250
+ ```
251
+
252
+ ---
253
+
254
+ ### +update-exam
255
+
256
+ 更新考试,支持发布。**发布时 `--title` 和 `--path` 必传**,`action` 会映射为后端 `act` 字段。
257
+
258
+ ```bash
259
+ # 发布考试(title + path 必传)
260
+ soke-cli exam +update-exam \
261
+ --exam-id <exam_uuid> \
262
+ --title <考试标题> \
263
+ --action publish \
264
+ --path '["<category_uuid>"]'
265
+
266
+ # 仅更新标题
267
+ soke-cli exam +update-exam \
268
+ --exam-id <exam_uuid> \
269
+ --title <新标题>
270
+ ```
271
+
272
+ | 参数 | 必需 | 说明 |
273
+ |------|------|------|
274
+ | `--exam-id` | 是 | 考试 UUID |
275
+ | `--title` | 条件 | 发布时必传,避免标题被清空 |
276
+ | `--action` | 否 | `publish`=发布考试,留空仅更新信息 |
277
+ | `--path` | 条件 | 发布时必传,考试分类 ID 数组 JSON |
278
+
279
+ **发布前提**:
280
+ 1. 考试创建时已设置 `--path`(分类),否则发布时分类检查不通过
281
+ 2. 考试已通过 `+import-paper` 关联了试卷
282
+ 3. 试卷已通过 `+update-paper --action publish` 发布
283
+
284
+ ---
285
+
286
+ ### +assign-exam
287
+
288
+ 指派考试给指定用户。
289
+
290
+ ```bash
291
+ soke-cli exam +assign-exam \
292
+ --exam-id <exam_uuid> \
293
+ --user-ids '["<dept_user_id>", ...]'
294
+ ```
295
+
296
+ | 参数 | 必需 | 说明 |
297
+ |------|------|------|
298
+ | `--exam-id` | 是 | 考试 UUID |
299
+ | `--user-ids` | 是 | 用户 dept_user_id 数组,JSON 格式 |
300
+
301
+ **查找用户 ID**:`soke-cli contact +search-user --dept-user-name "姓名"`
302
+
303
+ ---
304
+
305
+ ### +get-assign
306
+
307
+ 查询考试已指派的用户列表。
308
+
309
+ ```bash
310
+ soke-cli exam +get-assign --exam-id <exam_uuid>
311
+ ```
312
+
313
+ ---
314
+
315
+ ### +import-paper
316
+
317
+ 将已发布的试卷关联到考试。
318
+
319
+ ```bash
320
+ soke-cli exam +import-paper \
321
+ --exam-id <exam_uuid> \
322
+ --paper-id <paper_uuid>
323
+ ```
324
+
325
+ ---
326
+
327
+ ### +get-exam
328
+
329
+ 获取考试详情。
330
+
331
+ ```bash
332
+ soke-cli exam +get-exam --exam-id <exam_uuid>
333
+ ```
334
+
335
+ 返回字段包括:`uuid`, `title`, `status`(0=未发布 1=已发布), `paper_id`, `question_count`, `total_score`, `pass_score` 等。
336
+
337
+ ---
338
+
339
+ ### +list-exams
340
+
341
+ 列出考试列表。
342
+
343
+ ```bash
344
+ soke-cli exam +list-exams \
345
+ [--page <页码>] \
346
+ [--page-size <每页条数>]
347
+ ```
348
+
349
+ | 参数 | 默认值 | 说明 |
350
+ |------|--------|------|
351
+ | `--page` | 1 | 页码 |
352
+ | `--page-size` | 10 | 每页条数 |
353
+
354
+ ---
355
+
356
+ ### +list-exam-users
357
+
358
+ 列出考试用户成绩列表。
359
+
360
+ ```bash
361
+ soke-cli exam +list-exam-users \
362
+ --exam-id <exam_uuid> \
363
+ [--page <页码>] \
364
+ [--page-size <每页条数>]
365
+ ```
366
+
367
+ ---
368
+
369
+ ### +get-exam-user
370
+
371
+ 获取单个考试用户的详细成绩。
372
+
373
+ ```bash
374
+ soke-cli exam +get-exam-user \
375
+ --exam-id <exam_uuid> \
376
+ --dept-user-id <dept_user_id>
377
+ ```
378
+
379
+ ---
380
+
381
+ ### +list-pool-categories
382
+
383
+ 列出题库分类。
384
+
385
+ ```bash
386
+ soke-cli exam +list-pool-categories [--parent-id 1]
387
+ ```
388
+
389
+ ---
390
+
391
+ ### 其他查询命令
392
+
393
+ ```bash
394
+ soke-cli exam +list-pools [--page 1] [--page-size 10]
395
+ soke-cli exam +get-pool --pool-id <uuid>
396
+ soke-cli exam +list-questions [--pool-id <uuid>] [--page 1] [--page-size 10]
397
+ soke-cli exam +list-papers [--page 1] [--page-size 10]
398
+ soke-cli exam +get-paper --paper-id <uuid>
399
+ soke-cli exam +get-paper-questions --paper-id <uuid>
400
+ soke-cli exam +get-statistic-data --exam-id <uuid>
401
+ soke-cli exam +list-user-list --exam-id <uuid>
402
+ soke-cli exam +list-categories [--page 1] [--page-size 10]
403
+ soke-cli exam +update-pool --pool-id <uuid> --title <新标题>
404
+ soke-cli exam +delete-paper --paper-id <uuid>
405
+ soke-cli exam +set-paper-score --paper-id <uuid> --score <分值>
406
+ ```
407
+
408
+ ---
409
+
410
+ ## 完整工作流
411
+
412
+ ### 工作流 1:从零创建一场考试
413
+
414
+ ```bash
415
+ # 1. 创建题库分类
416
+ soke-cli exam +create-pool-category --title "考试分类名"
417
+ # → 记下 uuid
418
+
419
+ # 2. 创建题库
420
+ soke-cli exam +create-pool \
421
+ --title "题库名" \
422
+ --path '["<category_uuid>"]'
423
+ # → 记下 uuid
424
+
425
+ # 3. 创建试题(6 种题型各一例)
426
+ # 单选题
427
+ soke-cli exam +create-question \
428
+ --pool-id "<pool_uuid>" --type single_choice \
429
+ --title "题目内容?" --score 5 --difficulty simple \
430
+ --choices '[{"key":"A1","value":"A"},{"key":"B1","value":"B"},{"key":"C1","value":"C"},{"key":"D1","value":"D"}]' \
431
+ --answer '["0"]'
432
+
433
+ # 判断题
434
+ soke-cli exam +create-question \
435
+ --pool-id "<pool_uuid>" --type determine \
436
+ --title "判断内容" --score 2 --difficulty simple \
437
+ --answer '["1"]' # 0=对 1=错
438
+
439
+ # 多选题
440
+ soke-cli exam +create-question \
441
+ --pool-id "<pool_uuid>" --type choice \
442
+ --title "题目内容?" --score 5 --difficulty medium \
443
+ --choices '[{"key":"A1","value":"A"},...]' \
444
+ --answer '["0","1","2"]'
445
+
446
+ # 简答题
447
+ soke-cli exam +create-question \
448
+ --pool-id "<pool_uuid>" --type essay \
449
+ --title "题目内容?" --score 10 --difficulty medium \
450
+ --answer "参考答案文本"
451
+
452
+ # 不定项选择题
453
+ soke-cli exam +create-question \
454
+ --pool-id "<pool_uuid>" --type uncertain_choice \
455
+ --title "题目内容?" --score 5 --difficulty hard \
456
+ --choices '[{"key":"A1","value":"A"},...]' \
457
+ --answer '["0","2"]'
458
+
459
+ # 填空题 — 答案嵌入 title 中,不传 --answer
460
+ soke-cli exam +create-question \
461
+ --pool-id "<pool_uuid>" --type fill \
462
+ --title "...[[答案1]]...[[答案2]]..." \
463
+ --score 5 --difficulty medium
464
+
465
+ # 4. 创建试卷(从题库按题型抽取)
466
+ soke-cli exam +create-paper \
467
+ --title "试卷名" \
468
+ --pool-id '["<pool_uuid>"]' \
469
+ --pattern questionType \
470
+ --type-metas '{"single_choice":{"count":1,"score":5},"determine":{"count":1,"score":2},"choice":{"count":1,"score":5},"essay":{"count":1,"score":10},"uncertain_choice":{"count":1,"score":5},"fill":{"count":1,"score":5}}'
471
+
472
+ # 5. 发布试卷(title 必传)
473
+ soke-cli exam +update-paper \
474
+ --paper-id "<paper_uuid>" \
475
+ --title "试卷名" \
476
+ --action publish
477
+
478
+ # 6. 创建考试(必须带 --path 才能发布)
479
+ soke-cli exam +create-exam \
480
+ --title "考试名" \
481
+ --is-papers 1 \
482
+ --path '["<category_uuid>"]'
483
+
484
+ # 7. 关联试卷到考试
485
+ soke-cli exam +import-paper \
486
+ --exam-id "<exam_uuid>" \
487
+ --paper-id "<paper_uuid>"
488
+
489
+ # 8. 发布考试(title + path 必传)
490
+ soke-cli exam +update-exam \
491
+ --exam-id "<exam_uuid>" \
492
+ --title "考试名" \
493
+ --action publish \
494
+ --path '["<category_uuid>"]'
495
+
496
+ # 9. 指派考试给用户
497
+ soke-cli exam +assign-exam \
498
+ --exam-id "<exam_uuid>" \
499
+ --user-ids '["<dept_user_id>"]'
500
+ ```
501
+
502
+ ### 工作流 2:查询用户考试成绩
503
+
504
+ ```bash
505
+ # 1. 已知用户名,先查 dept_user_id
506
+ soke-cli contact +search-user --dept-user-name "张三"
507
+
508
+ # 2. 查询成绩
509
+ soke-cli exam +get-exam-user \
510
+ --exam-id <exam_uuid> \
511
+ --dept-user-id <dept_user_id>
512
+ ```
513
+
514
+ ### 工作流 3:统计考试完成情况
515
+
516
+ ```bash
517
+ soke-cli exam +get-statistic-data --exam-id <exam_uuid>
518
+ soke-cli exam +list-exam-users --exam-id <exam_uuid>
519
+ ```
520
+
521
+ ---
522
+
523
+ ## 常见问题与排错
524
+
525
+ ### 填空题报"答案为空"
526
+
527
+ title 中没有使用 `[[答案N]]` 标记。检查:
528
+ - `______` → 改成 `[[答案1]]`
529
+ - `___` → 改成 `[[答案1]]`
530
+ - `(答案1)` → 改成 `[[答案1]]`
531
+
532
+ ### 填空题报 500 错误
533
+
534
+ `--answer-type` 未传且 title 含 `[[答案N]]` 时可能触发(CLI 已默认 `"1"`,一般不再出现)。
535
+
536
+ ### 创建成功但没有输出
537
+
538
+ API 返回了业务错误(如 `status: "error"`)但没显示。用 `--format json` 查看原始响应。CLI v1.0.52+ 已修复静默失败问题,现在会自动显示 `Error: [code] message`。
539
+
540
+ ### 列表接口报 500
541
+
542
+ 部分 `/skills/examUser/*` 端点可能因数据问题崩溃,先用 `+get-exam-user` 逐个查询。
543
+
544
+ ---
545
+
546
+ ## 权限表
547
+
548
+ | 操作 | 所需权限 |
549
+ |------|---------|
550
+ | 查询类(list/get) | `exam:exam:readonly` / `exam:examUser:readonly` / `exam:category:readonly` |
551
+ | 创建类(create) | `exam:exam:write` / `exam:examQuestion:write` / `exam:examPaper:write` / `exam:examPool:write` |
552
+ | 更新/删除 | 对应模块的 `:write` 权限 |
553
+
554
+ ## 注意事项
555
+
556
+ 1. **填空答案格式**: 必须用 `[[答案N]]` 嵌入 title,不能用 `______` 或自定义标记
557
+ 2. **填空不传 --answer**: fill 类型的 `--answer` 参数会被忽略,答案在 title 标记中
558
+ 3. **--answer-type 默认值**: fill 类型不传时 CLI 自动设为 `"1"`(完全一致)
559
+ 4. **choices key 格式**: `{"key":"A1","value":"A"}` — key 是选项标识,value 是选项文本
560
+ 5. **answer 索引**: 选择题答案用 0-based 索引,`"0"` 表示第一个选项
561
+ 6. **判断题 answer**: `["0"]` 对,`["1"]` 错
562
+ 7. **试卷必须先发布且带标题**: `+update-paper --title "..." --action publish`
563
+ 8. **考试创建时需带分类**: `+create-exam --path '["<category_uuid>"]'`,否则无法发布
564
+ 9. **发布考试**: `+update-exam --title "..." --action publish --path '["<category_uuid>"]'`,`action` 映射为后端 `act` 字段
565
+ 8. **考试状态**: status=0 未发布,status=1 已发布