From e9d93130e6bff542e8d042c53c2fbfe6e9b7ac32 Mon Sep 17 00:00:00 2001 From: Functionhx <172989722+Functionhx@users.noreply.github.com> Date: Sat, 3 Oct 2026 19:00:40 -0700 Subject: [PATCH 1/2] Add shared CET-6 source catalog and transactional question-bank imports --- Shared/QuestionBank/README.md | 39 + Shared/QuestionBank/cet6-2022-2026-index.json | 731 ++++++++++++++++++ WriteBench.xcodeproj/project.pbxproj | 21 + .../Writing/QuestionLibraryView.swift | 57 +- WriteBench/Models/CETQuestionBank.swift | 66 ++ WriteBench/Models/QuestionBank.swift | 3 +- WriteBenchTests/CETQuestionBankTests.swift | 52 ++ platforms/windows/WriteBench/App.xaml.cs | 2 +- platforms/windows/WriteBench/SelfTest.cs | 22 +- .../WriteBench/Services/CETQuestionBank.cs | 47 ++ .../windows/WriteBench/Views/MainWindow.cs | 23 + .../windows/WriteBench/WriteBench.csproj | 2 +- project.yml | 2 + 13 files changed, 1051 insertions(+), 16 deletions(-) create mode 100644 Shared/QuestionBank/README.md create mode 100644 Shared/QuestionBank/cet6-2022-2026-index.json create mode 100644 WriteBench/Models/CETQuestionBank.swift create mode 100644 WriteBenchTests/CETQuestionBankTests.swift create mode 100644 platforms/windows/WriteBench/Services/CETQuestionBank.cs diff --git a/Shared/QuestionBank/README.md b/Shared/QuestionBank/README.md new file mode 100644 index 0000000..b2b41d3 --- /dev/null +++ b/Shared/QuestionBank/README.md @@ -0,0 +1,39 @@ +# 六级 2022–2026 题库数据 + +Windows 和 macOS 使用同一个 `cet6-2022-2026-index.json` 文件。 + +**目前是第三方来源索引,包含写作 33 条、翻译 33 条,不包含真题正文,不能直接作为练习题。** 目录来自以下页面,并保留来源的套次编号,尚未逐卷核对正文、日期或题目真实性: + +- https://english-exam.lazynote.cn/cet6/sections/writing/ +- https://english-exam.lazynote.cn/cet6/sections/chinese-english-translation/ + +范围:2022、2023、2024、2025、2026;2026 仅列 6 月。包含目录中的 2022 年 9 月与 2023 年 3 月条目。不能将来源编号视为所有机构一致使用的官方套次编号。 + +## 完整正文批量导入 + +从用户提供的 PDF、图片或题目文件中提取并校对题目后,生成相同 JSON 格式: + +```json +{ + "schemaVersion": 1, + "questions": [ + { + "id": "cet6-2024-06-1-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 6, + "set": 1, + "title": "2024 年 6 月 · 来源第 1 套 · 写作", + "prompt": "这里填写从你提供的资料提取并校对后的完整题干", + "sourceUrl": "https://example.com/source", + "verification": "userImported" + } + ] +} +``` + +翻译的 `task` 为 `cet6Translation`。来源链接应指向所用资料的出处,不应伪造。导入文件必须全部有正文;仅含索引、重复 ID、未知题型、无效来源、未来考试日期或不支持的数据版本会整体拒绝,原题库不变。相同 ID 在后续导入中更新,其余已有条目保留。 + +macOS:题库 → 近五年六级 → 批量导入题库 JSON。Windows:六级 → 写作/翻译 → 近五年六级题库/批量导入。 + +用户题库只保存在本机:macOS `~/Library/Application Support/WriteBench/QuestionBank/cet6-custom.json`;Windows `%LOCALAPPDATA%/WriteBench/QuestionBank/cet6-custom.json`。两平台使用同一种格式,但不会自动跨设备同步。macOS 原有“我的题库”备份不会自动包含这个独立 JSON 文件;迁移时应另行复制它。 diff --git a/Shared/QuestionBank/cet6-2022-2026-index.json b/Shared/QuestionBank/cet6-2022-2026-index.json new file mode 100644 index 0000000..2ba51d3 --- /dev/null +++ b/Shared/QuestionBank/cet6-2022-2026-index.json @@ -0,0 +1,731 @@ +{ + "schemaVersion": 1, + "questions": [ + { + "id": "cet6-2026-06-1-cet6Writing", + "task": "cet6Writing", + "year": 2026, + "month": 6, + "set": 1, + "title": "2026 年 6 月 · 来源第 1 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-1/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2026-06-2-cet6Writing", + "task": "cet6Writing", + "year": 2026, + "month": 6, + "set": 2, + "title": "2026 年 6 月 · 来源第 2 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-2/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2026-06-3-cet6Writing", + "task": "cet6Writing", + "year": 2026, + "month": 6, + "set": 3, + "title": "2026 年 6 月 · 来源第 3 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-3/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-12-1-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 12, + "set": 1, + "title": "2025 年 12 月 · 来源第 1 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-1/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-12-2-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 12, + "set": 2, + "title": "2025 年 12 月 · 来源第 2 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-2/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-12-3-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 12, + "set": 3, + "title": "2025 年 12 月 · 来源第 3 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-3/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-06-1-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 6, + "set": 1, + "title": "2025 年 6 月 · 来源第 1 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-1/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-06-2-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 6, + "set": 2, + "title": "2025 年 6 月 · 来源第 2 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-2/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-06-3-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 6, + "set": 3, + "title": "2025 年 6 月 · 来源第 3 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-3/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-12-1-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 12, + "set": 1, + "title": "2024 年 12 月 · 来源第 1 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-1/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-12-2-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 12, + "set": 2, + "title": "2024 年 12 月 · 来源第 2 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-2/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-12-3-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 12, + "set": 3, + "title": "2024 年 12 月 · 来源第 3 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-3/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-06-1-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 6, + "set": 1, + "title": "2024 年 6 月 · 来源第 1 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-1/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-06-2-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 6, + "set": 2, + "title": "2024 年 6 月 · 来源第 2 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-2/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-06-3-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 6, + "set": 3, + "title": "2024 年 6 月 · 来源第 3 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-3/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-12-1-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 12, + "set": 1, + "title": "2023 年 12 月 · 来源第 1 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-1/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-12-2-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 12, + "set": 2, + "title": "2023 年 12 月 · 来源第 2 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-2/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-12-3-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 12, + "set": 3, + "title": "2023 年 12 月 · 来源第 3 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-3/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-06-1-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 6, + "set": 1, + "title": "2023 年 6 月 · 来源第 1 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-1/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-06-2-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 6, + "set": 2, + "title": "2023 年 6 月 · 来源第 2 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-2/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-06-3-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 6, + "set": 3, + "title": "2023 年 6 月 · 来源第 3 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-3/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-03-1-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 3, + "set": 1, + "title": "2023 年 3 月 · 来源第 1 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-1/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-03-2-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 3, + "set": 2, + "title": "2023 年 3 月 · 来源第 2 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-2/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-03-3-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 3, + "set": 3, + "title": "2023 年 3 月 · 来源第 3 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-3/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-12-1-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 12, + "set": 1, + "title": "2022 年 12 月 · 来源第 1 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-1/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-12-2-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 12, + "set": 2, + "title": "2022 年 12 月 · 来源第 2 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-2/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-12-3-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 12, + "set": 3, + "title": "2022 年 12 月 · 来源第 3 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-3/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-09-1-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 9, + "set": 1, + "title": "2022 年 9 月 · 来源第 1 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-1/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-09-2-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 9, + "set": 2, + "title": "2022 年 9 月 · 来源第 2 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-2/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-09-3-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 9, + "set": 3, + "title": "2022 年 9 月 · 来源第 3 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-3/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-06-1-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 6, + "set": 1, + "title": "2022 年 6 月 · 来源第 1 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-1/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-06-2-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 6, + "set": 2, + "title": "2022 年 6 月 · 来源第 2 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-2/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-06-3-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 6, + "set": 3, + "title": "2022 年 6 月 · 来源第 3 套 · 写作", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-3/part1/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2026-06-1-cet6Translation", + "task": "cet6Translation", + "year": 2026, + "month": 6, + "set": 1, + "title": "2026 年 6 月 · 来源第 1 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-1/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2026-06-2-cet6Translation", + "task": "cet6Translation", + "year": 2026, + "month": 6, + "set": 2, + "title": "2026 年 6 月 · 来源第 2 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-2/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2026-06-3-cet6Translation", + "task": "cet6Translation", + "year": 2026, + "month": 6, + "set": 3, + "title": "2026 年 6 月 · 来源第 3 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-3/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-12-1-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 12, + "set": 1, + "title": "2025 年 12 月 · 来源第 1 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-1/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-12-2-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 12, + "set": 2, + "title": "2025 年 12 月 · 来源第 2 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-2/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-12-3-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 12, + "set": 3, + "title": "2025 年 12 月 · 来源第 3 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-3/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-06-1-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 6, + "set": 1, + "title": "2025 年 6 月 · 来源第 1 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-1/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-06-2-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 6, + "set": 2, + "title": "2025 年 6 月 · 来源第 2 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-2/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2025-06-3-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 6, + "set": 3, + "title": "2025 年 6 月 · 来源第 3 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-3/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-12-1-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 12, + "set": 1, + "title": "2024 年 12 月 · 来源第 1 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-1/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-12-2-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 12, + "set": 2, + "title": "2024 年 12 月 · 来源第 2 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-2/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-12-3-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 12, + "set": 3, + "title": "2024 年 12 月 · 来源第 3 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-3/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-06-1-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 6, + "set": 1, + "title": "2024 年 6 月 · 来源第 1 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-1/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-06-2-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 6, + "set": 2, + "title": "2024 年 6 月 · 来源第 2 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-2/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2024-06-3-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 6, + "set": 3, + "title": "2024 年 6 月 · 来源第 3 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-3/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-12-1-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 12, + "set": 1, + "title": "2023 年 12 月 · 来源第 1 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-1/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-12-2-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 12, + "set": 2, + "title": "2023 年 12 月 · 来源第 2 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-2/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-12-3-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 12, + "set": 3, + "title": "2023 年 12 月 · 来源第 3 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-3/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-06-1-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 6, + "set": 1, + "title": "2023 年 6 月 · 来源第 1 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-1/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-06-2-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 6, + "set": 2, + "title": "2023 年 6 月 · 来源第 2 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-2/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-06-3-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 6, + "set": 3, + "title": "2023 年 6 月 · 来源第 3 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-3/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-03-1-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 3, + "set": 1, + "title": "2023 年 3 月 · 来源第 1 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-1/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-03-2-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 3, + "set": 2, + "title": "2023 年 3 月 · 来源第 2 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-2/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2023-03-3-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 3, + "set": 3, + "title": "2023 年 3 月 · 来源第 3 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-3/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-12-1-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 12, + "set": 1, + "title": "2022 年 12 月 · 来源第 1 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-1/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-12-2-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 12, + "set": 2, + "title": "2022 年 12 月 · 来源第 2 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-2/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-12-3-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 12, + "set": 3, + "title": "2022 年 12 月 · 来源第 3 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-3/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-09-1-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 9, + "set": 1, + "title": "2022 年 9 月 · 来源第 1 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-1/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-09-2-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 9, + "set": 2, + "title": "2022 年 9 月 · 来源第 2 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-2/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-09-3-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 9, + "set": 3, + "title": "2022 年 9 月 · 来源第 3 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-3/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-06-1-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 6, + "set": 1, + "title": "2022 年 6 月 · 来源第 1 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-1/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-06-2-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 6, + "set": 2, + "title": "2022 年 6 月 · 来源第 2 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-2/part-iv/", + "verification": "sourceIndex" + }, + { + "id": "cet6-2022-06-3-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 6, + "set": 3, + "title": "2022 年 6 月 · 来源第 3 套 · 翻译", + "prompt": "", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-3/part-iv/", + "verification": "sourceIndex" + } + ] +} diff --git a/WriteBench.xcodeproj/project.pbxproj b/WriteBench.xcodeproj/project.pbxproj index 5fba545..9e20957 100644 --- a/WriteBench.xcodeproj/project.pbxproj +++ b/WriteBench.xcodeproj/project.pbxproj @@ -20,6 +20,7 @@ 2B8AA947E573B4AD052F6F95 /* OCRService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F892E2F452C5999A8C08043 /* OCRService.swift */; }; 3197344EF97F73265170A114 /* WorkspaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9238EAE831BF69E5F210D72A /* WorkspaceView.swift */; }; 32367F4CF29D3A467EFA453D /* MockGradingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296A6193086826B2B071503F /* MockGradingService.swift */; }; + 337FAAE005C9D52F7539091A /* CETQuestionBank.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1689A9A92BD0E930F5FB82F9 /* CETQuestionBank.swift */; }; 361B2B881C01F86CC3A784DC /* cet6_translation.md in Resources */ = {isa = PBXBuildFile; fileRef = 6CED406B3EAB7FA3947795C5 /* cet6_translation.md */; }; 380960FEBBC3C2CDC16C3147 /* BackgroundGradingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A07798AF0255AB8EAFF76A /* BackgroundGradingTests.swift */; }; 3D7E00CED5955E5E709BAF28 /* RevisionViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E5B6AA16B1E69446387608 /* RevisionViews.swift */; }; @@ -28,6 +29,7 @@ 473B2ECB957707EDB2BF41AA /* BackgroundGradingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8E73D997ED19A98227B24C /* BackgroundGradingView.swift */; }; 4B7B1CDF7FADBE73B96E26DA /* kaoyan_english1_translation.md in Resources */ = {isa = PBXBuildFile; fileRef = AD3CEB6EC11C595CA1EA79D6 /* kaoyan_english1_translation.md */; }; 51899521D61CB025A5559EC5 /* LocalProcessRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 100F5B726342F502CA8C4207 /* LocalProcessRunner.swift */; }; + 52D947565422EE245913DE21 /* cet6-2022-2026-index.json in Resources */ = {isa = PBXBuildFile; fileRef = 63ABA3E9807196933476EF75 /* cet6-2022-2026-index.json */; }; 5317F309ED9004BD4665C0DC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 37444757CFEC8F67705A2D6C /* Assets.xcassets */; }; 54D5279B986C5DBEA37BA5C7 /* OCRConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54C82E0AE1ACA592616CDDB /* OCRConfirmationView.swift */; }; 55C7907B2F577F01BC57A08B /* ReviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F9DB3748FBE72E213C6EB37 /* ReviewView.swift */; }; @@ -45,6 +47,7 @@ 86CD1B5AEC144D4283491FC5 /* PlainTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6C23EF9D33F68C7816C642 /* PlainTextEditor.swift */; }; 892F119876541FA3E8699E90 /* BackgroundGradingJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31DECD6B9F0B3A54C27F4535 /* BackgroundGradingJob.swift */; }; 8938EFAD301830E8B39DF4FD /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEF0EC53CAA982107C3AA320 /* SettingsView.swift */; }; + 8A386C67F3728D7CC51BC97A /* CETQuestionBankTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FAD6385C4872B3E80D4B00C /* CETQuestionBankTests.swift */; }; 938D3916C068089FACA81D61 /* MistakesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4391A8E13E5C7A35D0A1467A /* MistakesView.swift */; }; 96EB80336D8E7D70E3839817 /* kaoyan_english1_small.md in Resources */ = {isa = PBXBuildFile; fileRef = 6A7B637179FC6E271F31DBF4 /* kaoyan_english1_small.md */; }; 9EA1454709EC8802D43C7CA4 /* HistoryFolderEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 419DE9ABE9E26F14128B9B1E /* HistoryFolderEditor.swift */; }; @@ -100,6 +103,7 @@ 1020C698B4DA8C1C47852419 /* CorrectionMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CorrectionMatcher.swift; sourceTree = ""; }; 11E52B4F1877F33DAEDBED32 /* EssayHistoryGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EssayHistoryGroup.swift; sourceTree = ""; }; 161DE1C1158C7D408EAD0C20 /* WriteBenchTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WriteBenchTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 1689A9A92BD0E930F5FB82F9 /* CETQuestionBank.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CETQuestionBank.swift; sourceTree = ""; }; 17802ADDF6589CB80F4B4F01 /* KeychainService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainService.swift; sourceTree = ""; }; 1D56C8434F452DE88A5B9669 /* TextQuestionImportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextQuestionImportView.swift; sourceTree = ""; }; 2322E689ACEC8741C4B1C432 /* WriteBenchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteBenchApp.swift; sourceTree = ""; }; @@ -116,11 +120,13 @@ 419DE9ABE9E26F14128B9B1E /* HistoryFolderEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryFolderEditor.swift; sourceTree = ""; }; 4391A8E13E5C7A35D0A1467A /* MistakesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MistakesView.swift; sourceTree = ""; }; 4BCC37FAB6E0DDC543B0D48B /* DeepSeekStreaming.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepSeekStreaming.swift; sourceTree = ""; }; + 4FAD6385C4872B3E80D4B00C /* CETQuestionBankTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CETQuestionBankTests.swift; sourceTree = ""; }; 51A76CC13C7CABACEC80CBAE /* WindowImmersionBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowImmersionBridge.swift; sourceTree = ""; }; 56792E2C1501DBCE7B80739B /* kaoyan_english2_translation.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = kaoyan_english2_translation.md; sourceTree = ""; }; 5AEB65E44D0601AEC6053865 /* Exam.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Exam.swift; sourceTree = ""; }; 6211317C38F78901403EE347 /* TranslationLesson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslationLesson.swift; sourceTree = ""; }; 634F608AF0DF72D3DE51E438 /* GradingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradingService.swift; sourceTree = ""; }; + 63ABA3E9807196933476EF75 /* cet6-2022-2026-index.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "cet6-2022-2026-index.json"; sourceTree = ""; }; 650B4D62F506EDDC71D6396A /* cet6_writing.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = cet6_writing.md; sourceTree = ""; }; 679F1D25813DBB4821B089EF /* WriteBenchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteBenchTests.swift; sourceTree = ""; }; 6A7B637179FC6E271F31DBF4 /* kaoyan_english1_small.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = kaoyan_english1_small.md; sourceTree = ""; }; @@ -229,6 +235,7 @@ isa = PBXGroup; children = ( 31DECD6B9F0B3A54C27F4535 /* BackgroundGradingJob.swift */, + 1689A9A92BD0E930F5FB82F9 /* CETQuestionBank.swift */, 5AEB65E44D0601AEC6053865 /* Exam.swift */, DA0CA900CDD0D63C0AA6C39F /* GradingModels.swift */, 71E6EE384D62168057B908A3 /* QuestionBank.swift */, @@ -269,6 +276,15 @@ path = App; sourceTree = ""; }; + 85C04166008095CC4B9B2FA4 /* QuestionBank */ = { + isa = PBXGroup; + children = ( + 63ABA3E9807196933476EF75 /* cet6-2022-2026-index.json */, + ); + name = QuestionBank; + path = Shared/QuestionBank; + sourceTree = ""; + }; 8B0E934F4B4A8BD953E7FE15 /* Mistakes */ = { isa = PBXGroup; children = ( @@ -281,6 +297,7 @@ isa = PBXGroup; children = ( 34A07798AF0255AB8EAFF76A /* BackgroundGradingTests.swift */, + 4FAD6385C4872B3E80D4B00C /* CETQuestionBankTests.swift */, 879136039903990A8065C3BD /* HistoryReviewTests.swift */, 296A6193086826B2B071503F /* MockGradingService.swift */, 9F5E568498AF07D6BF8C1335 /* PracticeLoopTests.swift */, @@ -340,6 +357,7 @@ B32DAE4CDBDFC97EC7BE4B5A = { isa = PBXGroup; children = ( + 85C04166008095CC4B9B2FA4 /* QuestionBank */, CC65E74040E23A5ED1894671 /* WriteBench */, 8E4D664CF8F8C451767E12E6 /* WriteBenchTests */, 6C0EBEADE4784897205C53CF /* Products */, @@ -519,6 +537,7 @@ buildActionMask = 2147483647; files = ( 5317F309ED9004BD4665C0DC /* Assets.xcassets in Resources */, + 52D947565422EE245913DE21 /* cet6-2022-2026-index.json in Resources */, 361B2B881C01F86CC3A784DC /* cet6_translation.md in Resources */, D3F29CFA674B891722D5B739 /* cet6_writing.md in Resources */, DEBA962949C4AADDFCB2C5D0 /* ielts_task1.md in Resources */, @@ -544,6 +563,7 @@ 473B2ECB957707EDB2BF41AA /* BackgroundGradingView.swift in Sources */, FAEA4C1F539996D40D1AD105 /* BackupService.swift in Sources */, 7E4B43903D948A9E26E11E8D /* BrandArt.swift in Sources */, + 337FAAE005C9D52F7539091A /* CETQuestionBank.swift in Sources */, DEF094BE47996A62C68AB985 /* CodexJudgeService.swift in Sources */, C118D4E53ACEC303DE46EA50 /* CorrectionMatcher.swift in Sources */, 6C1F7BEC5994E87DFA1CEF27 /* DeepSeekClient.swift in Sources */, @@ -598,6 +618,7 @@ buildActionMask = 2147483647; files = ( 380960FEBBC3C2CDC16C3147 /* BackgroundGradingTests.swift in Sources */, + 8A386C67F3728D7CC51BC97A /* CETQuestionBankTests.swift in Sources */, F2DBAF31C0FA351AB0D126DB /* HistoryReviewTests.swift in Sources */, 32367F4CF29D3A467EFA453D /* MockGradingService.swift in Sources */, A54BFAD371DEB925FCA1963B /* PracticeLoopTests.swift in Sources */, diff --git a/WriteBench/Features/Writing/QuestionLibraryView.swift b/WriteBench/Features/Writing/QuestionLibraryView.swift index 8be374e..5445956 100644 --- a/WriteBench/Features/Writing/QuestionLibraryView.swift +++ b/WriteBench/Features/Writing/QuestionLibraryView.swift @@ -1,8 +1,10 @@ import SwiftUI import SwiftData +import AppKit +import UniformTypeIdentifiers struct QuestionLibraryView: View { - enum Source: String, CaseIterable, Identifiable { case builtIn = "内置题目", saved = "我的题库"; var id: String { rawValue } } + enum Source: String, CaseIterable, Identifiable { case builtIn = "内置题目", saved = "我的题库", cet = "近五年六级"; var id: String { rawValue } } @Environment(\.modelContext) private var context @Environment(\.dismiss) private var dismiss @Query(sort: \SavedQuestion.date, order: .reverse) private var questions: [SavedQuestion] @@ -17,6 +19,8 @@ struct QuestionLibraryView: View { @State private var year = "" @State private var newLabel = "" @State private var error: String? + @State private var cetEntries: [CETBankEntry] = [] + @State private var importStatus = "" private struct Item: Identifiable { let id: String @@ -27,21 +31,27 @@ struct QuestionLibraryView: View { var year: Int? = nil var label = "" var saved: SavedQuestion? = nil + var sourceURL: URL? = nil } private var currentTask: WritingTask { task ?? store.task } private var practiceIndex: PracticeIndex { PracticeIndex(sessions) } private var labels: [String] { Array(Set(questions.filter { $0.subtype == currentTask.rawValue }.map(\.label).filter { !$0.isEmpty })).sorted() } private func items(_ index: PracticeIndex) -> [Item] { - let all: [Item] = source == .builtIn - ? QuestionBank.questions(for: currentTask).map { Item(id: $0.id, task: $0.task, title: $0.title, prompt: $0.prompt) } - : questions.filter { $0.subtype == currentTask.rawValue }.map { - Item(id: $0.id.uuidString, task: currentTask, title: $0.title, prompt: $0.prompt, image: $0.image, year: $0.year, label: $0.label, saved: $0) - } + let all: [Item] + switch source { + case .builtIn: all = QuestionBank.questions(for: currentTask).map { Item(id: $0.id, task: $0.task, title: $0.title, prompt: $0.prompt) } + case .saved: all = questions.filter { $0.subtype == currentTask.rawValue }.map { + Item(id: $0.id.uuidString, task: currentTask, title: $0.title, prompt: $0.prompt, image: $0.image, year: $0.year, label: $0.label, saved: $0) + } + case .cet: all = cetEntries.filter { $0.task == currentTask.rawValue }.map { + Item(id: $0.id, task: currentTask, title: $0.title, prompt: $0.prompt, year: $0.year, label: $0.hasPrompt ? "用户导入 · 可练习" : "第三方来源索引 · 无正文", sourceURL: URL(string: $0.sourceUrl)) + } + } let query = search.trimmingCharacters(in: .whitespacesAndNewlines) return all.filter { item in (query.isEmpty || [item.title, item.prompt, item.label].contains { $0.localizedCaseInsensitiveContains(query) }) && (!unpractisedOnly || index.attempts(item.task, item.prompt).isEmpty) - && (source == .builtIn || label == nil || item.label == label) + && (source != .saved || label == nil || item.label == label) } } var body: some View { @@ -53,7 +63,7 @@ struct QuestionLibraryView: View { IconButton(symbol: "xmark", help: "Close") { dismiss() } } HStack(spacing: 12) { - Picker("来源", selection: $source) { ForEach(Source.allCases) { Text($0.rawValue).tag($0) } }.pickerStyle(.segmented).labelsHidden().fixedSize() + Picker("来源", selection: $source) { ForEach(Source.allCases.filter { $0 != .cet || store.task.exam == .cet6 }) { Text($0.rawValue).tag($0) } }.pickerStyle(.segmented).labelsHidden().fixedSize() Picker("题型", selection: Binding(get: { currentTask }, set: { task = $0; label = nil })) { ForEach(store.task.exam.tasks) { Text($0.title).tag($0) } }.labelsHidden().frame(width: 140) @@ -65,17 +75,29 @@ struct QuestionLibraryView: View { } Spacer() Toggle("只看未练习", isOn: $unpractisedOnly).toggleStyle(.checkbox).font(.system(size: 12)) - Button { if let pick = (visible.filter { index.attempts($0.task, $0.prompt).isEmpty }.randomElement() ?? visible.randomElement()) { use(pick) } } label: { + Button { if let pick = (visible.filter { !$0.prompt.isEmpty && index.attempts($0.task, $0.prompt).isEmpty }.randomElement() ?? visible.filter { !$0.prompt.isEmpty }.randomElement()) { use(pick) } } label: { Label("随机一道", systemImage: "dice") - }.buttonStyle(QuietButtonStyle()).disabled(visible.isEmpty).help("优先抽取还没练过的题") + }.buttonStyle(QuietButtonStyle()).disabled(!visible.contains { !$0.prompt.isEmpty }).help("优先抽取还没练过的题") } HStack { Image(systemName: "magnifyingglass").foregroundStyle(WB.secondary) TextField("搜索题目", text: $search).textFieldStyle(.plain) }.padding(10).background(.white, in: RoundedRectangle(cornerRadius: 10)).overlay(RoundedRectangle(cornerRadius: 10).stroke(WB.line)) + if store.task.exam == .cet6 { + HStack { + Text("2022–2026 · 有正文才能练习;套次沿用来源编号。").font(.system(size: 12)).foregroundStyle(WB.secondary) + Spacer() + Button("批量导入题库 JSON") { importCETBank() }.buttonStyle(QuietButtonStyle()) + } + if !importStatus.isEmpty { Text(importStatus).font(.system(size: 12)).foregroundStyle(WB.green) } + } ScrollView { VStack(spacing: 10) { - ForEach(visible) { item in row(item, attempts: index.attempts(item.task, item.prompt)) } + ForEach(visible) { item in + if item.prompt.isEmpty, let url = item.sourceURL { + Card(padding: 16) { VStack(alignment: .leading, spacing: 8) { Text(item.title).font(.system(size: 14, weight: .semibold)); Text("第三方来源索引 · 未核对正文,不能直接答题").font(.system(size: 12)).foregroundStyle(WB.secondary); Link("打开来源资料", destination: url) } } + } else { row(item, attempts: index.attempts(item.task, item.prompt)) } + } if visible.isEmpty { EmptyState(symbol: "books.vertical", title: source == .saved ? "把好题留在这里" : "没有符合条件的题目", detail: source == .saved ? "在写作页导入或识别题目,再在下方命名保存。" : "换一个题型,或关闭“只看未练习”。") @@ -84,7 +106,18 @@ struct QuestionLibraryView: View { } if source == .saved { saveBar } if let error { Text(error).foregroundStyle(WB.amber).font(.system(size: 12)) } - }.padding(28).frame(width: 760, height: 640).background(WB.canvas) + }.padding(28).frame(width: 900, height: 640).background(WB.canvas).onAppear { reloadCETBank() } + } + private func reloadCETBank() { + do { cetEntries = try CETQuestionBank.entries() } catch { self.error = error.localizedDescription } + } + private func importCETBank() { + let panel = NSOpenPanel(); panel.allowedContentTypes = [.json]; panel.allowsMultipleSelection = false + guard panel.runModal() == .OK, let url = panel.url else { return } + do { + let count = try CETQuestionBank.importData(Data(contentsOf: url)) + reloadCETBank(); source = .cet; importStatus = "已导入 \(count) 道完整题目;同 ID 更新,其余题目保留。"; error = nil + } catch { self.error = error.localizedDescription } } private func row(_ item: Item, attempts: [EssaySession]) -> some View { Button { use(item) } label: { diff --git a/WriteBench/Models/CETQuestionBank.swift b/WriteBench/Models/CETQuestionBank.swift new file mode 100644 index 0000000..5b18279 --- /dev/null +++ b/WriteBench/Models/CETQuestionBank.swift @@ -0,0 +1,66 @@ +import Foundation + +struct CETBankEntry: Codable, Hashable, Sendable, Identifiable { + var id: String + var task: String + var year: Int + var month: Int + var set: Int + var title: String + var prompt: String + var sourceUrl: String + var verification: String + var writingTask: WritingTask? { WritingTask(rawValue: task) } + var hasPrompt: Bool { !prompt.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty } +} +struct CETBankDocument: Codable, Sendable { + var schemaVersion: Int + var questions: [CETBankEntry] + func validated(requirePrompts: Bool, now: Date = Date()) throws -> [CETBankEntry] { + guard schemaVersion == 1, !questions.isEmpty, questions.count <= 1000 else { throw CETBankError.invalid("题库版本或数量无效") } + var ids = Set() + let calendar = Calendar(identifier: .gregorian) + for item in questions { + guard !item.id.isEmpty, ids.insert(item.id).inserted, ["cet6Writing", "cet6Translation"].contains(item.task), + (2022...2026).contains(item.year), [3, 6, 9, 12].contains(item.month), (1...3).contains(item.set), + let date = calendar.date(from: DateComponents(year: item.year, month: item.month, day: 1)), date <= now, + !item.title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty, item.prompt.count <= 100_000, + let url = URL(string: item.sourceUrl), ["https", "http"].contains(url.scheme ?? ""), url.host != nil, + ["sourceIndex", "userImported"].contains(item.verification) + else { throw CETBankError.invalid("题目 \(item.id) 的年份、题型、套次、来源或标识无效") } + if requirePrompts && !item.hasPrompt { throw CETBankError.invalid("题目 \(item.title) 只有来源索引,没有正文,不能作为练习题导入") } + } + return questions + } +} +enum CETBankError: LocalizedError { + case invalid(String) + var errorDescription: String? { if case let .invalid(message) = self { message } else { nil } } +} +enum CETQuestionBank { + static var storage: URL { FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0].appendingPathComponent("WriteBench/QuestionBank/cet6-custom.json") } + static func decode(_ data: Data, requirePrompts: Bool) throws -> [CETBankEntry] { + guard data.count <= 10 * 1024 * 1024 else { throw CETBankError.invalid("题库文件超过 10 MB") } + return try JSONDecoder().decode(CETBankDocument.self, from: data).validated(requirePrompts: requirePrompts) + } + static func entries(storage: URL = storage) throws -> [CETBankEntry] { + guard let url = Bundle.main.url(forResource: "cet6-2022-2026-index", withExtension: "json") else { throw CETBankError.invalid("内置来源索引未找到") } + let base = try decode(Data(contentsOf: url), requirePrompts: false) + let custom = FileManager.default.fileExists(atPath: storage.path) ? try decode(Data(contentsOf: storage), requirePrompts: true) : [] + var values = Dictionary(uniqueKeysWithValues: base.map { ($0.id, $0) }) + for item in custom { values[item.id] = item } + return values.values.sorted { ($0.year, $0.month, $0.set, $0.task) > ($1.year, $1.month, $1.set, $1.task) } + } + @discardableResult static func importData(_ data: Data, storage: URL = storage) throws -> Int { + let imported = try decode(data, requirePrompts: true).map { entry in var entry = entry; entry.verification = "userImported"; return entry } + let previous = FileManager.default.fileExists(atPath: storage.path) ? try decode(Data(contentsOf: storage), requirePrompts: true) : [] + var values = Dictionary(uniqueKeysWithValues: previous.map { ($0.id, $0) }) + for item in imported { values[item.id] = item } + let result = CETBankDocument(schemaVersion: 1, questions: values.values.sorted { $0.id < $1.id }) + let encoder = JSONEncoder(); encoder.outputFormatting = [.prettyPrinted, .sortedKeys] + let output = try encoder.encode(result) + try FileManager.default.createDirectory(at: storage.deletingLastPathComponent(), withIntermediateDirectories: true) + try output.write(to: storage, options: .atomic) + return imported.count + } +} diff --git a/WriteBench/Models/QuestionBank.swift b/WriteBench/Models/QuestionBank.swift index 91759ac..bceb683 100644 --- a/WriteBench/Models/QuestionBank.swift +++ b/WriteBench/Models/QuestionBank.swift @@ -11,7 +11,8 @@ struct BankQuestion: Identifiable, Hashable, Sendable { enum QuestionBank { static func questions(for task: WritingTask) -> [BankQuestion] { let sample = BankQuestion(id: "\(task.rawValue)-0", task: task, title: task == .kaoyanSmall ? "原创练习 · 邀请信" : "原创练习", prompt: task.sampleQuestion) - return [sample] + extra(task).enumerated().map { BankQuestion(id: "\(task.rawValue)-\($0.offset + 1)", task: task, title: $0.element.0, prompt: $0.element.1) } + let imported = ((try? CETQuestionBank.entries()) ?? []).filter { $0.task == task.rawValue && $0.hasPrompt }.map { BankQuestion(id: $0.id, task: task, title: $0.title, prompt: $0.prompt) } + return imported + [sample] + extra(task).enumerated().map { BankQuestion(id: "\(task.rawValue)-\($0.offset + 1)", task: task, title: $0.element.0, prompt: $0.element.1) } } static var all: [BankQuestion] { WritingTask.allCases.flatMap(questions(for:)) } diff --git a/WriteBenchTests/CETQuestionBankTests.swift b/WriteBenchTests/CETQuestionBankTests.swift new file mode 100644 index 0000000..3a3d176 --- /dev/null +++ b/WriteBenchTests/CETQuestionBankTests.swift @@ -0,0 +1,52 @@ +import Foundation +import Testing +@testable import WriteBench + +private func entry(_ id: String = "fixture", prompt: String = "Write an essay about careful planning.") -> CETBankEntry { + CETBankEntry(id: id, task: "cet6Writing", year: 2024, month: 6, set: 1, title: "导入测试", prompt: prompt, sourceUrl: "https://example.com/fixture", verification: "userImported") +} +private func bankData(_ entries: [CETBankEntry], version: Int = 1) throws -> Data { + try JSONEncoder().encode(CETBankDocument(schemaVersion: version, questions: entries)) +} +@Test func cetSourceIndexCoverage() throws { + let folder = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) + let entries = try CETQuestionBank.entries(storage: folder.appendingPathComponent("empty.json")) + #expect(entries.count == 66) + #expect(entries.filter { $0.task == "cet6Writing" }.count == 33) + #expect(entries.filter { $0.task == "cet6Translation" }.count == 33) + #expect(entries.allSatisfy { !$0.hasPrompt && $0.verification == "sourceIndex" }) + #expect(entries.contains { $0.year == 2022 && $0.month == 9 }) + #expect(entries.contains { $0.year == 2023 && $0.month == 3 }) + #expect(!entries.contains { $0.year == 2026 && $0.month == 12 }) +} +@Test func cetIndexIsNotPlayable() throws { + #expect(throws: CETBankError.self) { try CETQuestionBank.decode(bankData([entry(prompt: "")]), requirePrompts: true) } + #expect(try CETQuestionBank.decode(bankData([entry(prompt: "")]), requirePrompts: false).count == 1) +} +@Test func cetInvalidMetadataRejected() throws { + var invalid = entry(); invalid.task = "kaoyanLarge" + #expect(throws: CETBankError.self) { try CETQuestionBank.decode(bankData([invalid]), requirePrompts: true) } + invalid = entry(); invalid.sourceUrl = "file:///etc/passwd" + #expect(throws: CETBankError.self) { try CETQuestionBank.decode(bankData([invalid]), requirePrompts: true) } + #expect(throws: CETBankError.self) { try CETQuestionBank.decode(bankData([entry(), entry()]), requirePrompts: true) } + #expect(throws: CETBankError.self) { try CETQuestionBank.decode(bankData([entry()], version: 2), requirePrompts: true) } +} +@Test func cetFutureExamRejected() throws { + var invalid = entry(); invalid.year = 2026; invalid.month = 12 + let document = CETBankDocument(schemaVersion: 1, questions: [invalid]) + #expect(throws: CETBankError.self) { try document.validated(requirePrompts: true, now: Date(timeIntervalSince1970: 1_791_000_000)) } +} +@Test func cetImportMergesAndFailedImportPreservesFile() throws { + let directory = FileManager.default.temporaryDirectory.appendingPathComponent("cet-bank-" + UUID().uuidString) + defer { try? FileManager.default.removeItem(at: directory) } + let storage = directory.appendingPathComponent("bank.json") + #expect(try CETQuestionBank.importData(bankData([entry("a"), entry("b")]), storage: storage) == 2) + let before = try Data(contentsOf: storage) + #expect(throws: CETBankError.self) { try CETQuestionBank.importData(bankData([entry("c", prompt: "")]), storage: storage) } + #expect(try Data(contentsOf: storage) == before) + #expect(try CETQuestionBank.importData(bankData([entry("a", prompt: "Updated original practice question.")]), storage: storage) == 1) + let result = try CETQuestionBank.decode(Data(contentsOf: storage), requirePrompts: true) + #expect(result.count == 2) + #expect(result.first { $0.id == "a" }?.prompt == "Updated original practice question.") + #expect(result.allSatisfy { $0.verification == "userImported" }) +} diff --git a/platforms/windows/WriteBench/App.xaml.cs b/platforms/windows/WriteBench/App.xaml.cs index c8fa622..54e2843 100644 --- a/platforms/windows/WriteBench/App.xaml.cs +++ b/platforms/windows/WriteBench/App.xaml.cs @@ -25,7 +25,7 @@ protected override async void OnStartup(StartupEventArgs e) try { var window = new MainWindow(preview: true); - foreach (string page in new[] { "Write", "Settings", "answer" }) { + foreach (string page in new[] { "Write", "Settings", "answer", "CETLibrary" }) { window.PreviewPage(page); var view = (FrameworkElement)window.Content; view.Measure(new Size(1320, 840)); view.Arrange(new Rect(0, 0, 1320, 840)); view.UpdateLayout(); diff --git a/platforms/windows/WriteBench/SelfTest.cs b/platforms/windows/WriteBench/SelfTest.cs index e313908..34df76f 100644 --- a/platforms/windows/WriteBench/SelfTest.cs +++ b/platforms/windows/WriteBench/SelfTest.cs @@ -45,6 +45,26 @@ public static async Task Run() throw new Exception("Missing fields accepted"); await ExtendedTests(task, response); var window = new MainWindow(preview: true); window.CheckUI(); + var bank = new CETQuestionBank(Path.Combine(Path.GetTempPath(), "WriteBench-bank-test-" + Guid.NewGuid())); + var entries = bank.Entries(); + Assert(entries.Length == 66 && entries.Count(e => e.Task == "cet6Writing") == 33 && entries.All(e => !e.HasPrompt), "CET source index incomplete/playable"); + string bankDir = Path.Combine(Path.GetTempPath(), "WriteBench-import-test-" + Guid.NewGuid()); + try { + var imports = new CETQuestionBank(bankDir); + var sample = new CETBankEntry("fixture-a", "cet6Writing", 2024, 6, 1, "导入测试", "Write about careful planning.", "https://example.com/fixture", "userImported"); + byte[] Data(params CETBankEntry[] rows) => JsonSerializer.SerializeToUtf8Bytes(new CETBankDocument(1, rows), JSON.Options); + Assert(imports.Import(Data(sample, sample with { Id = "fixture-b" })) == 2, "CET batch import failed"); + byte[] before = File.ReadAllBytes(Path.Combine(bankDir, "cet6-custom.json")); + bool invalidRejected = false; + try { imports.Import(Data(sample with { Prompt = "" })); } catch { invalidRejected = true; } + Assert(invalidRejected && before.SequenceEqual(File.ReadAllBytes(Path.Combine(bankDir, "cet6-custom.json"))), "Incomplete bank mutated stored data"); + imports.Import(Data(sample with { Prompt = "Updated original practice question." })); + Assert(imports.Entries().Count(e => e.HasPrompt) == 2 && imports.Entries().Single(e => e.Id == sample.Id).Prompt == "Updated original practice question.", "Import update lost other questions"); + foreach (var invalid in new[] { sample with { Task = "kaoyanLarge" }, sample with { SourceUrl = "file:///etc/passwd" }, sample with { Year = 2026, Month = 12 } }) { + invalidRejected = false; try { CETQuestionBank.Decode(Data(invalid), true, new DateTime(2026, 10, 3)); } catch { invalidRejected = true; } + Assert(invalidRejected, "Invalid bank metadata accepted"); + } + } finally { if (Directory.Exists(bankDir)) Directory.Delete(bankDir, true); } var fixture = Path.Combine(AppContext.BaseDirectory, "ocr-fixture.png"); if (File.Exists(fixture)) { @@ -54,7 +74,7 @@ public static async Task Run() if (!page.GetText().Contains("Alex", StringComparison.OrdinalIgnoreCase)) throw new Exception("OCR fixture recognition failed"); } - File.WriteAllText(Path.Combine(AppContext.BaseDirectory, "self-test-passed.txt"), "Domain, aggregation, schema compatibility, bounded retries, interrupted streams, HTTP authorization, encrypted credentials, timer, native WPF editor/undo/Tab/progress and real OCR passed."); + File.WriteAllText(Path.Combine(AppContext.BaseDirectory, "self-test-passed.txt"), "Domain, aggregation, schema compatibility, bounded retries, interrupted streams, HTTP authorization, encrypted credentials, timer, native WPF editor/undo/Tab/progress CET question-bank import/source-index checks, and real OCR passed."); } static void Assert(bool condition, string name) { if (!condition) throw new Exception(name); } static async Task ExtendedTests(ExamTask task, JudgeResponse valid) diff --git a/platforms/windows/WriteBench/Services/CETQuestionBank.cs b/platforms/windows/WriteBench/Services/CETQuestionBank.cs new file mode 100644 index 0000000..233b4a3 --- /dev/null +++ b/platforms/windows/WriteBench/Services/CETQuestionBank.cs @@ -0,0 +1,47 @@ +using System.IO; +using System.Text.Json; +namespace WriteBench; + +public record CETBankEntry(string Id, string Task, int Year, int Month, int Set, string Title, string Prompt, string SourceUrl, string Verification) +{ + public bool HasPrompt => !string.IsNullOrWhiteSpace(Prompt); +} +public record CETBankDocument(int SchemaVersion, CETBankEntry[] Questions); +public sealed class CETQuestionBank(string? directory = null) +{ + readonly string folder = directory ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "WriteBench", "QuestionBank"); + string FileName => Path.Combine(folder, "cet6-custom.json"); + public static CETBankEntry[] Decode(byte[] data, bool requirePrompts, DateTime? now = null) + { + if (data.Length > 10 * 1024 * 1024) throw new Exception("题库文件超过 10 MB"); + var document = JsonSerializer.Deserialize(data, JSON.Options) ?? throw new Exception("题库为空"); + if (document.SchemaVersion != 1 || document.Questions is not { Length: > 0 and <= 1000 }) throw new Exception("题库版本或数量无效"); + var ids = new HashSet(); + foreach (var item in document.Questions) + { + if (item == null || string.IsNullOrWhiteSpace(item.Id) || !ids.Add(item.Id) || !new[] { "cet6Writing", "cet6Translation" }.Contains(item.Task) + || item.Year < 2022 || item.Year > 2026 || !new[] { 3, 6, 9, 12 }.Contains(item.Month) || item.Set < 1 || item.Set > 3 + || new DateTime(item.Year, item.Month, 1) > (now ?? DateTime.Now) || string.IsNullOrWhiteSpace(item.Title) || item.Prompt == null || item.Prompt.Length > 100_000 + || !Uri.TryCreate(item.SourceUrl, UriKind.Absolute, out var uri) || !new[] { "http", "https" }.Contains(uri.Scheme) || string.IsNullOrEmpty(uri.Host) + || !new[] { "sourceIndex", "userImported" }.Contains(item.Verification)) throw new Exception("题目年份、题型、套次、来源或标识无效"); + if (requirePrompts && !item.HasPrompt) throw new Exception($"题目 {item.Title} 只有来源索引,没有正文,不能作为练习题导入"); + } + return document.Questions; + } + public CETBankEntry[] Entries() + { + var bundled = Decode(File.ReadAllBytes(Path.Combine(AppContext.BaseDirectory, "QuestionBank", "cet6-2022-2026-index.json")), false); + var custom = File.Exists(FileName) ? Decode(File.ReadAllBytes(FileName), true) : []; + return bundled.Concat(custom).GroupBy(item => item.Id).Select(group => group.Last()).OrderByDescending(item => item.Year).ThenByDescending(item => item.Month).ThenBy(item => item.Set).ToArray(); + } + public int Import(byte[] data) + { + var imported = Decode(data, true).Select(item => item with { Verification = "userImported" }).ToArray(); + var old = File.Exists(FileName) ? Decode(File.ReadAllBytes(FileName), true) : []; + var merged = old.Concat(imported).GroupBy(item => item.Id).Select(group => group.Last()).ToArray(); + Directory.CreateDirectory(folder); + File.WriteAllText(FileName + ".tmp", JsonSerializer.Serialize(new CETBankDocument(1, merged), JSON.Options)); + File.Move(FileName + ".tmp", FileName, true); + return imported.Length; + } +} diff --git a/platforms/windows/WriteBench/Views/MainWindow.cs b/platforms/windows/WriteBench/Views/MainWindow.cs index eb56418..74c6ef7 100644 --- a/platforms/windows/WriteBench/Views/MainWindow.cs +++ b/platforms/windows/WriteBench/Views/MainWindow.cs @@ -130,6 +130,9 @@ void Render() Content = grid; switch (page) { + case "CETLibrary": + CETLibrary(); + break; case "History": History(); break; @@ -150,6 +153,22 @@ void Render() break; } } + void CETLibrary() + { + Heading("近五年六级题库", "2022–2026 · 来源索引与可练习正文分开显示,套次沿用来源编号。"); + content.Children.Add(Button("批量导入题库 JSON", () => { + var picker = new OpenFileDialog { Filter = "题库 JSON|*.json" }; if (picker.ShowDialog(this) != true) return; + int count = new CETQuestionBank().Import(File.ReadAllBytes(picker.FileName)); Message($"已导入 {count} 道完整题目;同 ID 更新,其余保留。"); Render(); + }, true)); + try { + foreach (var entry in new CETQuestionBank().Entries().Where(entry => entry.Task == task.Id)) { + var card = Card(content); card.Children.Add(Text(entry.Title, 18)); + card.Children.Add(Text(entry.HasPrompt ? "用户导入 · 可练习" : "第三方来源索引 · 未核对正文,不能直接答题", 12, Muted)); + if (entry.HasPrompt) { card.Children.Add(Text(entry.Prompt, 14)); card.Children.Add(Button("使用这道题", () => { question = entry.Prompt; page = "Write"; SaveDraft(); Render(); })); } + card.Children.Add(Button("打开来源资料", () => System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(entry.SourceUrl) { UseShellExecute = true }))); + } + } catch (Exception e) { content.Children.Add(Text(e.Message, 14)); } + } void Preparation() { Heading(task.Translation ? "准备翻译" : "准备写作", task.Translation ? (task.Chinese ? "英译汉 · 译义准确,表达自然。" : "汉译英 · 忠实完整地传达原文。") : "选好题目,开始一段安静的写作。"); @@ -157,6 +176,7 @@ void Preparation() foreach (var t in ExamTask.All.Where(t => t.Exam == task.Exam)) sub.Children.Add(Button(t.Title, () => SelectTask(t), t == task)); content.Children.Add(sub); + if (task.Exam == "CET-6 六级") content.Children.Add(Button("近五年六级题库 / 批量导入", () => { page = "CETLibrary"; Render(); })); var c = Card(content); c.Children.Add(Text("题目 · 原创练习 / 自行导入", 13, Muted)); var q = Input(question, 210); @@ -340,10 +360,13 @@ internal void CheckUI() if (judgeStatus.Count != 3 || !editor!.IsReadOnly) throw new Exception("Grading UI did not lock answer/show progress"); grading = false; Render(); if (writingTimer.Running) throw new Exception("Failed grading resumed timer"); + PreviewPage("CETLibrary"); + if (content.Children.Count < 33) throw new Exception("CET source index missing from WPF library"); Close(); } internal void PreviewPage(string destination) { + if (destination == "CETLibrary") task = ExamTask.All.First(t => t.Id == "cet6Writing"); answering = destination == "answer"; if (answering) { essay = "Notice\r\n\r\n Our university library is recruiting student volunteers.\r\n\r\n University Library"; writingTimer.Reset(600); } else page = destination; diff --git a/platforms/windows/WriteBench/WriteBench.csproj b/platforms/windows/WriteBench/WriteBench.csproj index cbc0c74..c64fb3c 100644 --- a/platforms/windows/WriteBench/WriteBench.csproj +++ b/platforms/windows/WriteBench/WriteBench.csproj @@ -1,4 +1,4 @@ WinExenet10.0-windowstrueenableenableAssets\WriteBench.icoWriteBench1.9.1falsetruewin-x64 - + diff --git a/project.yml b/project.yml index 4dc4896..8db197c 100644 --- a/project.yml +++ b/project.yml @@ -19,6 +19,8 @@ targets: platform: macOS sources: - WriteBench + - path: Shared/QuestionBank/cet6-2022-2026-index.json + buildPhase: resources settings: base: PRODUCT_BUNDLE_IDENTIFIER: com.chen.WriteBench From 6ec03d9d6229cadb17801eb8c5d949db462f5e6c Mon Sep 17 00:00:00 2001 From: Functionhx <172989722+Functionhx@users.noreply.github.com> Date: Sat, 3 Oct 2026 19:19:08 -0700 Subject: [PATCH 2/2] Import 66 complete CET-6 tasks from user-provided PDF and Word papers --- README.md | 6 +- RELEASE-NOTES.md | 8 + Shared/QuestionBank/README.md | 64 +- Shared/QuestionBank/cet6-2022-2026-index.json | 731 -------------- Shared/QuestionBank/cet6-2022-2026.json | 891 ++++++++++++++++++ Shared/QuestionBank/cet6-import-audit.json | 370 ++++++++ WriteBench.xcodeproj/project.pbxproj | 16 +- .../Writing/QuestionLibraryView.swift | 8 +- WriteBench/Features/Writing/WritingView.swift | 4 +- WriteBench/Models/CETQuestionBank.swift | 4 +- WriteBenchTests/CETQuestionBankTests.swift | 6 +- platforms/windows/README.md | 6 +- platforms/windows/WriteBench/SelfTest.cs | 4 +- .../WriteBench/Services/CETQuestionBank.cs | 4 +- .../windows/WriteBench/Views/MainWindow.cs | 26 +- .../windows/WriteBench/WriteBench.csproj | 4 +- project.yml | 6 +- scripts/import-cet6.py | 66 ++ 18 files changed, 1422 insertions(+), 802 deletions(-) delete mode 100644 Shared/QuestionBank/cet6-2022-2026-index.json create mode 100644 Shared/QuestionBank/cet6-2022-2026.json create mode 100644 Shared/QuestionBank/cet6-import-audit.json create mode 100644 scripts/import-cet6.py diff --git a/README.md b/README.md index e1f8bd8..dc2f52f 100644 --- a/README.md +++ b/README.md @@ -47,11 +47,13 @@ WriteBench 把练习收敛为一条清晰的路径:选题、作答、评阅、 | 平台 | 安装方式 | 当前状态 | | :--- | :--- | :--- | | **macOS 15+** | 下载 ZIP / DMG,将 WriteBench.app 放入 Applications | 原生 SwiftUI,Apple silicon + Intel | -| **Windows 11 x64** | [下载便携 ZIP](https://github.com/Functionhx/WriteBench/releases/download/v1.9.1/WriteBench-1.9.1-Windows-x64.zip),完整解压后运行 WriteBench.exe | 原生 WPF / .NET 10 · 1.9.1 | +| **Windows 11 x64** | [下载便携 ZIP](https://github.com/Functionhx/WriteBench/releases/download/v1.9.2/WriteBench-1.9.2-Windows-x64.zip),完整解压后运行 WriteBench.exe | 原生 WPF / .NET 10 · 1.9.2 | | **Android 13+** | [下载签名 APK](https://github.com/Functionhx/WriteBench/releases/download/v1.3.0/WriteBench-0.1.0-Android.apk),在手机安装 | 原生 Android Views · 0.1 预览版 | macOS 当前是本地 ad-hoc 签名版本,尚未经过 Apple Developer ID 公证;Windows 预览版尚未进行 Authenticode 签名。Windows OCR 需要 Microsoft Visual C++ x64 运行库,详见[平台说明](platforms/windows/README.md)。公开仓库与安装包不包含 API Key、Codex 登录信息或用户作文。 +六级写作、翻译现已在 Windows 与 macOS 内置 2022–2026 年完整题库,各 33 题;包含 2022 年 9 月与 2023 年 3 月场次。原题从用户提供的 PDF/Word 交叉提取,套次沿用资料编号。详见[题库与核对记录](Shared/QuestionBank/README.md)。 + ## 开始使用 1. 打开 **Settings**,填写自己的 DeepSeek API Key,点击 **使用此 Key**。macOS 默认勾选 **在这台 Mac 上记住 Key**,重启和更新后自动读取。保存为仅当前用户可读写的本机文件(非加密、不随作文备份导出);取消勾选并保存则仅本次运行使用。 @@ -137,7 +139,7 @@ platforms/android/ Android Studio 项目与手机界面 scripts/ 构建、图标生成与显式联调脚本 ``` -macOS 自动化测试覆盖 82 个案例,Android 有 5 个领域测试与 2 个实际设备服务测试;Windows 通过评分、持久化、字段校验及实际 OCR 自检。GPT-6 Astra/MAX 已通过实际 Swift 子进程完成样例评卷;DeepSeek 已验证官方模型接口连接。后台、流式输出及版本路径已用隔离测试验证;本次未执行完整付费三评,需用户填入有效 Key 后使用。 +macOS 自动化测试覆盖 87 个案例,Android 有 5 个领域测试与 2 个实际设备服务测试;Windows 通过评分、持久化、字段校验及实际 OCR 自检。GPT-6 Astra/MAX 已通过实际 Swift 子进程完成样例评卷;DeepSeek 已验证官方模型接口连接。后台、流式输出及版本路径已用隔离测试验证;本次未执行完整付费三评,需用户填入有效 Key 后使用。
更多文档 diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 821d745..c01c108 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,3 +1,11 @@ +# 1.9.2 · 近五年六级完整真题库 + +- Windows 与 macOS 共用 2022–2026 年六级题库:33 套,写作 33 题、翻译 33 题,完整题干可直接用于答题;2026 仅含已收录的 6 月场次。 +- 包含 2022 年 9 月、2023 年 3 月场次;按年份、月份、资料套次和主题标明。套次以提供的资料为准。 +- 原文从用户提供的本机 PDF/Word 提取并逐题交叉核对;保留指定开头与作答要求,移除页眉、页脚及排版空格,未包含范文和答案。少数英文词内断空格修复有记录。 +- 六级随机抽题优先使用真题;题库支持两端共用的批量 JSON 导入,同 ID 更新、保留其他题目,无效文件整批拒绝。 +- 内置题不改写用户已有草稿、历史和手动保存的题目。原 PDF/Word 未打包,仅包含题目文本与来源、校对记录。 + # 1.9.1 · Windows 核心功能补齐与评分兼容 - Windows 便携 x64 版升级至 1.9.1,Key 使用当前 Windows 账户加密保存,支持忘记 Key 与连接检查。 diff --git a/Shared/QuestionBank/README.md b/Shared/QuestionBank/README.md index b2b41d3..19b90e4 100644 --- a/Shared/QuestionBank/README.md +++ b/Shared/QuestionBank/README.md @@ -1,39 +1,31 @@ -# 六级 2022–2026 题库数据 - -Windows 和 macOS 使用同一个 `cet6-2022-2026-index.json` 文件。 - -**目前是第三方来源索引,包含写作 33 条、翻译 33 条,不包含真题正文,不能直接作为练习题。** 目录来自以下页面,并保留来源的套次编号,尚未逐卷核对正文、日期或题目真实性: - -- https://english-exam.lazynote.cn/cet6/sections/writing/ -- https://english-exam.lazynote.cn/cet6/sections/chinese-english-translation/ - -范围:2022、2023、2024、2025、2026;2026 仅列 6 月。包含目录中的 2022 年 9 月与 2023 年 3 月条目。不能将来源编号视为所有机构一致使用的官方套次编号。 - -## 完整正文批量导入 - -从用户提供的 PDF、图片或题目文件中提取并校对题目后,生成相同 JSON 格式: - -```json -{ - "schemaVersion": 1, - "questions": [ - { - "id": "cet6-2024-06-1-cet6Writing", - "task": "cet6Writing", - "year": 2024, - "month": 6, - "set": 1, - "title": "2024 年 6 月 · 来源第 1 套 · 写作", - "prompt": "这里填写从你提供的资料提取并校对后的完整题干", - "sourceUrl": "https://example.com/source", - "verification": "userImported" - } - ] -} -``` +# 六级 2022–2026 真题库 + +Windows 和 macOS 内置同一份 `cet6-2022-2026.json`:**33 套,写作 33 题、翻译 33 题,均包含完整正文,可直接选题作答。** + +正文提取自用户提供的本机真题 PDF 与 Word 文件。每套的写作题干和翻译题段落均经过 PDF/DOCX 交叉对比,移除了页眉、页脚、听力说明和排版断行,未混入答案或范文。保留写作题的指定开头、150–200 词要求及其他指令。中文词内的排版空格已清理。 + +少数资料存在英文词内断空格及标点空格问题,如 `t o`、`sen tence`;已对照 PDF 原页修复,并在条目的 `layoutCorrections` 中记录。未擅自改变指定句子的语法或观点。 + +范围:2022–2025 各已收录场次,以及 2026 年 6 月;包括 2022 年 9 月与 2023 年 3 月场次。套次沿用用户资料/来源网站编号,不保证其他机构的套次编号相同。资料核对依据为用户提供的文件,不表示这些重排资料是考试院发布的原版扫描件。 + +`cet6-import-audit.json` 保存每套 PDF、Word 的 SHA-256、文件名、交叉核对结果和题干长度。原始 PDF/Word 未复制进安装包。 + +## 使用 -翻译的 `task` 为 `cet6Translation`。来源链接应指向所用资料的出处,不应伪造。导入文件必须全部有正文;仅含索引、重复 ID、未知题型、无效来源、未来考试日期或不支持的数据版本会整体拒绝,原题库不变。相同 ID 在后续导入中更新,其余已有条目保留。 +macOS:六级 → 写作/翻译 → 题库,默认显示近五年六级真题;“随机抽题”优先从六级真题抽取,并优先选未练习题目。 -macOS:题库 → 近五年六级 → 批量导入题库 JSON。Windows:六级 → 写作/翻译 → 近五年六级题库/批量导入。 +Windows:六级 → 写作/翻译 → 随机真题,或“近五年六级题库/批量导入”逐题选择。 + +## 批量导入与复核 + +两平台接受相同 JSON 格式,顶层为 `schemaVersion: 1` 和 `questions` 数组;题目字段为 `id`、`task`、`year`、`month`、`set`、`title`、`prompt`、`sourceUrl`、`verification`。题型为 `cet6Writing` 或 `cet6Translation`;用户导入标识为 `userImported`,本次从资料核对的内置题为 `providedDocument`。 + +缺正文、重复 ID、未知题型、无效来源、未来考试日期或不支持的数据版本会整批拒绝,原题库不变。相同 ID 更新,其余已有题目保留。内置题不会修改用户此前手动保存的题目和作答。 + +重新提取(需本机有 Poppler 的 `pdftotext`): + +```sh +python3 scripts/import-cet6.py --source '/path/to/六级真题2022-2026' +``` -用户题库只保存在本机:macOS `~/Library/Application Support/WriteBench/QuestionBank/cet6-custom.json`;Windows `%LOCALAPPDATA%/WriteBench/QuestionBank/cet6-custom.json`。两平台使用同一种格式,但不会自动跨设备同步。macOS 原有“我的题库”备份不会自动包含这个独立 JSON 文件;迁移时应另行复制它。 +额外导入题目保存于 macOS `~/Library/Application Support/WriteBench/QuestionBank/cet6-custom.json`,Windows `%LOCALAPPDATA%/WriteBench/QuestionBank/cet6-custom.json`。同一 JSON 可在两平台导入,但不自动跨设备同步。macOS 现有“我的题库”备份不包含此独立 JSON,迁移时应另行复制它。 diff --git a/Shared/QuestionBank/cet6-2022-2026-index.json b/Shared/QuestionBank/cet6-2022-2026-index.json deleted file mode 100644 index 2ba51d3..0000000 --- a/Shared/QuestionBank/cet6-2022-2026-index.json +++ /dev/null @@ -1,731 +0,0 @@ -{ - "schemaVersion": 1, - "questions": [ - { - "id": "cet6-2026-06-1-cet6Writing", - "task": "cet6Writing", - "year": 2026, - "month": 6, - "set": 1, - "title": "2026 年 6 月 · 来源第 1 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-1/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2026-06-2-cet6Writing", - "task": "cet6Writing", - "year": 2026, - "month": 6, - "set": 2, - "title": "2026 年 6 月 · 来源第 2 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-2/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2026-06-3-cet6Writing", - "task": "cet6Writing", - "year": 2026, - "month": 6, - "set": 3, - "title": "2026 年 6 月 · 来源第 3 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-3/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-12-1-cet6Writing", - "task": "cet6Writing", - "year": 2025, - "month": 12, - "set": 1, - "title": "2025 年 12 月 · 来源第 1 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-1/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-12-2-cet6Writing", - "task": "cet6Writing", - "year": 2025, - "month": 12, - "set": 2, - "title": "2025 年 12 月 · 来源第 2 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-2/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-12-3-cet6Writing", - "task": "cet6Writing", - "year": 2025, - "month": 12, - "set": 3, - "title": "2025 年 12 月 · 来源第 3 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-3/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-06-1-cet6Writing", - "task": "cet6Writing", - "year": 2025, - "month": 6, - "set": 1, - "title": "2025 年 6 月 · 来源第 1 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-1/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-06-2-cet6Writing", - "task": "cet6Writing", - "year": 2025, - "month": 6, - "set": 2, - "title": "2025 年 6 月 · 来源第 2 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-2/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-06-3-cet6Writing", - "task": "cet6Writing", - "year": 2025, - "month": 6, - "set": 3, - "title": "2025 年 6 月 · 来源第 3 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-3/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-12-1-cet6Writing", - "task": "cet6Writing", - "year": 2024, - "month": 12, - "set": 1, - "title": "2024 年 12 月 · 来源第 1 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-1/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-12-2-cet6Writing", - "task": "cet6Writing", - "year": 2024, - "month": 12, - "set": 2, - "title": "2024 年 12 月 · 来源第 2 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-2/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-12-3-cet6Writing", - "task": "cet6Writing", - "year": 2024, - "month": 12, - "set": 3, - "title": "2024 年 12 月 · 来源第 3 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-3/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-06-1-cet6Writing", - "task": "cet6Writing", - "year": 2024, - "month": 6, - "set": 1, - "title": "2024 年 6 月 · 来源第 1 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-1/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-06-2-cet6Writing", - "task": "cet6Writing", - "year": 2024, - "month": 6, - "set": 2, - "title": "2024 年 6 月 · 来源第 2 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-2/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-06-3-cet6Writing", - "task": "cet6Writing", - "year": 2024, - "month": 6, - "set": 3, - "title": "2024 年 6 月 · 来源第 3 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-3/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-12-1-cet6Writing", - "task": "cet6Writing", - "year": 2023, - "month": 12, - "set": 1, - "title": "2023 年 12 月 · 来源第 1 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-1/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-12-2-cet6Writing", - "task": "cet6Writing", - "year": 2023, - "month": 12, - "set": 2, - "title": "2023 年 12 月 · 来源第 2 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-2/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-12-3-cet6Writing", - "task": "cet6Writing", - "year": 2023, - "month": 12, - "set": 3, - "title": "2023 年 12 月 · 来源第 3 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-3/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-06-1-cet6Writing", - "task": "cet6Writing", - "year": 2023, - "month": 6, - "set": 1, - "title": "2023 年 6 月 · 来源第 1 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-1/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-06-2-cet6Writing", - "task": "cet6Writing", - "year": 2023, - "month": 6, - "set": 2, - "title": "2023 年 6 月 · 来源第 2 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-2/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-06-3-cet6Writing", - "task": "cet6Writing", - "year": 2023, - "month": 6, - "set": 3, - "title": "2023 年 6 月 · 来源第 3 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-3/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-03-1-cet6Writing", - "task": "cet6Writing", - "year": 2023, - "month": 3, - "set": 1, - "title": "2023 年 3 月 · 来源第 1 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-1/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-03-2-cet6Writing", - "task": "cet6Writing", - "year": 2023, - "month": 3, - "set": 2, - "title": "2023 年 3 月 · 来源第 2 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-2/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-03-3-cet6Writing", - "task": "cet6Writing", - "year": 2023, - "month": 3, - "set": 3, - "title": "2023 年 3 月 · 来源第 3 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-3/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-12-1-cet6Writing", - "task": "cet6Writing", - "year": 2022, - "month": 12, - "set": 1, - "title": "2022 年 12 月 · 来源第 1 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-1/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-12-2-cet6Writing", - "task": "cet6Writing", - "year": 2022, - "month": 12, - "set": 2, - "title": "2022 年 12 月 · 来源第 2 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-2/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-12-3-cet6Writing", - "task": "cet6Writing", - "year": 2022, - "month": 12, - "set": 3, - "title": "2022 年 12 月 · 来源第 3 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-3/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-09-1-cet6Writing", - "task": "cet6Writing", - "year": 2022, - "month": 9, - "set": 1, - "title": "2022 年 9 月 · 来源第 1 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-1/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-09-2-cet6Writing", - "task": "cet6Writing", - "year": 2022, - "month": 9, - "set": 2, - "title": "2022 年 9 月 · 来源第 2 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-2/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-09-3-cet6Writing", - "task": "cet6Writing", - "year": 2022, - "month": 9, - "set": 3, - "title": "2022 年 9 月 · 来源第 3 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-3/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-06-1-cet6Writing", - "task": "cet6Writing", - "year": 2022, - "month": 6, - "set": 1, - "title": "2022 年 6 月 · 来源第 1 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-1/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-06-2-cet6Writing", - "task": "cet6Writing", - "year": 2022, - "month": 6, - "set": 2, - "title": "2022 年 6 月 · 来源第 2 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-2/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-06-3-cet6Writing", - "task": "cet6Writing", - "year": 2022, - "month": 6, - "set": 3, - "title": "2022 年 6 月 · 来源第 3 套 · 写作", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-3/part1/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2026-06-1-cet6Translation", - "task": "cet6Translation", - "year": 2026, - "month": 6, - "set": 1, - "title": "2026 年 6 月 · 来源第 1 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-1/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2026-06-2-cet6Translation", - "task": "cet6Translation", - "year": 2026, - "month": 6, - "set": 2, - "title": "2026 年 6 月 · 来源第 2 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-2/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2026-06-3-cet6Translation", - "task": "cet6Translation", - "year": 2026, - "month": 6, - "set": 3, - "title": "2026 年 6 月 · 来源第 3 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-3/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-12-1-cet6Translation", - "task": "cet6Translation", - "year": 2025, - "month": 12, - "set": 1, - "title": "2025 年 12 月 · 来源第 1 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-1/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-12-2-cet6Translation", - "task": "cet6Translation", - "year": 2025, - "month": 12, - "set": 2, - "title": "2025 年 12 月 · 来源第 2 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-2/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-12-3-cet6Translation", - "task": "cet6Translation", - "year": 2025, - "month": 12, - "set": 3, - "title": "2025 年 12 月 · 来源第 3 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-3/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-06-1-cet6Translation", - "task": "cet6Translation", - "year": 2025, - "month": 6, - "set": 1, - "title": "2025 年 6 月 · 来源第 1 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-1/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-06-2-cet6Translation", - "task": "cet6Translation", - "year": 2025, - "month": 6, - "set": 2, - "title": "2025 年 6 月 · 来源第 2 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-2/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2025-06-3-cet6Translation", - "task": "cet6Translation", - "year": 2025, - "month": 6, - "set": 3, - "title": "2025 年 6 月 · 来源第 3 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-3/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-12-1-cet6Translation", - "task": "cet6Translation", - "year": 2024, - "month": 12, - "set": 1, - "title": "2024 年 12 月 · 来源第 1 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-1/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-12-2-cet6Translation", - "task": "cet6Translation", - "year": 2024, - "month": 12, - "set": 2, - "title": "2024 年 12 月 · 来源第 2 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-2/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-12-3-cet6Translation", - "task": "cet6Translation", - "year": 2024, - "month": 12, - "set": 3, - "title": "2024 年 12 月 · 来源第 3 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-3/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-06-1-cet6Translation", - "task": "cet6Translation", - "year": 2024, - "month": 6, - "set": 1, - "title": "2024 年 6 月 · 来源第 1 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-1/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-06-2-cet6Translation", - "task": "cet6Translation", - "year": 2024, - "month": 6, - "set": 2, - "title": "2024 年 6 月 · 来源第 2 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-2/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2024-06-3-cet6Translation", - "task": "cet6Translation", - "year": 2024, - "month": 6, - "set": 3, - "title": "2024 年 6 月 · 来源第 3 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-3/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-12-1-cet6Translation", - "task": "cet6Translation", - "year": 2023, - "month": 12, - "set": 1, - "title": "2023 年 12 月 · 来源第 1 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-1/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-12-2-cet6Translation", - "task": "cet6Translation", - "year": 2023, - "month": 12, - "set": 2, - "title": "2023 年 12 月 · 来源第 2 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-2/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-12-3-cet6Translation", - "task": "cet6Translation", - "year": 2023, - "month": 12, - "set": 3, - "title": "2023 年 12 月 · 来源第 3 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-3/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-06-1-cet6Translation", - "task": "cet6Translation", - "year": 2023, - "month": 6, - "set": 1, - "title": "2023 年 6 月 · 来源第 1 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-1/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-06-2-cet6Translation", - "task": "cet6Translation", - "year": 2023, - "month": 6, - "set": 2, - "title": "2023 年 6 月 · 来源第 2 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-2/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-06-3-cet6Translation", - "task": "cet6Translation", - "year": 2023, - "month": 6, - "set": 3, - "title": "2023 年 6 月 · 来源第 3 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-3/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-03-1-cet6Translation", - "task": "cet6Translation", - "year": 2023, - "month": 3, - "set": 1, - "title": "2023 年 3 月 · 来源第 1 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-1/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-03-2-cet6Translation", - "task": "cet6Translation", - "year": 2023, - "month": 3, - "set": 2, - "title": "2023 年 3 月 · 来源第 2 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-2/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2023-03-3-cet6Translation", - "task": "cet6Translation", - "year": 2023, - "month": 3, - "set": 3, - "title": "2023 年 3 月 · 来源第 3 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-3/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-12-1-cet6Translation", - "task": "cet6Translation", - "year": 2022, - "month": 12, - "set": 1, - "title": "2022 年 12 月 · 来源第 1 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-1/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-12-2-cet6Translation", - "task": "cet6Translation", - "year": 2022, - "month": 12, - "set": 2, - "title": "2022 年 12 月 · 来源第 2 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-2/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-12-3-cet6Translation", - "task": "cet6Translation", - "year": 2022, - "month": 12, - "set": 3, - "title": "2022 年 12 月 · 来源第 3 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-3/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-09-1-cet6Translation", - "task": "cet6Translation", - "year": 2022, - "month": 9, - "set": 1, - "title": "2022 年 9 月 · 来源第 1 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-1/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-09-2-cet6Translation", - "task": "cet6Translation", - "year": 2022, - "month": 9, - "set": 2, - "title": "2022 年 9 月 · 来源第 2 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-2/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-09-3-cet6Translation", - "task": "cet6Translation", - "year": 2022, - "month": 9, - "set": 3, - "title": "2022 年 9 月 · 来源第 3 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-3/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-06-1-cet6Translation", - "task": "cet6Translation", - "year": 2022, - "month": 6, - "set": 1, - "title": "2022 年 6 月 · 来源第 1 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-1/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-06-2-cet6Translation", - "task": "cet6Translation", - "year": 2022, - "month": 6, - "set": 2, - "title": "2022 年 6 月 · 来源第 2 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-2/part-iv/", - "verification": "sourceIndex" - }, - { - "id": "cet6-2022-06-3-cet6Translation", - "task": "cet6Translation", - "year": 2022, - "month": 6, - "set": 3, - "title": "2022 年 6 月 · 来源第 3 套 · 翻译", - "prompt": "", - "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-3/part-iv/", - "verification": "sourceIndex" - } - ] -} diff --git a/Shared/QuestionBank/cet6-2022-2026.json b/Shared/QuestionBank/cet6-2022-2026.json new file mode 100644 index 0000000..6d7fafe --- /dev/null +++ b/Shared/QuestionBank/cet6-2022-2026.json @@ -0,0 +1,891 @@ +{ + "schemaVersion": 1, + "questions": [ + { + "id": "cet6-2026-06-1-cet6Translation", + "task": "cet6Translation", + "year": 2026, + "month": 6, + "set": 1, + "title": "2026 年 6 月 · 第 1 套 · 科技与医疗", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n科技进步使中国的医疗事业得到快速发展。近年来,远程医疗使优质医疗资源惠及更多患者。医学专家可以通过视频为偏远地区患者提供咨询,指导当地医生制定并实施治疗方案。人工智能辅助诊断系统帮助医生识别患者的早期症状,提高诊断准确率。电子健康档案的普及让医生能够快速了解患者病史,避免重复检查。线上医疗咨询平台极大地方便了患者就诊。科技与医疗的深度融合更好地满足了人民的健康需求。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-1/part-iv/", + "verification": "providedDocument", + "sourceFile": "2026/英语六级2026年6月第1套真题(整卷).pdf", + "sourceSha256": "0df76248c652e977c6289e80d3aa42b0757e28060c603c901a5a654004f300a0" + }, + { + "id": "cet6-2026-06-1-cet6Writing", + "task": "cet6Writing", + "year": 2026, + "month": 6, + "set": 1, + "title": "2026 年 6 月 · 第 1 套 · 亲近自然与城市生活", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"With the trend of Urbanization, it is vitally important for city residents to develop a stronger love for Nature.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-1/part1/", + "verification": "providedDocument", + "sourceFile": "2026/英语六级2026年6月第1套真题(整卷).pdf", + "sourceSha256": "0df76248c652e977c6289e80d3aa42b0757e28060c603c901a5a654004f300a0" + }, + { + "id": "cet6-2026-06-2-cet6Translation", + "task": "cet6Translation", + "year": 2026, + "month": 6, + "set": 2, + "title": "2026 年 6 月 · 第 2 套 · 农村电子商务", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n电子商务的蓬勃发展正在深刻改变中国农村的面貌。随着互联网和物流网络快速向农村延伸,越来越多的农村居民通过电子商务平台将农产品直接销售给城市消费者。近年来,直播带货(live-streaming commerce)使城市消费者能够与卖家实时互动,已成为促进农村发展的一种新方式。电子商务打破了城乡之间的信息壁垒,拓宽了农产品销售渠道,帮助农村居民增收致富。数字经济与乡村振兴的深度融合,正在为中国农村发展注入前所未有的活力。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-2/part-iv/", + "verification": "providedDocument", + "sourceFile": "2026/英语六级2026年6月第2套真题(整卷).pdf", + "sourceSha256": "2411b6f58b774603ae274896642f44fdc73cb71b4976da519617d0b31e746125" + }, + { + "id": "cet6-2026-06-2-cet6Writing", + "task": "cet6Writing", + "year": 2026, + "month": 6, + "set": 2, + "title": "2026 年 6 月 · 第 2 套 · 青年责任感", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"In an era of rapid social development, it is vitally important to enhance young people's sense of responsibility.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-2/part1/", + "verification": "providedDocument", + "sourceFile": "2026/英语六级2026年6月第2套真题(整卷).pdf", + "sourceSha256": "2411b6f58b774603ae274896642f44fdc73cb71b4976da519617d0b31e746125" + }, + { + "id": "cet6-2026-06-3-cet6Translation", + "task": "cet6Translation", + "year": 2026, + "month": 6, + "set": 3, + "title": "2026 年 6 月 · 第 3 套 · 无人机产业", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n近年来,中国无人机(drone)产业蓬勃发展,出口量跃升为全球第一。中国的无人机以出色的稳定性、高清(high-definition)拍摄能力和便捷的操作,受到全球消费者的喜爱,在民用领域得到广泛应用。无人机已被国家纳入战略性新兴产业,逐步成为能满足多种场景需求的智能助手。在农村,无人机可精准识别农作物病虫害,高效喷洒农药。在城市,无人机可快速运送生鲜食品。在不久的将来,无人机能够在更多领域实现其独特价值,为经济社会发展注入新动能。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-3/part-iv/", + "verification": "providedDocument", + "sourceFile": "2026/英语六级2026年6月第3套真题(整卷).pdf", + "sourceSha256": "72f20ebafe95c79bb06edf42adaca7d7b6ba59528e68ffb26f3ef86d600749e1" + }, + { + "id": "cet6-2026-06-3-cet6Writing", + "task": "cet6Writing", + "year": 2026, + "month": 6, + "set": 3, + "title": "2026 年 6 月 · 第 3 套 · 传统文化与文化自信", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"Faced with growing globalization, students realize that a deep understanding of traditional Chinese culture helps cultivate cultural confidence.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2026-06-3/part1/", + "verification": "providedDocument", + "sourceFile": "2026/英语六级2026年6月第3套真题(整卷).pdf", + "sourceSha256": "72f20ebafe95c79bb06edf42adaca7d7b6ba59528e68ffb26f3ef86d600749e1", + "layoutCorrections": [ + { + "original": "globalization,students", + "corrected": "globalization, students" + } + ] + }, + { + "id": "cet6-2025-12-1-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 12, + "set": 1, + "title": "2025 年 12 月 · 第 1 套 · 尊老传统", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n尊老是中华民族的传统美德,深深植根于中国人的思想和行为中,是人们普遍遵守的行为规范和社会准则。在当今的中国,这种美德得到广泛传承。社会各界积极营造敬老助老的社会氛围。为老年人提供便利服务已成为社会共识,例如社区专门开设长者食堂,公共场所配置优先座位。政府还出台了一系列政策,为老年人的权益提供有力保障。尊老是社会和谐与发展的重要基石,有助于培育良好的社会氛围,推动整个社会文明进步。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-1/part-iv/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年12月第1套真题(整卷).pdf", + "sourceSha256": "fbb389a72593d61e522c48e17ededbee3005f58890c6db906c55c068c012c1cf" + }, + { + "id": "cet6-2025-12-1-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 12, + "set": 1, + "title": "2025 年 12 月 · 第 1 套 · 中国梦与青年自我价值", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"While striving for the Chinese Dream, young people enjoy more opportunities to realize their self-worth.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-1/part1/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年12月第1套真题(整卷).pdf", + "sourceSha256": "fbb389a72593d61e522c48e17ededbee3005f58890c6db906c55c068c012c1cf" + }, + { + "id": "cet6-2025-12-2-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 12, + "set": 2, + "title": "2025 年 12 月 · 第 2 套 · 自强自立", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n中华民族崇尚自强自立的精神,这一精神深植于中国文化之中,是民族生存与发展的重要支撑。改革开放以来,中国在自强自立的征程上,持续加大科研投入,在信息技术、人工智能、航天工程等领域不断取得新突破。5G网络覆盖全国,远程医疗发展迅速,电子支付的使用全球领先,嫦娥探月工程展现了航天领域引人注目的发展。自强自主精神成为推动国家现代化进程的强大动力,激励着中国人民为实现民族复兴(rejuvenation)的中国梦不断奋进。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-2/part-iv/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年12月第2套真题(整卷).pdf", + "sourceSha256": "e3fdfac47463f14b10ed9649ddde6d07439a6188eb9f9b792640196f2ea2dda3" + }, + { + "id": "cet6-2025-12-2-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 12, + "set": 2, + "title": "2025 年 12 月 · 第 2 套 · 教师对学生的影响", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"It is believed that teachers can exert a profound influence on their students' academic pursuit and personal development.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-2/part1/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年12月第2套真题(整卷).pdf", + "sourceSha256": "e3fdfac47463f14b10ed9649ddde6d07439a6188eb9f9b792640196f2ea2dda3" + }, + { + "id": "cet6-2025-12-3-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 12, + "set": 3, + "title": "2025 年 12 月 · 第 3 套 · 节俭传统", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n节俭(frugality)是中华民族的传统美德。在中国古代,生产力低下,先人们深知劳动成果来之不易,因而秉持节俭的理念。到了物质极大丰富的今天,中国人民依然坚持节俭的生活方式,体现了理性消费的生活理念和对劳动的尊重。近年来,中国政府持续加强节约型社会的建设,倡导\"光盘行动\",减少食物浪费,提倡简约低碳的生活方式,推进资源循环利用,反对过度消费。节约型社会的建设有力地推动了中国经济的高质量发展。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-3/part-iv/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年12月第3套真题(整卷).pdf", + "sourceSha256": "22d68e1174049930a97df672710bd8aed39097591ebe09d8c009ba1a7c884791" + }, + { + "id": "cet6-2025-12-3-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 12, + "set": 3, + "title": "2025 年 12 月 · 第 3 套 · 应对竞争与挑战", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"Living in an increasingly competitive world, college students should better prepare themselves to confront various challenges.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-12-3/part1/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年12月第3套真题(整卷).pdf", + "sourceSha256": "22d68e1174049930a97df672710bd8aed39097591ebe09d8c009ba1a7c884791" + }, + { + "id": "cet6-2025-06-1-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 6, + "set": 1, + "title": "2025 年 6 月 · 第 1 套 · 天宫空间站", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n天宫空间站(Tiangong Space Station)是中国首个太空实验室,拥有110多立方米使用空间,可驻留三名宇航员,在距地球表面400-450公里的轨道上运行。天宫空间站已实施180多个科学研究与应用项目,涉及空间生命科学、太空医学、空间材料科学等领域。天宫空间站的研究成果在我国得到了广泛应用,产生了显著的经济效益。例如,太空育种创造的直接经济效益高达数千亿元。这不仅标志中国在航天技术上取得了巨大进步,也表明中国为全球的太空研究和应用做出了重大贡献。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-1/part-iv/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年6月第1套真题(整卷).pdf", + "sourceSha256": "964aedfc1a34d085d64c5f0ffd7158788bed652071c64c3b29ea810bbdd00155" + }, + { + "id": "cet6-2025-06-1-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 6, + "set": 1, + "title": "2025 年 6 月 · 第 1 套 · 职业准备", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"As requirements for job applications are getting increasingly higher, college students ought to be better prepared for their future career.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-1/part1/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年6月第1套真题(整卷).pdf", + "sourceSha256": "964aedfc1a34d085d64c5f0ffd7158788bed652071c64c3b29ea810bbdd00155" + }, + { + "id": "cet6-2025-06-2-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 6, + "set": 2, + "title": "2025 年 6 月 · 第 2 套 · 粤港澳大湾区", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n粤港澳大湾区(Guangdong-Hong Kong-Macao Greater Bay Area)具有得天独厚的地理位置,拥有完善的交通基础设施和丰富的产业资源。大湾区是中国开放程度最高、经济活力最强的区域之一,在国家经济发展中具有重要的战略地位。大湾区不仅将建成充满活力的世界级城市群和具有全球影响力的国际科技创新中心,还将打造成适合工作、购物、旅游的优质生活圈。随着改革开放的不断深入,大湾区的建设将进一步推动区域经济发展。到2035年,大湾区将实现成为国际一流湾区的目标。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-2/part-iv/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年6月第2套真题(整卷).pdf", + "sourceSha256": "cd0c60961faa8f2cde89a8bbd5f95b57d4cd55b277accf478198d66d5981eb5a" + }, + { + "id": "cet6-2025-06-2-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 6, + "set": 2, + "title": "2025 年 6 月 · 第 2 套 · 负责任地使用社交媒体", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"As social media is used more and more extensively, there is a growing awareness of the importance of using it properly and responsibly.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-2/part1/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年6月第2套真题(整卷).pdf", + "sourceSha256": "cd0c60961faa8f2cde89a8bbd5f95b57d4cd55b277accf478198d66d5981eb5a" + }, + { + "id": "cet6-2025-06-3-cet6Translation", + "task": "cet6Translation", + "year": 2025, + "month": 6, + "set": 3, + "title": "2025 年 6 月 · 第 3 套 · 南水北调", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n自古以来,中国的水资源北缺南丰,分布极不均衡。为了有效解决北方严重缺水问题,中国政府实施了南水北调工程(the South-to-North Water Diversion Project)。这是一项跨区域配置水资源的宏大水利工程。历经数十年的规划与筹备,工程于2002年开工建设,分为东、中、西三条线路,总长4350公里,惠及人口将超过4亿。自2014年通水以来,工程向北方调水累计已超500亿立方米,为北方地区的人民提供了可靠的水资源,同时也极大地改善了这一地区的生态环境,促进了经济的可持续健康发展。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-3/part-iv/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年6月第3套真题(整卷).pdf", + "sourceSha256": "7559420e92387bb51a26dc4d0d7de9ae8fc080d7e5d047e53ff354739dcacaf5" + }, + { + "id": "cet6-2025-06-3-cet6Writing", + "task": "cet6Writing", + "year": 2025, + "month": 6, + "set": 3, + "title": "2025 年 6 月 · 第 3 套 · 人工智能与创造力", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"With the increasing application of AI technology, there is a growing concern that it may negatively impact human creativity.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2025-06-3/part1/", + "verification": "providedDocument", + "sourceFile": "2025/英语六级2025年6月第3套真题(整卷).pdf", + "sourceSha256": "7559420e92387bb51a26dc4d0d7de9ae8fc080d7e5d047e53ff354739dcacaf5" + }, + { + "id": "cet6-2024-12-1-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 12, + "set": 1, + "title": "2024 年 12 月 · 第 1 套 · 北斗导航系统", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n北斗(Beidou)卫星导航系统的成功研制是中国自改革开放以来取得的一项重大科技成就。研发人员经过不懈努力,攻克了一系列技术难题,北斗系统最终实现了全球覆盖和高精度定位,使中国成为世界上少数几个独立拥有全球卫星导航系统的国家之一。北斗系统已广泛应用于交通运输、灾害救援、天气预报、公共安全等诸多领域。北斗系统现在已经在国际上得到广泛认可,开始为越来越多的国家和地区提供优质服务。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-1/part-iv/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年12月第1套真题(整卷).pdf", + "sourceSha256": "70956c7b81b3ba3f137e98ac4b46ce254309def0b20c2b7a1745266e31a4efec" + }, + { + "id": "cet6-2024-12-1-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 12, + "set": 1, + "title": "2024 年 12 月 · 第 1 套 · 现实目标与持之以恒", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “To increase the likelihood of success, one should set realistic goals and work persistently towards them.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words.You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-1/part1/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年12月第1套真题(整卷).pdf", + "sourceSha256": "70956c7b81b3ba3f137e98ac4b46ce254309def0b20c2b7a1745266e31a4efec" + }, + { + "id": "cet6-2024-12-2-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 12, + "set": 2, + "title": "2024 年 12 月 · 第 2 套 · 洋山港", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n洋山港(Yangshan Port)是上海航运中心的重要组成部分,是中国第一个深水港,也是世界上规模最大的深水港之一。经过近20年的发展,洋山港已实现高度自动化。数字技术和人工智能的使用大大减少了用工成本和碳排放。自主研发的码头管理系统可以在百公里之外对大型设备进行远程操控。洋山港看上去一片繁忙,现场却见不到人工操作,而且能够24小时不间断运作。洋山港将不断发展,为把上海建成一个全球航运中心做出更大贡献。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-2/part-iv/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年12月第2套真题(整卷).pdf", + "sourceSha256": "3d09b2104bf8f9b0f5f46e080d34bda5e9d2d81ffb2b88513b39faee1d144cfa" + }, + { + "id": "cet6-2024-12-2-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 12, + "set": 2, + "title": "2024 年 12 月 · 第 2 套 · 自律与个人成长", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"Nowadays, more and more students have realized the importance of self-discipline in their personal growth.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words.You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-2/part1/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年12月第2套真题(整卷).pdf", + "sourceSha256": "3d09b2104bf8f9b0f5f46e080d34bda5e9d2d81ffb2b88513b39faee1d144cfa" + }, + { + "id": "cet6-2024-12-3-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 12, + "set": 3, + "title": "2024 年 12 月 · 第 3 套 · 中国载人航天", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n遨游太空历来是中华民族的梦想。2003年,神舟五号飞船发射成功,杨利伟成为第一个飞入太空的中国宇航员。2008年,神舟七号升空,翟志刚成为中国历史上首位进行太空行走的宇航员。近年来,中国航天进入创新发展\"快车道\",太空基础设施建设稳步推进,中国空间站于2022年全面建成。中国航天事业的迅速发展在中华民族的历史上写下了辉煌一页,也为人类文明进步做出了巨大贡献。未来,中国探索太空的脚步将迈得更稳、更远。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-3/part-iv/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年12月第3套真题(整卷).pdf", + "sourceSha256": "445484a4480b5e7429065087013209e7d93251a0bf4ab8a58def5b17c4ff635c" + }, + { + "id": "cet6-2024-12-3-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 12, + "set": 3, + "title": "2024 年 12 月 · 第 3 套 · 探索人生方向", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “College provides a great opportunity for students to explore various possibilities and find the right path for themselves.” You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. You should copy the sentence given in quotes at the beginning of your essay.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-12-3/part1/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年12月第3套真题(整卷).pdf", + "sourceSha256": "445484a4480b5e7429065087013209e7d93251a0bf4ab8a58def5b17c4ff635c" + }, + { + "id": "cet6-2024-06-1-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 6, + "set": 1, + "title": "2024 年 6 月 · 第 1 套 · 传统婚礼", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n中国的传统婚礼习俗历史悠久,从周朝开始就逐渐形成了一套完整的婚礼仪式,有些一直沿用至今。如今的中式婚礼习俗已有很大变化,但婚礼庆典仍然十分隆重。婚礼场地经过精心装饰,以象征喜庆(jubilance)的红色为主色调,摆放着许多祝愿新人幸福的物件。在婚礼上,新人要拜天地(bow to Heaven and Earth)、拜父母和相互对拜,然后设宴招待宾客,并向宾客敬酒致谢。今天,许多年轻人依然钟情于传统的中式婚礼,体验独特而美好的中国式浪漫。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-1/part-iv/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年6月第1套真题(整卷).pdf", + "sourceSha256": "f6cd11c8f5c99d480ae98072345c4ee2e9b6a29ab5f21d6a5f35761f35f9bc8f" + }, + { + "id": "cet6-2024-06-1-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 6, + "set": 1, + "title": "2024 年 6 月 · 第 1 套 · 自主学习能力", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “Nowadays, cultivating independent learning ability is becoming increasingly crucial for personal development.” You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. (You should copy the sentence given in quotes at the beginning of your essay.)", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-1/part1/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年6月第1套真题(整卷).pdf", + "sourceSha256": "f6cd11c8f5c99d480ae98072345c4ee2e9b6a29ab5f21d6a5f35761f35f9bc8f" + }, + { + "id": "cet6-2024-06-2-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 6, + "set": 2, + "title": "2024 年 6 月 · 第 2 套 · 竹子", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n中国盛产竹子,是最早开发利用竹资源的国家。竹子在中国分布广泛,品种丰富。竹子实用性强,用于生产和生活的许多方面,如筷子、桌椅的制作和桥梁、房屋的建造。中国人爱竹,自古以来就有无数文人以竹为主题,创作了绚丽多彩的文学和绘画作品。竹子主干(stem)笔直,象征正直的品格。竹子具有强大的生命力和适应能力,无论环境多么恶劣,都能够顽强生存,因而寓意坚韧不拔的精神。几千年来,竹子一直被视为中华民族品格的象征。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-2/part-iv/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年6月第2套真题(整卷).pdf", + "sourceSha256": "eed58359d56438ec081d3ac1c2978d2cd1bfddf812f7c3a14c57ecb86347af09" + }, + { + "id": "cet6-2024-06-2-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 6, + "set": 2, + "title": "2024 年 6 月 · 第 2 套 · 社会实践与学业", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “Nowadays more and more college students have come to realize social practice and academic learning are equally important.” You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. (You should copy the sentence given in quotes at the beginning of your essay.)", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-2/part1/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年6月第2套真题(整卷).pdf", + "sourceSha256": "eed58359d56438ec081d3ac1c2978d2cd1bfddf812f7c3a14c57ecb86347af09" + }, + { + "id": "cet6-2024-06-3-cet6Translation", + "task": "cet6Translation", + "year": 2024, + "month": 6, + "set": 3, + "title": "2024 年 6 月 · 第 3 套 · 扇子", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n扇子自古以来就深受中国人喜爱,但现在已不只是消暑纳凉的工具,而更多地作为艺术品供人欣赏。许多扇子造型优美、做工精良,并绘有山水、花鸟、人物等精美图案,具有很高的艺术价值。中国许多著名画家和书法家喜欢在扇子上作诗绘画,展示其艺术品味。扇子常作为礼物赠予他人,表达美好的祝福和真挚的情感。如今,扇子的实用功能已大为减弱,但作为一种文化符号和艺术形式,扇子仍然在中国传统文化中扮演着重要角色。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-3/part-iv/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年6月第3套真题(整卷).pdf", + "sourceSha256": "e2cdb42a70d183a59326d151ab021d531c5788ebf13f7e4858e54a969c5388c4" + }, + { + "id": "cet6-2024-06-3-cet6Writing", + "task": "cet6Writing", + "year": 2024, + "month": 6, + "set": 3, + "title": "2024 年 6 月 · 第 3 套 · 数字素养与技能", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “There is a growing awareness of the importance of digital literacy and skills in today’s world.” You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words. (You should copy the sentence given in quotes at the beginning of your essay. )", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2024-06-3/part1/", + "verification": "providedDocument", + "sourceFile": "2024/英语六级2024年6月第3套真题(整卷).pdf", + "sourceSha256": "e2cdb42a70d183a59326d151ab021d531c5788ebf13f7e4858e54a969c5388c4" + }, + { + "id": "cet6-2023-12-1-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 12, + "set": 1, + "title": "2023 年 12 月 · 第 1 套 · 多元养老模式", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n在中国,随着老龄化社会的到来,养老受到普遍关注。人们谈论最多的是应当采取什么样的养老模式。多数人认为,养老模式需要多元化。可以通过政府引导和社会参与,建立更多更好的养老服务机构,改进社区服务中心,鼓励居家自助养老,还可以推行家庭养老与社会养老相结合的模式。随着政府和社会对养老服务事业投入的持续增加,养老设施将不断升级,服务质量逐步改进,老年人的生活将会更加方便舒适、健康快乐。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-1/part-iv/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年12月第1套真题(整卷).pdf", + "sourceSha256": "ae0ce2b9900a3c68bfe2eea3eb150ece6c349db4e11cd6dd90b3788255d4cfa9" + }, + { + "id": "cet6-2023-12-1-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 12, + "set": 1, + "title": "2023 年 12 月 · 第 1 套 · 学科基础知识", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"As is known to all, gaining a sound knowledge of the basics is of vital importance for students to master an academic subject.”You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words (not including the sentence given).", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-1/part1/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年12月第1套真题(整卷).pdf", + "sourceSha256": "ae0ce2b9900a3c68bfe2eea3eb150ece6c349db4e11cd6dd90b3788255d4cfa9" + }, + { + "id": "cet6-2023-12-2-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 12, + "set": 2, + "title": "2023 年 12 月 · 第 2 套 · 应对人口老龄化", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n随着经济与社会的发展,中国人口结构发生了显著变化,逐渐步入老龄化社会。中国老年人口将持续增加,人口老龄化趋势将更加明显。为了应对人口老龄化带来的种种挑战,国家正积极采取措施,加大对养老的支持。通过改革社会保障(social security)制度,政府不断增加社会保障经费,逐步扩大社会保障覆盖范围,使更多老年人受益。政府还鼓励各种社会团体为老年人提供服务。在政府和社会团体的共同努力下,老年人将生活得更加幸福。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-2/part-iv/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年12月第2套真题(整卷).pdf", + "sourceSha256": "7e4c39c2f55d8c8f85cacec51dd429a699ab05ac808ba7aee28f84cbebfb317e" + }, + { + "id": "cet6-2023-12-2-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 12, + "set": 2, + "title": "2023 年 12 月 · 第 2 套 · 儿童自主探索", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “Nowadays parents are increasingly aware that allowing kids more freedom to explore and learn on their own helps foster their independence and boost their confidence.” You can make comments, cite examples or use your personal experiences to develop your essay.You should write at least 150 words but no more than 200 words(not including the sentence given).", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-2/part1/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年12月第2套真题(整卷).pdf", + "sourceSha256": "7e4c39c2f55d8c8f85cacec51dd429a699ab05ac808ba7aee28f84cbebfb317e" + }, + { + "id": "cet6-2023-12-3-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 12, + "set": 3, + "title": "2023 年 12 月 · 第 3 套 · 养老服务体系", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n近年来,中国老龄人口持续增长。中国政府正采取各种措施,推进养老服务体系建设,使老年人晚年生活健康幸福。全国兴建了各类养老服务机构。为了提升养老机构的服务质量,政府颁布了一系列标准,加强对养老机构的监管。许多城市为方便老年人用餐,开设了社区食堂,为他们提供价格实惠的饭菜。行动不便的老年人还能享受上门送餐服务。同时,中国还在积极探索居家和社区养老等其他养老模式,以确保所有老年人老有所养。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-3/part-iv/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年12月第3套真题(整卷).pdf", + "sourceSha256": "20deb499f923bf14978f579c88dcf2fe0f4cb3e742131593d8d469fb41fe9275" + }, + { + "id": "cet6-2023-12-3-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 12, + "set": 3, + "title": "2023 年 12 月 · 第 3 套 · 老年人的社会贡献", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “With their valuable skills and experience, elderly people can continue to make significant contributions to society.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-12-3/part1/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年12月第3套真题(整卷).pdf", + "sourceSha256": "20deb499f923bf14978f579c88dcf2fe0f4cb3e742131593d8d469fb41fe9275" + }, + { + "id": "cet6-2023-06-1-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 6, + "set": 1, + "title": "2023 年 6 月 · 第 1 套 · 文化产品出口", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n近年来,越来越多的中国文化产品走向全球市场,日益受到海外消费者的青睐。随着中国对外文化贸易的快速发展,中国文化产品出口额已持续多年位居世界前列,形成了一批具有国际影响力的文化企业、产品和品牌。数据显示,中国的出版物、影视作品、网络文学与动漫作品等在海外的销售量连年攀升。中国政府出台了一系列政策鼓励和支持更多具有中国元素的优秀文化产品走出国门,扩大海外市场份额,进一步提升中国文化的世界影响力。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-1/part-iv/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年6月第1套真题(整卷).pdf", + "sourceSha256": "45b2f3e738065e1729f5882eb4f185ab431290446710c3b847c24621a2aedbb1" + }, + { + "id": "cet6-2023-06-1-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 6, + "set": 1, + "title": "2023 年 6 月 · 第 1 套 · 心理健康", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"Today there is a growing awareness that mental well-being needs to be given as much attention as physical health.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-1/part1/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年6月第1套真题(整卷).pdf", + "sourceSha256": "45b2f3e738065e1729f5882eb4f185ab431290446710c3b847c24621a2aedbb1" + }, + { + "id": "cet6-2023-06-2-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 6, + "set": 2, + "title": "2023 年 6 月 · 第 2 套 · 城市公共设施", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n随着中国经济的快速发展和人们生活水平的稳步提高,城市居民对环境和生活品质的要求越来越高。中国地方政府更加注重公共设施的建设和改进,以更好地满足人们的需求。通过兴建新的广场、公园和公共绿地或对原有公共场地重新加以规划改造,许多城市为市民提供了更多休闲和社交的场所。如今,政府出资购置的健身器械和铺设的健身步道在不少城市随处可见,既明显改善了市民户外活动的条件,又使城市更加美丽。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-2/part-iv/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年6月第2套真题(整卷).pdf", + "sourceSha256": "0816c073830aeef48a9896a526e65d2a621215010acf5511754b7cb54fe0504b" + }, + { + "id": "cet6-2023-06-2-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 6, + "set": 2, + "title": "2023 年 6 月 · 第 2 套 · 通过讨论达成共识", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “When faced with differing opinions, we should try to reach agreement through friendly discussion and reasonable argument.” You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words(not including the sentence given).", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-2/part1/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年6月第2套真题(整卷).pdf", + "sourceSha256": "0816c073830aeef48a9896a526e65d2a621215010acf5511754b7cb54fe0504b" + }, + { + "id": "cet6-2023-06-3-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 6, + "set": 3, + "title": "2023 年 6 月 · 第 3 套 · 城市人居环境", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n近年来,中国城市加快发展,城市人居环境得到显著改善。许多城市努力探索中国特色的城市高质量发展之路,城市功能不断完善,治理水平明显提高。中国持续开展城市生态修复和功能修补,全面实施城镇老旧小区改造,大力推进城市园林绿化,消除污染;同时大力推进城市基础设施体系化建设,开展房屋建筑和市政设施普查以及安全隐患排查整治,努力为市民创造高品质的生活环境,让城市更美丽、更安全、更宜居。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-3/part-iv/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年6月第3套真题(整卷).pdf", + "sourceSha256": "8ed7812347fba15b99ceb23916e020054d9ae444558e16a5e7e53f45350293d0" + }, + { + "id": "cet6-2023-06-3-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 6, + "set": 3, + "title": "2023 年 6 月 · 第 3 套 · 学会学习", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence \"It is widely accepted that an important goal of education is to help students learn how to learn.\" You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-06-3/part1/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年6月第3套真题(整卷).pdf", + "sourceSha256": "8ed7812347fba15b99ceb23916e020054d9ae444558e16a5e7e53f45350293d0" + }, + { + "id": "cet6-2023-03-1-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 3, + "set": 1, + "title": "2023 年 3 月 · 第 1 套 · 张骞", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n张骞(Zhang Qian)是中国第一个伟大的探险家。他不畏艰险,克服重重困难,两次出使西域,开通了中国同西亚和欧洲的通商关系,将中国的丝和丝织品运往西亚和欧洲,开拓了历史上著名的\"丝绸之路\"。同时,他又将西域的风土人情、地理文化以及特有物种等介绍到中原,极大地开阔了人们的视野。正如历史学家所指出的那样,如果没有张骞出使西域,就不可能有丝绸之路的开辟,也就不会有汉朝同西域或欧洲的文化交流。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-1/part-iv/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年3月第1套真题(整卷).pdf", + "sourceSha256": "b298418c5f2b2a7c6ea0e5f3106293ffd3cd2b9244cae4c93187c0eea7504a30" + }, + { + "id": "cet6-2023-03-1-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 3, + "set": 1, + "title": "2023 年 3 月 · 第 1 套 · 容貌焦虑", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “People are now increasingly aware of the danger of ‘appearance anxiety’ or being obsessed with one’s looks.” You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-1/part1/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年3月第1套真题(整卷).pdf", + "sourceSha256": "b298418c5f2b2a7c6ea0e5f3106293ffd3cd2b9244cae4c93187c0eea7504a30" + }, + { + "id": "cet6-2023-03-2-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 3, + "set": 2, + "title": "2023 年 3 月 · 第 2 套 · 郑和", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n郑和是中国历史上最杰出的航海家,在航海、外交、军事等诸多领域都表现出非凡的智慧和卓越的才能。他曾七次率领庞大的船队远航,访问了西太平洋和印度洋的许多国家和地区,加深了中国同东南亚、东非的相互了解。郑和下西洋对中外的经济和文化交流起到了十分积极的推进作用,也为维护区域和平做出了巨大贡献。为了永远铭记郑和及其丰功伟绩,7月11日,即郑和首次率船队远航启程的日子,被定为中国的航海节。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-2/part-iv/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年3月第2套真题(整卷).pdf", + "sourceSha256": "d00269d42b413bb68ecbe084b598266bb92711abc3a75141c54420835bb1d1b3" + }, + { + "id": "cet6-2023-03-2-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 3, + "set": 2, + "title": "2023 年 3 月 · 第 2 套 · 选择过多与决策", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “People are now increasingly aware of the challenges in making a decision when faced with too many choices.” You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-2/part1/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年3月第2套真题(整卷).pdf", + "sourceSha256": "d00269d42b413bb68ecbe084b598266bb92711abc3a75141c54420835bb1d1b3" + }, + { + "id": "cet6-2023-03-3-cet6Translation", + "task": "cet6Translation", + "year": 2023, + "month": 3, + "set": 3, + "title": "2023 年 3 月 · 第 3 套 · 徐霞客", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n徐霞客是中国明代的著名地理学家。他花费了三十多年的时间游遍了大半个中国。他主要靠徒步跋涉,寻访了许多荒远偏僻的地区。他把自己的见闻和考察结果详细记录下来,为后人留下了珍贵的考察资料。他通过对许多河流的实地调查,纠正了文献中关于水源的错误。他还详细地描述了地形、气候等因素对植物的影响,生动地描绘了各地的名胜古迹和风土人情。他的考察记录由后人整理成了《徐霞客游记》,在国内外产生了广泛的影响。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-3/part-iv/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年3月第3套真题(整卷).pdf", + "sourceSha256": "72f8826adab1b33f9cb8795eabe115fadb7b36e39d6a8648ac0d9f19e978c6ec" + }, + { + "id": "cet6-2023-03-3-cet6Writing", + "task": "cet6Writing", + "year": 2023, + "month": 3, + "set": 3, + "title": "2023 年 3 月 · 第 3 套 · 老年人与数字鸿沟", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “People are now increasingly aware of the ‘digital gap’ or challenges the elderly face in a digital world.” You can make comments, give explanations, or cite examples to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2023-03-3/part1/", + "verification": "providedDocument", + "sourceFile": "2023/英语六级2023年3月第3套真题(整卷).pdf", + "sourceSha256": "72f8826adab1b33f9cb8795eabe115fadb7b36e39d6a8648ac0d9f19e978c6ec" + }, + { + "id": "cet6-2022-12-1-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 12, + "set": 1, + "title": "2022 年 12 月 · 第 1 套 · 青藏高原", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n青藏高原(the Qinghai-Tibet Plateau)位于中国西南部,面积约230万平方公里,平均海拔4000米以上,被称为\"世界屋脊\"。青藏高原自然资源丰富,风景秀丽,拥有多种珍稀野生动物。青藏高原气温很低,形成了大面积高山冰川。这里是亚洲许多著名河流的源头,是中国和东南亚的主要淡水供应源。青藏高原对全球生态系统至关重要。由于气候变化的影响,青藏高原的冰川正在加速融化。中国一直在努力保护青藏高原的生态系统,草地覆盖率不断增加,许多濒危物种得到更为有效的保护。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-1/part-iv/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年12月第1套真题(整卷).pdf", + "sourceSha256": "025f979c61abef94b263d05cd77386f46a29a9b87c30220a9c7911f7eae3acab" + }, + { + "id": "cet6-2022-12-1-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 12, + "set": 1, + "title": "2022 年 12 月 · 第 1 套 · 信息技术与教育", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence“With the application of information technology in education, college students can now learn in more diverse and efficient ways.” You can make statements, give reasons, or cite examples to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-1/part1/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年12月第1套真题(整卷).pdf", + "sourceSha256": "025f979c61abef94b263d05cd77386f46a29a9b87c30220a9c7911f7eae3acab" + }, + { + "id": "cet6-2022-12-2-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 12, + "set": 2, + "title": "2022 年 12 月 · 第 2 套 · 黄土高原", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n黄土高原(the Loess Plateau)是中国第三大高原,面积约60万平方公里,平均海拔1000-2000米,绝大部分覆盖着50-80米厚的黄土,是世界上黄土分布最集中、覆盖厚度最大的区域。这是大自然创造的一个奇迹,在世界上也是绝无仅有的。黄土高原是中华民族的发祥地之一。早在5500年前,人们就已经在黄土高原上开始农耕。随着农耕业的持续发展,黄土高原人口不断增加,在秦汉时期就成为中国的政治和经济中心。如今,随着西部大开发战略的实施,黄土高原地区的经济得到了迅速发展。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-2/part-iv/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年12月第2套真题(整卷).pdf", + "sourceSha256": "5c5180c1bdaac6830724eb71ebb5b920894368d37f72f00986b97aef5cd75b75" + }, + { + "id": "cet6-2022-12-2-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 12, + "set": 2, + "title": "2022 年 12 月 · 第 2 套 · 批判性思维与理性选择", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “In an era of information explosion, it is vitally important to develop the ability to think critically and make rational choices.” You can make statements, give reasons, or cite examples to develop your essay.You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-2/part1/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年12月第2套真题(整卷).pdf", + "sourceSha256": "5c5180c1bdaac6830724eb71ebb5b920894368d37f72f00986b97aef5cd75b75", + "layoutCorrections": [ + { + "original": "ability t o think", + "corrected": "ability to think" + } + ] + }, + { + "id": "cet6-2022-12-3-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 12, + "set": 3, + "title": "2022 年 12 月 · 第 3 套 · 云贵高原", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n云贵高原(the Yunnan-Guizhou Plateau)大部分位于云南、贵州省境内,总面积约50万平方公里,平均海拔2000-4000米,是中国第四大高原。云贵高原西高东低,河流众多,形成了许多又深又陡的峡谷(canyon)。峡谷中许多地方土壤肥沃,非常有利于多种农作物生长。云贵高原独特的自然环境造就了生物和文化的多样性。它是中国森林和矿产资源类型十分丰富的地区,也是古人类起源的重要地区。云贵高原是中国少数民族数量最多的地区,各民族都保留了自己丰富多彩的文化传统。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-3/part-iv/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年12月第3套真题(整卷).pdf", + "sourceSha256": "cbe473e741288cec78ccb819d52d790cc2b276ea367280050ca7f77c385f61b5" + }, + { + "id": "cet6-2022-12-3-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 12, + "set": 3, + "title": "2022 年 12 月 · 第 3 套 · 大学生团队精神", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence“Today increasing importance is being attached to cultivating college students' team spirit.” You can make statements, give reasons, or cite examples to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-12-3/part1/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年12月第3套真题(整卷).pdf", + "sourceSha256": "cbe473e741288cec78ccb819d52d790cc2b276ea367280050ca7f77c385f61b5", + "layoutCorrections": [ + { + "original": "students'team", + "corrected": "students' team" + } + ] + }, + { + "id": "cet6-2022-09-1-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 9, + "set": 1, + "title": "2022 年 9 月 · 第 1 套 · 春联", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n贴春联(Spring Festival couplets)是中国人欢度春节的一个重要习俗。春联由一对诗句和四字横批(horizontal scroll)组成,诗句和横批用金色或黑色写在红纸上,红色代表幸运,金色代表财富。春联贴在大门左右两侧和门框上方。春联的诗句体现中国传统诗词的特点,两句诗的字数相同、内容相关。横批凸显春联的主题,更是锦上添花。春联以简洁的文字描绘生动的形象,抒发美好的愿望。当家家户户贴春联时,人们就会意识到春节己经正式拉开序幕。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-1/part-iv/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年9月第1套真题(整卷).pdf", + "sourceSha256": "b293727f6f3f589142276a5602e2985d073c2ba87fa32fc198d2b51954185016" + }, + { + "id": "cet6-2022-09-1-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 9, + "set": 1, + "title": "2022 年 9 月 · 第 1 套 · 数字技能", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “Nowadays more and more students are becoming increasingly aware of the importance of developing digital skills.” You can make comments, cite examples or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-1/part1/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年9月第1套真题(整卷).pdf", + "sourceSha256": "b293727f6f3f589142276a5602e2985d073c2ba87fa32fc198d2b51954185016" + }, + { + "id": "cet6-2022-09-2-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 9, + "set": 2, + "title": "2022 年 9 月 · 第 2 套 · 印章", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n自古以来,印章在中国就是身份的凭证和权力的象征。印章不仅具有实用性,而且也是一种艺术形式,是一门集书法与雕刻于一体的古老艺术,经常被看作与书画并列的独立艺术品。印章从材料的选择、制作的工艺到字体的设计,都具有极其丰富的美学表现。其他国家的艺术家通常在其绘画作品上签名,而中国艺术家则往往在其书画作品上盖上印章代替签名。这样,印章也就成为作品的组成部分,是体现作品独特性的一种方式。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-2/part-iv/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年9月第2套真题(整卷).pdf", + "sourceSha256": "b05f9e8b07413bedfee2092128d744dc339b13827b5fb87b8d5039910ec1cc6b" + }, + { + "id": "cet6-2022-09-2-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 9, + "set": 2, + "title": "2022 年 9 月 · 第 2 套 · 现实社交的乐趣", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “Today more and more people begin to realize the pleasures and joys of real-world social interaction.” You can make comments, cite examples or use your personal experiences to develop your essay.You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-2/part1/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年9月第2套真题(整卷).pdf", + "sourceSha256": "b05f9e8b07413bedfee2092128d744dc339b13827b5fb87b8d5039910ec1cc6b" + }, + { + "id": "cet6-2022-09-3-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 9, + "set": 3, + "title": "2022 年 9 月 · 第 3 套 · 中央电视台总部大楼", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n中央电视台总部大楼位于北京市朝阳区,总建筑面积约55万平方米。主楼由两座塔楼组成,因其独特的造型,成为这座城市的一个热门景点,每天都吸引众多游客前来参观。大楼的创新结构是中外建筑师长期合作的成果,不仅体现了环保意识,而且大大节约了建筑材料。中央电视台总部设有一条穿过大楼的专用通道,向公众展示各个工作室以及中央电视台的历史。在那里,参观者还可以看到故宫和北京其他地方的壮观景色。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-3/part-iv/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年9月第3套真题(整卷).pdf", + "sourceSha256": "bd39c8b670fe4246aa95c5f71a3db6a13756fa9a6c35aee6960484aec535ca95" + }, + { + "id": "cet6-2022-09-3-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 9, + "set": 3, + "title": "2022 年 9 月 · 第 3 套 · 信任开放与合作", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “It is now widely accepted that mutual trust and openness is the key to promoting cooperation.” You can make comments, cite examples, or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-09-3/part1/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年9月第3套真题(整卷).pdf", + "sourceSha256": "bd39c8b670fe4246aa95c5f71a3db6a13756fa9a6c35aee6960484aec535ca95", + "layoutCorrections": [ + { + "original": "sen tence", + "corrected": "sentence" + }, + { + "original": "comments,cite", + "corrected": "comments, cite" + } + ] + }, + { + "id": "cet6-2022-06-1-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 6, + "set": 1, + "title": "2022 年 6 月 · 第 1 套 · 卢沟桥", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n卢沟桥位于天安门广场西南15公里处,横跨永定河,是北京现存最古老的多拱石桥。卢沟桥最初建成于1192年,1698年重建,由281根柱子支撑。每根柱子上都有一头石狮。这些石狮的头、背、腹部或爪子上都藏着更多的狮子。这些石狮生动逼真、千姿百态,是卢沟桥石刻艺术的精品。桥上的石狮不计其数,因而北京地区流传着\"卢沟桥上的石狮子——数不清\"的说法。卢沟桥不仅以其美学特征闻名于世,还被公认为石桥建筑史上的一座丰碑。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-1/part-iv/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年6月第1套真题(整卷).pdf", + "sourceSha256": "afd3589d7341ed81113c427789c32f26325bf775a8f0775d92bd682828785872" + }, + { + "id": "cet6-2022-06-1-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 6, + "set": 1, + "title": "2022 年 6 月 · 第 1 套 · 环保生活方式", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “Nowadays more and more people choose to live an environmentally friendly lifestyle.” You can make comments, cite examples, or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-1/part1/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年6月第1套真题(整卷).pdf", + "sourceSha256": "afd3589d7341ed81113c427789c32f26325bf775a8f0775d92bd682828785872" + }, + { + "id": "cet6-2022-06-2-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 6, + "set": 2, + "title": "2022 年 6 月 · 第 2 套 · 南京长江大桥", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n南京长江大桥是长江上首座由中国设计、采用国产材料建造的铁路、公路两用桥,上层的4车道公路桥长4589米,下层的双轨道铁路桥长6772米。铁路桥连接原来的天津一浦口和上海―南京两条铁路线,使火车过江从过去一个半小时缩短为现在的2分钟。大桥是南北交通的重要枢纽,也是南京的著名景点之一。南京长江大桥的建成标志着中国桥梁建设的一个飞跃,大大方便了长江两岸的物资交流和人员来往,对促进经济发展和改善人民生活起到了巨大作用。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-2/part-iv/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年6月第2套真题(整卷).pdf", + "sourceSha256": "239d837f362613a61ca46a0c9fa9e24312d6bfd8b4e834eeeaaa5a566451ef74" + }, + { + "id": "cet6-2022-06-2-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 6, + "set": 2, + "title": "2022 年 6 月 · 第 2 套 · 学习新技能", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “Nowadays more and more people keep learning new skills to adapt to a fast-changing world.” You can make comments, cite examples, or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-2/part1/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年6月第2套真题(整卷).pdf", + "sourceSha256": "239d837f362613a61ca46a0c9fa9e24312d6bfd8b4e834eeeaaa5a566451ef74" + }, + { + "id": "cet6-2022-06-3-cet6Translation", + "task": "cet6Translation", + "year": 2022, + "month": 6, + "set": 3, + "title": "2022 年 6 月 · 第 3 套 · 赵州桥", + "prompt": "Directions: For this part, you are allowed 30 minutes to translate a passage from Chinese into English. You should write your answer on Answer Sheet 2.\n\n赵州桥建于隋朝,公元605年左右,长50.82米,宽9.6米,跨度37.37米。天才建筑师李春设计并监督了桥的建设。赵州桥结构新颖、造型优美。桥有一个大拱,在大拱的两端有两个小拱,帮助排泄洪水、减轻桥梁重量并节省石材。建成以来,该桥经受了多次洪水和地震,但其主体结构仍然完好无损,至今仍在使用。赵州桥是世界桥梁建筑史上的一次创举,是中国古代文明史上的一项杰出成就。类似设计的桥梁直到14世纪才在欧洲出现,比赵州桥晚了700多年。", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-3/part-iv/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年6月第3套真题(整卷).pdf", + "sourceSha256": "eeb5cdb594e1f68aaeca8c294af1e358a19039771b348851b1ab73583075596d" + }, + { + "id": "cet6-2022-06-3-cet6Writing", + "task": "cet6Writing", + "year": 2022, + "month": 6, + "set": 3, + "title": "2022 年 6 月 · 第 3 套 · 帮助有需要的人", + "prompt": "Directions: For this part, you are allowed 30 minutes to write an essay that begins with the sentence “Nowadays more and more people take delight in offering help to the needy.” You can make comments, cite examples, or use your personal experiences to develop your essay. You should write at least 150 words but no more than 200 words.", + "sourceUrl": "https://english-exam.lazynote.cn/cet6/sections/2022-06-3/part1/", + "verification": "providedDocument", + "sourceFile": "2022/英语六级2022年6月第3套真题(整卷).pdf", + "sourceSha256": "eeb5cdb594e1f68aaeca8c294af1e358a19039771b348851b1ab73583075596d" + } + ] +} diff --git a/Shared/QuestionBank/cet6-import-audit.json b/Shared/QuestionBank/cet6-import-audit.json new file mode 100644 index 0000000..449720e --- /dev/null +++ b/Shared/QuestionBank/cet6-import-audit.json @@ -0,0 +1,370 @@ +{ + "source": "User-provided local PDF and DOCX files", + "paperCount": 33, + "questionCount": 66, + "papers": [ + { + "year": 2022, + "month": 6, + "set": 1, + "pdf": "2022/英语六级2022年6月第1套真题(整卷).pdf", + "pdfSha256": "afd3589d7341ed81113c427789c32f26325bf775a8f0775d92bd682828785872", + "docxSha256": "16c010cb1b6b675dbb327eaa10bcd21b3a95f3386dceb9bc6cdea24d3c1e8bce", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 345, + "translationLength": 356 + }, + { + "year": 2022, + "month": 6, + "set": 2, + "pdf": "2022/英语六级2022年6月第2套真题(整卷).pdf", + "pdfSha256": "239d837f362613a61ca46a0c9fa9e24312d6bfd8b4e834eeeaaa5a566451ef74", + "docxSha256": "c904a10d9cfd3cf0dc5b249b1eafd10dca86df2bc78bd79f71b1a9b08ac3cba8", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 351, + "translationLength": 360 + }, + { + "year": 2022, + "month": 6, + "set": 3, + "pdf": "2022/英语六级2022年6月第3套真题(整卷).pdf", + "pdfSha256": "eeb5cdb594e1f68aaeca8c294af1e358a19039771b348851b1ab73583075596d", + "docxSha256": "39b7c5729861b4fbd40cb13f11d848d3fe1e239739136756eee80ddd7b68d9ce", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 335, + "translationLength": 367 + }, + { + "year": 2022, + "month": 9, + "set": 1, + "pdf": "2022/英语六级2022年9月第1套真题(整卷).pdf", + "pdfSha256": "b293727f6f3f589142276a5602e2985d073c2ba87fa32fc198d2b51954185016", + "docxSha256": "097e8c96c4acbf3308a4da2859bda1859b1d1356bc255a2a722d106363797224", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 372, + "translationLength": 379 + }, + { + "year": 2022, + "month": 9, + "set": 2, + "pdf": "2022/英语六级2022年9月第2套真题(整卷).pdf", + "pdfSha256": "b05f9e8b07413bedfee2092128d744dc339b13827b5fb87b8d5039910ec1cc6b", + "docxSha256": "71a774a4b260f2216bd8409c96cb891dca8be42e1d67a1e06d827c4720445ac8", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 360, + "translationLength": 343 + }, + { + "year": 2022, + "month": 9, + "set": 3, + "pdf": "2022/英语六级2022年9月第3套真题(整卷).pdf", + "pdfSha256": "bd39c8b670fe4246aa95c5f71a3db6a13756fa9a6c35aee6960484aec535ca95", + "docxSha256": "273f13945baf437527e9e761a42896b095e9afc8c94b719280f1c8d1a9b05d74", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 355, + "translationLength": 342 + }, + { + "year": 2022, + "month": 12, + "set": 1, + "pdf": "2022/英语六级2022年12月第1套真题(整卷).pdf", + "pdfSha256": "025f979c61abef94b263d05cd77386f46a29a9b87c30220a9c7911f7eae3acab", + "docxSha256": "da6d5956d85cde6ec965cbc005facfd0016b8022f52896ae260172067a747b00", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 373, + "translationLength": 389 + }, + { + "year": 2022, + "month": 12, + "set": 2, + "pdf": "2022/英语六级2022年12月第2套真题(整卷).pdf", + "pdfSha256": "5c5180c1bdaac6830724eb71ebb5b920894368d37f72f00986b97aef5cd75b75", + "docxSha256": "5e1cca33f5e3ed0e70f63bc28405a4177108202e2dff3679218fdbebebdc45b3", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 376, + "translationLength": 391 + }, + { + "year": 2022, + "month": 12, + "set": 3, + "pdf": "2022/英语六级2022年12月第3套真题(整卷).pdf", + "pdfSha256": "cbe473e741288cec78ccb819d52d790cc2b276ea367280050ca7f77c385f61b5", + "docxSha256": "f3fb7cc0c356fe94f7a96eed2d596bff24b41e9112c20eea6ac02949cbaaf92a", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 336, + "translationLength": 391 + }, + { + "year": 2023, + "month": 3, + "set": 1, + "pdf": "2023/英语六级2023年3月第1套真题(整卷).pdf", + "pdfSha256": "b298418c5f2b2a7c6ea0e5f3106293ffd3cd2b9244cae4c93187c0eea7504a30", + "docxSha256": "697aa4420984cc0dc05d65735bf4b00e6d4cff6a00c2ed076c98256205e35136", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 368, + "translationLength": 349 + }, + { + "year": 2023, + "month": 3, + "set": 2, + "pdf": "2023/英语六级2023年3月第2套真题(整卷).pdf", + "pdfSha256": "d00269d42b413bb68ecbe084b598266bb92711abc3a75141c54420835bb1d1b3", + "docxSha256": "7b77fd95990fb918052eed2ffa876b24aae411ca6f306a44aac4334c516293c1", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 367, + "translationLength": 343 + }, + { + "year": 2023, + "month": 3, + "set": 3, + "pdf": "2023/英语六级2023年3月第3套真题(整卷).pdf", + "pdfSha256": "72f8826adab1b33f9cb8795eabe115fadb7b36e39d6a8648ac0d9f19e978c6ec", + "docxSha256": "93ba686d25bb5c3eb646d26399c1008152518b50088f2dde08ae3cca18ec96e2", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 355, + "translationLength": 348 + }, + { + "year": 2023, + "month": 6, + "set": 1, + "pdf": "2023/英语六级2023年6月第1套真题(整卷).pdf", + "pdfSha256": "45b2f3e738065e1729f5882eb4f185ab431290446710c3b847c24621a2aedbb1", + "docxSha256": "efd968e40167f4e79fa4e1939e1d12cb12f9761233e0a3e38457dd527e16684f", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 373, + "translationLength": 350 + }, + { + "year": 2023, + "month": 6, + "set": 2, + "pdf": "2023/英语六级2023年6月第2套真题(整卷).pdf", + "pdfSha256": "0816c073830aeef48a9896a526e65d2a621215010acf5511754b7cb54fe0504b", + "docxSha256": "fc5864c7e9e73bd61425bc7f41a5a8b8c9703f5214bdf950b690822436839217", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 416, + "translationLength": 341 + }, + { + "year": 2023, + "month": 6, + "set": 3, + "pdf": "2023/英语六级2023年6月第3套真题(整卷).pdf", + "pdfSha256": "8ed7812347fba15b99ceb23916e020054d9ae444558e16a5e7e53f45350293d0", + "docxSha256": "46c89d2b3839164949ef01b574528567d0984b056a311b25954212a019df9ff7", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 358, + "translationLength": 340 + }, + { + "year": 2023, + "month": 12, + "set": 1, + "pdf": "2023/英语六级2023年12月第1套真题(整卷).pdf", + "pdfSha256": "ae0ce2b9900a3c68bfe2eea3eb150ece6c349db4e11cd6dd90b3788255d4cfa9", + "docxSha256": "f32b78def280331195913e8c10cf64805a93f92a33cf9412f993011baf5cab9f", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 421, + "translationLength": 342 + }, + { + "year": 2023, + "month": 12, + "set": 2, + "pdf": "2023/英语六级2023年12月第2套真题(整卷).pdf", + "pdfSha256": "7e4c39c2f55d8c8f85cacec51dd429a699ab05ac808ba7aee28f84cbebfb317e", + "docxSha256": "956a2bb12c253d6932ff41e99679484cd61af2e2a024b80946fd6f80b8cf80cd", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 459, + "translationLength": 359 + }, + { + "year": 2023, + "month": 12, + "set": 3, + "pdf": "2023/英语六级2023年12月第3套真题(整卷).pdf", + "pdfSha256": "20deb499f923bf14978f579c88dcf2fe0f4cb3e742131593d8d469fb41fe9275", + "docxSha256": "fe2e367aff2caef33988d7195223e21968965a0741f08e793178249edb372a64", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 377, + "translationLength": 346 + }, + { + "year": 2024, + "month": 6, + "set": 1, + "pdf": "2024/英语六级2024年6月第1套真题(整卷).pdf", + "pdfSha256": "f6cd11c8f5c99d480ae98072345c4ee2e9b6a29ab5f21d6a5f35761f35f9bc8f", + "docxSha256": "bfc1509205925473f93b617eb7b683a79badd7024b1cecd90c1291020f5f1ee3", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 449, + "translationLength": 374 + }, + { + "year": 2024, + "month": 6, + "set": 2, + "pdf": "2024/英语六级2024年6月第2套真题(整卷).pdf", + "pdfSha256": "eed58359d56438ec081d3ac1c2978d2cd1bfddf812f7c3a14c57ecb86347af09", + "docxSha256": "7ea5a6e1c5da3d04a2337051940f3d497eecc9233a4e87f71ef899835cd0d045", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 461, + "translationLength": 354 + }, + { + "year": 2024, + "month": 6, + "set": 3, + "pdf": "2024/英语六级2024年6月第3套真题(整卷).pdf", + "pdfSha256": "e2cdb42a70d183a59326d151ab021d531c5788ebf13f7e4858e54a969c5388c4", + "docxSha256": "d7255e84666016caab2d60db9b9743258f2bd01bd437289a29059b1c34e6c220", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 436, + "translationLength": 346 + }, + { + "year": 2024, + "month": 12, + "set": 1, + "pdf": "2024/英语六级2024年12月第1套真题(整卷).pdf", + "pdfSha256": "70956c7b81b3ba3f137e98ac4b46ce254309def0b20c2b7a1745266e31a4efec", + "docxSha256": "8a661e2ef3ffbe201719dfba165cba68a3078564abc6751d0d606fa759364a20", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 442, + "translationLength": 342 + }, + { + "year": 2024, + "month": 12, + "set": 2, + "pdf": "2024/英语六级2024年12月第2套真题(整卷).pdf", + "pdfSha256": "3d09b2104bf8f9b0f5f46e080d34bda5e9d2d81ffb2b88513b39faee1d144cfa", + "docxSha256": "3cb524e67de8a193b3dda39c47768a92ae2adae7f41384116a216d3f5b4b71ad", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 443, + "translationLength": 357 + }, + { + "year": 2024, + "month": 12, + "set": 3, + "pdf": "2024/英语六级2024年12月第3套真题(整卷).pdf", + "pdfSha256": "445484a4480b5e7429065087013209e7d93251a0bf4ab8a58def5b17c4ff635c", + "docxSha256": "277f4c813eb8bc56c1980902b6a9f39800981d321f986e7714f1299a500e2f7b", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 460, + "translationLength": 354 + }, + { + "year": 2025, + "month": 6, + "set": 1, + "pdf": "2025/英语六级2025年6月第1套真题(整卷).pdf", + "pdfSha256": "964aedfc1a34d085d64c5f0ffd7158788bed652071c64c3b29ea810bbdd00155", + "docxSha256": "c997f7e3080fdf71bee0af103d37a9f46abeeb41cf535e9c0e17e63dfa4707ac", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 477, + "translationLength": 385 + }, + { + "year": 2025, + "month": 6, + "set": 2, + "pdf": "2025/英语六级2025年6月第2套真题(整卷).pdf", + "pdfSha256": "cd0c60961faa8f2cde89a8bbd5f95b57d4cd55b277accf478198d66d5981eb5a", + "docxSha256": "3a5dd5e18c803044804b1d50c14c891ceebbb549b9fa17eb90efebdba293482d", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 473, + "translationLength": 393 + }, + { + "year": 2025, + "month": 6, + "set": 3, + "pdf": "2025/英语六级2025年6月第3套真题(整卷).pdf", + "pdfSha256": "7559420e92387bb51a26dc4d0d7de9ae8fc080d7e5d047e53ff354739dcacaf5", + "docxSha256": "ab25d739500c3e41b6e188dae99146b02df857cb1d8a13c3f5945fc349a6a72f", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 462, + "translationLength": 406 + }, + { + "year": 2025, + "month": 12, + "set": 1, + "pdf": "2025/英语六级2025年12月第1套真题(整卷).pdf", + "pdfSha256": "fbb389a72593d61e522c48e17ededbee3005f58890c6db906c55c068c012c1cf", + "docxSha256": "77384d87b4cfa7d6db9e2a04abcb4f1b228df328dee0a70b456fcb2abbe825e1", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 442, + "translationLength": 344 + }, + { + "year": 2025, + "month": 12, + "set": 2, + "pdf": "2025/英语六级2025年12月第2套真题(整卷).pdf", + "pdfSha256": "e3fdfac47463f14b10ed9649ddde6d07439a6188eb9f9b792640196f2ea2dda3", + "docxSha256": "c8f8130154334f16f6cf952e461c9333d24071a68392f1a211758ce5d0d32c94", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 459, + "translationLength": 360 + }, + { + "year": 2025, + "month": 12, + "set": 3, + "pdf": "2025/英语六级2025年12月第3套真题(整卷).pdf", + "pdfSha256": "22d68e1174049930a97df672710bd8aed39097591ebe09d8c009ba1a7c884791", + "docxSha256": "e49dd204e9e8c8701758685966fed67ccefdc27bf43ed563538624ad25c70729", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 464, + "translationLength": 351 + }, + { + "year": 2026, + "month": 6, + "set": 1, + "pdf": "2026/英语六级2026年6月第1套真题(整卷).pdf", + "pdfSha256": "0df76248c652e977c6289e80d3aa42b0757e28060c603c901a5a654004f300a0", + "docxSha256": "46c16f8dda7fdc7c305d287ae88385b22016839e2ccdb21d365bef0544eae8fd", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 451, + "translationLength": 337 + }, + { + "year": 2026, + "month": 6, + "set": 2, + "pdf": "2026/英语六级2026年6月第2套真题(整卷).pdf", + "pdfSha256": "2411b6f58b774603ae274896642f44fdc73cb71b4976da519617d0b31e746125", + "docxSha256": "c7781ce7553844cb86572455811abbd07684c5dfd9334d25fad3aa05b1890284", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 451, + "translationLength": 364 + }, + { + "year": 2026, + "month": 6, + "set": 3, + "pdf": "2026/英语六级2026年6月第3套真题(整卷).pdf", + "pdfSha256": "72f20ebafe95c79bb06edf42adaca7d7b6ba59528e68ffb26f3ef86d600749e1", + "docxSha256": "d56ec35871c2b710c68cd5f01b97e44ff9760ba10ef4abe397e1f9d7bb5e0516", + "crossCheck": "PDF and DOCX match after whitespace normalization", + "writingLength": 481, + "translationLength": 371 + } + ] +} diff --git a/WriteBench.xcodeproj/project.pbxproj b/WriteBench.xcodeproj/project.pbxproj index 9e20957..4580694 100644 --- a/WriteBench.xcodeproj/project.pbxproj +++ b/WriteBench.xcodeproj/project.pbxproj @@ -29,13 +29,13 @@ 473B2ECB957707EDB2BF41AA /* BackgroundGradingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8E73D997ED19A98227B24C /* BackgroundGradingView.swift */; }; 4B7B1CDF7FADBE73B96E26DA /* kaoyan_english1_translation.md in Resources */ = {isa = PBXBuildFile; fileRef = AD3CEB6EC11C595CA1EA79D6 /* kaoyan_english1_translation.md */; }; 51899521D61CB025A5559EC5 /* LocalProcessRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 100F5B726342F502CA8C4207 /* LocalProcessRunner.swift */; }; - 52D947565422EE245913DE21 /* cet6-2022-2026-index.json in Resources */ = {isa = PBXBuildFile; fileRef = 63ABA3E9807196933476EF75 /* cet6-2022-2026-index.json */; }; 5317F309ED9004BD4665C0DC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 37444757CFEC8F67705A2D6C /* Assets.xcassets */; }; 54D5279B986C5DBEA37BA5C7 /* OCRConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54C82E0AE1ACA592616CDDB /* OCRConfirmationView.swift */; }; 55C7907B2F577F01BC57A08B /* ReviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F9DB3748FBE72E213C6EB37 /* ReviewView.swift */; }; 55E01FD08D907D18E2AFCBFC /* WritingStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00C1A68BA4227431C3B8884 /* WritingStore.swift */; }; 57B1584FB0F0DC411801C7D5 /* WritingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3788E5EB782131E544DDEDC /* WritingView.swift */; }; 611D1CBBEE2017C06DCD6D8D /* GradingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 634F608AF0DF72D3DE51E438 /* GradingService.swift */; }; + 6A2D61FFBE7F968DBCFB1164 /* cet6-2022-2026.json in Resources */ = {isa = PBXBuildFile; fileRef = 445C1E2A61051C152970E26E /* cet6-2022-2026.json */; }; 6C1F7BEC5994E87DFA1CEF27 /* DeepSeekClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = A399A503863E6199B340A50C /* DeepSeekClient.swift */; }; 6C3E278AD86905C7C0A63BCE /* QuestionText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0DD31CC0B614898B36ED76 /* QuestionText.swift */; }; 6EF13FD59119BAB281533752 /* TranslationLessonCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11CD6DC48ADA2A2066B58A3 /* TranslationLessonCard.swift */; }; @@ -119,6 +119,7 @@ 405A85F2A07E72B5AD277D96 /* ielts_task1.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = ielts_task1.md; sourceTree = ""; }; 419DE9ABE9E26F14128B9B1E /* HistoryFolderEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryFolderEditor.swift; sourceTree = ""; }; 4391A8E13E5C7A35D0A1467A /* MistakesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MistakesView.swift; sourceTree = ""; }; + 445C1E2A61051C152970E26E /* cet6-2022-2026.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "cet6-2022-2026.json"; sourceTree = ""; }; 4BCC37FAB6E0DDC543B0D48B /* DeepSeekStreaming.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepSeekStreaming.swift; sourceTree = ""; }; 4FAD6385C4872B3E80D4B00C /* CETQuestionBankTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CETQuestionBankTests.swift; sourceTree = ""; }; 51A76CC13C7CABACEC80CBAE /* WindowImmersionBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowImmersionBridge.swift; sourceTree = ""; }; @@ -126,7 +127,6 @@ 5AEB65E44D0601AEC6053865 /* Exam.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Exam.swift; sourceTree = ""; }; 6211317C38F78901403EE347 /* TranslationLesson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslationLesson.swift; sourceTree = ""; }; 634F608AF0DF72D3DE51E438 /* GradingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradingService.swift; sourceTree = ""; }; - 63ABA3E9807196933476EF75 /* cet6-2022-2026-index.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "cet6-2022-2026-index.json"; sourceTree = ""; }; 650B4D62F506EDDC71D6396A /* cet6_writing.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = cet6_writing.md; sourceTree = ""; }; 679F1D25813DBB4821B089EF /* WriteBenchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteBenchTests.swift; sourceTree = ""; }; 6A7B637179FC6E271F31DBF4 /* kaoyan_english1_small.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = kaoyan_english1_small.md; sourceTree = ""; }; @@ -279,7 +279,7 @@ 85C04166008095CC4B9B2FA4 /* QuestionBank */ = { isa = PBXGroup; children = ( - 63ABA3E9807196933476EF75 /* cet6-2022-2026-index.json */, + 445C1E2A61051C152970E26E /* cet6-2022-2026.json */, ); name = QuestionBank; path = Shared/QuestionBank; @@ -537,7 +537,7 @@ buildActionMask = 2147483647; files = ( 5317F309ED9004BD4665C0DC /* Assets.xcassets in Resources */, - 52D947565422EE245913DE21 /* cet6-2022-2026-index.json in Resources */, + 6A2D61FFBE7F968DBCFB1164 /* cet6-2022-2026.json in Resources */, 361B2B881C01F86CC3A784DC /* cet6_translation.md in Resources */, D3F29CFA674B891722D5B739 /* cet6_writing.md in Resources */, DEBA962949C4AADDFCB2C5D0 /* ielts_task1.md in Resources */, @@ -692,7 +692,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 16; + CURRENT_PROJECT_VERSION = 17; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_HARDENED_RUNTIME = YES; ENABLE_NS_ASSERTIONS = NO; @@ -707,7 +707,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 15.0; - MARKETING_VERSION = 1.9.1; + MARKETING_VERSION = 1.9.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -788,7 +788,7 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 16; + CURRENT_PROJECT_VERSION = 17; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_HARDENED_RUNTIME = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -809,7 +809,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 15.0; - MARKETING_VERSION = 1.9.1; + MARKETING_VERSION = 1.9.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; diff --git a/WriteBench/Features/Writing/QuestionLibraryView.swift b/WriteBench/Features/Writing/QuestionLibraryView.swift index 5445956..dcaa7be 100644 --- a/WriteBench/Features/Writing/QuestionLibraryView.swift +++ b/WriteBench/Features/Writing/QuestionLibraryView.swift @@ -44,7 +44,7 @@ struct QuestionLibraryView: View { Item(id: $0.id.uuidString, task: currentTask, title: $0.title, prompt: $0.prompt, image: $0.image, year: $0.year, label: $0.label, saved: $0) } case .cet: all = cetEntries.filter { $0.task == currentTask.rawValue }.map { - Item(id: $0.id, task: currentTask, title: $0.title, prompt: $0.prompt, year: $0.year, label: $0.hasPrompt ? "用户导入 · 可练习" : "第三方来源索引 · 无正文", sourceURL: URL(string: $0.sourceUrl)) + Item(id: $0.id, task: currentTask, title: $0.title, prompt: $0.prompt, year: $0.year, label: $0.hasPrompt ? ($0.verification == "providedDocument" ? "真题 · 已从文件核对" : "用户导入 · 可练习") : "第三方来源索引 · 无正文", sourceURL: URL(string: $0.sourceUrl)) } } let query = search.trimmingCharacters(in: .whitespacesAndNewlines) @@ -58,7 +58,7 @@ struct QuestionLibraryView: View { let index = practiceIndex, visible = items(index) VStack(alignment: .leading, spacing: 16) { HStack { - SectionHeading(title: "题库", subtitle: "内置题目均为原创练习;导入或识别的题目可保存到我的题库。") + SectionHeading(title: "题库", subtitle: "原创练习与近五年六级真题;导入或识别的题目可保存到我的题库。") Spacer() IconButton(symbol: "xmark", help: "Close") { dismiss() } } @@ -85,7 +85,7 @@ struct QuestionLibraryView: View { }.padding(10).background(.white, in: RoundedRectangle(cornerRadius: 10)).overlay(RoundedRectangle(cornerRadius: 10).stroke(WB.line)) if store.task.exam == .cet6 { HStack { - Text("2022–2026 · 有正文才能练习;套次沿用来源编号。").font(.system(size: 12)).foregroundStyle(WB.secondary) + Text("2022–2026 · 写作、翻译各 33 题 · 套次沿用资料编号。").font(.system(size: 12)).foregroundStyle(WB.secondary) Spacer() Button("批量导入题库 JSON") { importCETBank() }.buttonStyle(QuietButtonStyle()) } @@ -106,7 +106,7 @@ struct QuestionLibraryView: View { } if source == .saved { saveBar } if let error { Text(error).foregroundStyle(WB.amber).font(.system(size: 12)) } - }.padding(28).frame(width: 900, height: 640).background(WB.canvas).onAppear { reloadCETBank() } + }.padding(28).frame(width: 900, height: 640).background(WB.canvas).onAppear { reloadCETBank(); if store.task.exam == .cet6 { source = .cet } } } private func reloadCETBank() { do { cetEntries = try CETQuestionBank.entries() } catch { self.error = error.localizedDescription } diff --git a/WriteBench/Features/Writing/WritingView.swift b/WriteBench/Features/Writing/WritingView.swift index 956f230..4a3cf76 100644 --- a/WriteBench/Features/Writing/WritingView.swift +++ b/WriteBench/Features/Writing/WritingView.swift @@ -124,7 +124,9 @@ struct WritingView: View { } private func randomQuestion() { let index = PracticeIndex(sessions), current = QuestionBank.key(store.question) - let candidates = QuestionBank.questions(for: store.task).filter { QuestionBank.key($0.prompt) != current } + let bank = QuestionBank.questions(for: store.task) + let real = bank.filter { $0.id.hasPrefix("cet6-") } + let candidates = (real.isEmpty ? bank : real).filter { QuestionBank.key($0.prompt) != current } guard let pick = candidates.filter({ index.attempts($0.task, $0.prompt).isEmpty }).randomElement() ?? candidates.randomElement() else { return } store.useQuestion(pick.prompt, title: pick.title, task: pick.task) } diff --git a/WriteBench/Models/CETQuestionBank.swift b/WriteBench/Models/CETQuestionBank.swift index 5b18279..7704831 100644 --- a/WriteBench/Models/CETQuestionBank.swift +++ b/WriteBench/Models/CETQuestionBank.swift @@ -26,7 +26,7 @@ struct CETBankDocument: Codable, Sendable { let date = calendar.date(from: DateComponents(year: item.year, month: item.month, day: 1)), date <= now, !item.title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty, item.prompt.count <= 100_000, let url = URL(string: item.sourceUrl), ["https", "http"].contains(url.scheme ?? ""), url.host != nil, - ["sourceIndex", "userImported"].contains(item.verification) + ["sourceIndex", "userImported", "providedDocument"].contains(item.verification) else { throw CETBankError.invalid("题目 \(item.id) 的年份、题型、套次、来源或标识无效") } if requirePrompts && !item.hasPrompt { throw CETBankError.invalid("题目 \(item.title) 只有来源索引,没有正文,不能作为练习题导入") } } @@ -44,7 +44,7 @@ enum CETQuestionBank { return try JSONDecoder().decode(CETBankDocument.self, from: data).validated(requirePrompts: requirePrompts) } static func entries(storage: URL = storage) throws -> [CETBankEntry] { - guard let url = Bundle.main.url(forResource: "cet6-2022-2026-index", withExtension: "json") else { throw CETBankError.invalid("内置来源索引未找到") } + guard let url = Bundle.main.url(forResource: "cet6-2022-2026", withExtension: "json") else { throw CETBankError.invalid("内置来源索引未找到") } let base = try decode(Data(contentsOf: url), requirePrompts: false) let custom = FileManager.default.fileExists(atPath: storage.path) ? try decode(Data(contentsOf: storage), requirePrompts: true) : [] var values = Dictionary(uniqueKeysWithValues: base.map { ($0.id, $0) }) diff --git a/WriteBenchTests/CETQuestionBankTests.swift b/WriteBenchTests/CETQuestionBankTests.swift index 3a3d176..b1e1b03 100644 --- a/WriteBenchTests/CETQuestionBankTests.swift +++ b/WriteBenchTests/CETQuestionBankTests.swift @@ -8,13 +8,15 @@ private func entry(_ id: String = "fixture", prompt: String = "Write an essay ab private func bankData(_ entries: [CETBankEntry], version: Int = 1) throws -> Data { try JSONEncoder().encode(CETBankDocument(schemaVersion: version, questions: entries)) } -@Test func cetSourceIndexCoverage() throws { +@Test func cetProvidedPaperCoverage() throws { let folder = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) let entries = try CETQuestionBank.entries(storage: folder.appendingPathComponent("empty.json")) #expect(entries.count == 66) #expect(entries.filter { $0.task == "cet6Writing" }.count == 33) #expect(entries.filter { $0.task == "cet6Translation" }.count == 33) - #expect(entries.allSatisfy { !$0.hasPrompt && $0.verification == "sourceIndex" }) + #expect(entries.allSatisfy { $0.hasPrompt && $0.verification == "providedDocument" }) + #expect(Set(entries.map(\.prompt)).count == 66) + #expect(entries.allSatisfy { $0.prompt.hasPrefix("Directions:") && !$0.prompt.contains("懒笔记") && !$0.prompt.contains("参考范文") }) #expect(entries.contains { $0.year == 2022 && $0.month == 9 }) #expect(entries.contains { $0.year == 2023 && $0.month == 3 }) #expect(!entries.contains { $0.year == 2026 && $0.month == 12 }) diff --git a/platforms/windows/README.md b/platforms/windows/README.md index f6a718d..b5bc228 100644 --- a/platforms/windows/README.md +++ b/platforms/windows/README.md @@ -1,4 +1,4 @@ -# WriteBench for Windows 1.9.1 +# WriteBench for Windows 1.9.2 Native WPF / C# application, .NET 10, self-contained Windows x64. Extract the entire ZIP and run `WriteBench.exe`; keep all adjacent files and OCR data together. No separate .NET installation is required. @@ -22,9 +22,9 @@ OCR uses bundled Tesseract English/Simplified Chinese models. On a clean Windows ## Validation and limitations -The release workflow publishes on a real GitHub-hosted Windows runner, starts the published executable, checks domain/scoring/rejection, format retries, interrupted streams, DPAPI persistence/forgetting, timer pause/resume, actual WPF editor alignment/undo/Tab/progress, and real OCR. It renders preparation, settings and answer-sheet screens for visual inspection. Tests use deterministic provider fixtures, not paid live grading requests. +The release workflow publishes on a real GitHub-hosted Windows runner, starts the published executable, checks domain/scoring/rejection, format retries, interrupted streams, DPAPI persistence/forgetting, timer pause/resume, actual WPF editor alignment/undo/Tab/progress, and real OCR. It also validates the 66-question full-text CET-6 bank, transactional imports and native library screen, and renders preparation, settings, answer-sheet and CET-6-library screens for visual inspection. Tests use deterministic provider fixtures, not paid live grading requests. -This automated coverage does not replace manual Windows 11 checks of screen scaling, physical keyboard shortcuts, window switching, network/proxy configurations, or a live grading account. The portable application is not Authenticode-signed. Windows currently provides eight task presets and does not yet include every macOS workflow (such as the expanded question bank and unified synthesized review). +This automated coverage does not replace manual Windows 11 checks of screen scaling, physical keyboard shortcuts, window switching, network/proxy configurations, or a live grading account. The portable application is not Authenticode-signed. Windows provides eight task presets and the shared 2022–2026 CET-6 full-text bank (33 writing and 33 translation questions). Other expanded macOS question banks and the unified synthesized review are not yet included. ## Build diff --git a/platforms/windows/WriteBench/SelfTest.cs b/platforms/windows/WriteBench/SelfTest.cs index 34df76f..75825f3 100644 --- a/platforms/windows/WriteBench/SelfTest.cs +++ b/platforms/windows/WriteBench/SelfTest.cs @@ -47,7 +47,7 @@ public static async Task Run() var window = new MainWindow(preview: true); window.CheckUI(); var bank = new CETQuestionBank(Path.Combine(Path.GetTempPath(), "WriteBench-bank-test-" + Guid.NewGuid())); var entries = bank.Entries(); - Assert(entries.Length == 66 && entries.Count(e => e.Task == "cet6Writing") == 33 && entries.All(e => !e.HasPrompt), "CET source index incomplete/playable"); + Assert(entries.Length == 66 && entries.Count(e => e.Task == "cet6Writing") == 33 && entries.All(e => e.HasPrompt && e.Verification == "providedDocument"), "CET full-text bank incomplete"); string bankDir = Path.Combine(Path.GetTempPath(), "WriteBench-import-test-" + Guid.NewGuid()); try { var imports = new CETQuestionBank(bankDir); @@ -59,7 +59,7 @@ public static async Task Run() try { imports.Import(Data(sample with { Prompt = "" })); } catch { invalidRejected = true; } Assert(invalidRejected && before.SequenceEqual(File.ReadAllBytes(Path.Combine(bankDir, "cet6-custom.json"))), "Incomplete bank mutated stored data"); imports.Import(Data(sample with { Prompt = "Updated original practice question." })); - Assert(imports.Entries().Count(e => e.HasPrompt) == 2 && imports.Entries().Single(e => e.Id == sample.Id).Prompt == "Updated original practice question.", "Import update lost other questions"); + Assert(imports.Entries().Count(e => e.Id.StartsWith("fixture-")) == 2 && imports.Entries().Single(e => e.Id == sample.Id).Prompt == "Updated original practice question.", "Import update lost other questions"); foreach (var invalid in new[] { sample with { Task = "kaoyanLarge" }, sample with { SourceUrl = "file:///etc/passwd" }, sample with { Year = 2026, Month = 12 } }) { invalidRejected = false; try { CETQuestionBank.Decode(Data(invalid), true, new DateTime(2026, 10, 3)); } catch { invalidRejected = true; } Assert(invalidRejected, "Invalid bank metadata accepted"); diff --git a/platforms/windows/WriteBench/Services/CETQuestionBank.cs b/platforms/windows/WriteBench/Services/CETQuestionBank.cs index 233b4a3..7e69861 100644 --- a/platforms/windows/WriteBench/Services/CETQuestionBank.cs +++ b/platforms/windows/WriteBench/Services/CETQuestionBank.cs @@ -23,14 +23,14 @@ public static CETBankEntry[] Decode(byte[] data, bool requirePrompts, DateTime? || item.Year < 2022 || item.Year > 2026 || !new[] { 3, 6, 9, 12 }.Contains(item.Month) || item.Set < 1 || item.Set > 3 || new DateTime(item.Year, item.Month, 1) > (now ?? DateTime.Now) || string.IsNullOrWhiteSpace(item.Title) || item.Prompt == null || item.Prompt.Length > 100_000 || !Uri.TryCreate(item.SourceUrl, UriKind.Absolute, out var uri) || !new[] { "http", "https" }.Contains(uri.Scheme) || string.IsNullOrEmpty(uri.Host) - || !new[] { "sourceIndex", "userImported" }.Contains(item.Verification)) throw new Exception("题目年份、题型、套次、来源或标识无效"); + || !new[] { "sourceIndex", "userImported", "providedDocument" }.Contains(item.Verification)) throw new Exception("题目年份、题型、套次、来源或标识无效"); if (requirePrompts && !item.HasPrompt) throw new Exception($"题目 {item.Title} 只有来源索引,没有正文,不能作为练习题导入"); } return document.Questions; } public CETBankEntry[] Entries() { - var bundled = Decode(File.ReadAllBytes(Path.Combine(AppContext.BaseDirectory, "QuestionBank", "cet6-2022-2026-index.json")), false); + var bundled = Decode(File.ReadAllBytes(Path.Combine(AppContext.BaseDirectory, "QuestionBank", "cet6-2022-2026.json")), false); var custom = File.Exists(FileName) ? Decode(File.ReadAllBytes(FileName), true) : []; return bundled.Concat(custom).GroupBy(item => item.Id).Select(group => group.Last()).OrderByDescending(item => item.Year).ThenByDescending(item => item.Month).ThenBy(item => item.Set).ToArray(); } diff --git a/platforms/windows/WriteBench/Views/MainWindow.cs b/platforms/windows/WriteBench/Views/MainWindow.cs index 74c6ef7..094c5c9 100644 --- a/platforms/windows/WriteBench/Views/MainWindow.cs +++ b/platforms/windows/WriteBench/Views/MainWindow.cs @@ -153,9 +153,17 @@ void Render() break; } } + void UseBankQuestion(CETBankEntry entry) + { + if (entry.Prompt != question && !string.IsNullOrWhiteSpace(essay)) { + if (MessageBox.Show(this, "当前已有作答。切换题目会清空当前作答和计时,是否继续?", "WriteBench", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; + essay = ""; writingTimer.Reset(); rewriteID = null; + } + question = entry.Prompt; page = "Write"; SaveDraft(); Render(); + } void CETLibrary() { - Heading("近五年六级题库", "2022–2026 · 来源索引与可练习正文分开显示,套次沿用来源编号。"); + Heading("近五年六级题库", "2022–2026 · 写作、翻译各 33 题 · 套次沿用资料编号。"); content.Children.Add(Button("批量导入题库 JSON", () => { var picker = new OpenFileDialog { Filter = "题库 JSON|*.json" }; if (picker.ShowDialog(this) != true) return; int count = new CETQuestionBank().Import(File.ReadAllBytes(picker.FileName)); Message($"已导入 {count} 道完整题目;同 ID 更新,其余保留。"); Render(); @@ -163,8 +171,8 @@ void CETLibrary() try { foreach (var entry in new CETQuestionBank().Entries().Where(entry => entry.Task == task.Id)) { var card = Card(content); card.Children.Add(Text(entry.Title, 18)); - card.Children.Add(Text(entry.HasPrompt ? "用户导入 · 可练习" : "第三方来源索引 · 未核对正文,不能直接答题", 12, Muted)); - if (entry.HasPrompt) { card.Children.Add(Text(entry.Prompt, 14)); card.Children.Add(Button("使用这道题", () => { question = entry.Prompt; page = "Write"; SaveDraft(); Render(); })); } + card.Children.Add(Text(entry.HasPrompt ? (entry.Verification == "providedDocument" ? "真题 · 已从文件核对" : "用户导入 · 可练习") : "第三方来源索引 · 未核对正文,不能直接答题", 12, Muted)); + if (entry.HasPrompt) { card.Children.Add(Text(entry.Prompt, 14)); card.Children.Add(Button("使用这道题", () => { UseBankQuestion(entry); })); } card.Children.Add(Button("打开来源资料", () => System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(entry.SourceUrl) { UseShellExecute = true }))); } } catch (Exception e) { content.Children.Add(Text(e.Message, 14)); } @@ -176,7 +184,17 @@ void Preparation() foreach (var t in ExamTask.All.Where(t => t.Exam == task.Exam)) sub.Children.Add(Button(t.Title, () => SelectTask(t), t == task)); content.Children.Add(sub); - if (task.Exam == "CET-6 六级") content.Children.Add(Button("近五年六级题库 / 批量导入", () => { page = "CETLibrary"; Render(); })); + if (task.Exam == "CET-6 六级") { + var bankButtons = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 0, 0, 16) }; + bankButtons.Children.Add(Button("随机真题", () => { + var candidates = new CETQuestionBank().Entries().Where(e => e.Task == task.Id && e.HasPrompt && e.Prompt != question).ToArray(); + var seen = store.History().Where(s => s.TaskId == task.Id).Select(s => s.Question).ToHashSet(); + var unpractised = candidates.Where(e => !seen.Contains(e.Prompt)).ToArray(); + var choices = unpractised.Length > 0 ? unpractised : candidates; + if (choices.Length > 0) UseBankQuestion(choices[Random.Shared.Next(choices.Length)]); + })); + bankButtons.Children.Add(Button("近五年六级题库 / 批量导入", () => { page = "CETLibrary"; Render(); })); content.Children.Add(bankButtons); + } var c = Card(content); c.Children.Add(Text("题目 · 原创练习 / 自行导入", 13, Muted)); var q = Input(question, 210); diff --git a/platforms/windows/WriteBench/WriteBench.csproj b/platforms/windows/WriteBench/WriteBench.csproj index c64fb3c..ea42cad 100644 --- a/platforms/windows/WriteBench/WriteBench.csproj +++ b/platforms/windows/WriteBench/WriteBench.csproj @@ -1,4 +1,4 @@ - WinExenet10.0-windowstrueenableenableAssets\WriteBench.icoWriteBench1.9.1falsetruewin-x64 - + WinExenet10.0-windowstrueenableenableAssets\WriteBench.icoWriteBench1.9.2falsetruewin-x64 + diff --git a/project.yml b/project.yml index 8db197c..56ed48c 100644 --- a/project.yml +++ b/project.yml @@ -11,15 +11,15 @@ settings: CODE_SIGN_IDENTITY: "-" ENABLE_HARDENED_RUNTIME: YES GENERATE_INFOPLIST_FILE: YES - MARKETING_VERSION: "1.9.1" - CURRENT_PROJECT_VERSION: "16" + MARKETING_VERSION: "1.9.2" + CURRENT_PROJECT_VERSION: "17" targets: WriteBench: type: application platform: macOS sources: - WriteBench - - path: Shared/QuestionBank/cet6-2022-2026-index.json + - path: Shared/QuestionBank/cet6-2022-2026.json buildPhase: resources settings: base: diff --git a/scripts/import-cet6.py b/scripts/import-cet6.py new file mode 100644 index 0000000..9176d47 --- /dev/null +++ b/scripts/import-cet6.py @@ -0,0 +1,66 @@ +from pathlib import Path +from zipfile import ZipFile +from xml.etree import ElementTree as ET +import subprocess,re,json,hashlib,unicodedata +import argparse +parser=argparse.ArgumentParser(description='Extract user-provided CET-6 writing/translation papers with PDF/DOCX cross-checks.') +parser.add_argument('--source',type=Path,required=True) +args=parser.parse_args() +source=args.source +repo=Path(__file__).resolve().parents[1] +base=json.loads((repo/'Shared/QuestionBank/cet6-2022-2026.json').read_text()) +ns={'w':'http://schemas.openxmlformats.org/wordprocessingml/2006/main'} +def normalize(text): + text=re.sub(r'\s+',' ',text).strip() + # Remove layout-only splits within Chinese words, preserving English word boundaries. + text=re.sub(r'(?<=[\u3400-\u9fff])\s+(?=[\u3400-\u9fff])','',text) + match=re.search(r'[\u3400-\u9fff]',text) + if match: + prefix,body=text[:match.start()].strip(),text[match.start():] + body=re.sub(r'(?100 + assert t.startswith('Directions:') and 'Chinese into English' in t and len(re.findall(r'[\u3400-\u9fff]',t))>100 + assert all(x not in w+t for x in ['懒笔记','参考译文','参考范文','答案解析','Part II','Questions 1']) + for task,prompt in [('cet6Writing',w),('cet6Translation',t)]: + row=next(r for r in base['questions'] if (r['year'],r['month'],r['set'],r['task'])==(year,month,setno,task)) + row['prompt']=prompt + for fix in row.get('layoutCorrections',[]): + if fix['original'] in row['prompt']: row['prompt']=row['prompt'].replace(fix['original'],fix['corrected']) + row['verification']='providedDocument' + row['sourceFile']=str(pdf.relative_to(source));row['sourceSha256']=hashlib.sha256(pdf.read_bytes()).hexdigest() + audit.append(dict(year=year,month=month,set=setno,pdf=str(pdf.relative_to(source)),pdfSha256=hashlib.sha256(pdf.read_bytes()).hexdigest(),docxSha256=hashlib.sha256(docx.read_bytes()).hexdigest(),crossCheck='PDF and DOCX match after whitespace normalization',writingLength=len(w),translationLength=len(t))) +base['questions'].sort(key=lambda r:(-r['year'],-r['month'],r['set'],r['task'])) +(repo/'Shared/QuestionBank/cet6-2022-2026.json').write_text(json.dumps(base,ensure_ascii=False,indent=2)+'\n') +(repo/'Shared/QuestionBank/cet6-import-audit.json').write_text(json.dumps(dict(source='User-provided local PDF and DOCX files',paperCount=len(audit),questionCount=len(base['questions']),papers=audit),ensure_ascii=False,indent=2)+'\n') +print(f'Extracted {len(base["questions"])} questions from {len(audit)} user-provided papers; all PDF/DOCX cross-checks passed.')