# 软考高项时间轴功能 - 需求与初设文档

## 文档信息

- **创建日期**: 2026-03-22
- **模块名称**: 软考高项时间轴 (Timeline)
- **当前阶段**: 第一阶段 - 数据 JSON 设计与整理
- **适用范围**: 软考高项教材中的时间类知识点整理、结构化存储与后续时间轴展示

---

## 1. 背景与目标

### 1.1 背景

当前项目已经形成较成熟的静态数据驱动模式，主要特征包括：

- 使用 `src/data/*.json` 维护结构化知识数据
- 使用 `src/types/*.ts` 或 `src/types/itto.ts` 维护类型定义
- 使用 `src/data/index.ts` 统一导出数据与查询能力
- 页面展示层基于结构化数据进行可视化学习与交互

在此基础上，计划增加一个新的学习功能：

> 将软考高项中的关键时间类知识点整理为统一 JSON 数据，并在后续以时间轴形式进行展示。

该能力本质上不是普通的“历史事件时间线”，而是：

> **按教材主题归类、按显式时间排序、保留原文可追溯性的知识点时间轴。**

---

### 1.2 第一阶段目标

第一阶段不以页面开发为重点，而是优先夯实数据基础，主要完成：

1. 明确时间轴节点的数据结构
2. 明确字段命名与语义边界
3. 明确时间标准化规则
4. 明确原文抽取规则
5. 形成首批可落库的 JSON 数据样例

第一阶段的核心交付物包括：

- 时间轴数据结构 V1
- 抽取规则 V1
- `timeline-items.json` 初始样例数据
- 供后续前端展示使用的数据基础

---

## 2. 设计原则

### 2.1 显式时间优先

时间轴的核心是“时间可排序”，因此每个节点必须存在明确的显式时间。

显式时间可以是：

- 年：如 `2035年`
- 年月：如 `2021年3月`
- 年月日：如 `2021年3月15日`

时间排序只能依赖显式时间，不依赖会议名称、政策名称或组织名称。

---

### 2.2 原文可追溯

每个节点必须保留教材原文摘录，用于：

- 回看原始语境
- 避免二次摘要失真
- 支持后续搜索与核对
- 提高复习时的可信度与可解释性

原文摘录必须尽量保真，不以转述替代原文。

---

### 2.3 主题稳定可归类

时间轴中的每个节点都必须归属于某个明确主题，用于：

- 按章节筛选
- 按知识域复习
- 后续主题聚合展示

主题应优先使用教材章节名、小节名或知识点标题，避免同类主题命名不一致。

---

### 2.4 来源与时间解耦

原先讨论中的“隐式时间”命名不够准确，因为这类信息不一定是时间，也可能是：

- 会议
- 文件
- 组织
- 人物
- 报告
- 规划

因此，V1 中统一将该字段定义为：

> **来源锚点（sourceAnchor）**

它的作用是说明该节点“由谁提出、在哪里提出、依附于什么来源语境”，而不是承担排序功能。

---

## 3. 需求范围

### 3.1 纳入范围

第一阶段纳入时间轴整理范围的内容包括：

1. 教材中带有明确年份的战略目标、规划节点、发展目标
2. 教材中带有明确年月的政策、制度、会议、文件、重要部署
3. 教材中带有明确年月日的重要事件、发布动作、政策出台节点
4. 与明确显式时间强相关，且适合纳入时间轴展示的知识点原文

---

### 3.2 暂不纳入范围

以下内容第一阶段不进入主时间轴 JSON：

1. 没有显式时间的纯概念性描述
2. 只有意义、路径、措施，但缺少明确时间锚点的句子
3. 只有会议/文件/组织来源，但原文中没有显式时间且暂不准备人工补全的内容
4. 需要复杂推理或联网核验后才能确认时间的内容

这类内容可在后续进入：

- 候选池
- 待补录列表
- 二阶段人工校验列表

---

## 4. 核心需求定义

### 4.1 节点必备字段

每条时间轴节点至少应包含以下 5 个要素：

#### 1）显式时间
必须存在。

作用：

- 时间轴展示
- 统一排序
- 构建标准化排序键

---

#### 2）时间精度
必须存在。

用于区分当前节点时间粒度：

- `year`
- `month`
- `day`

这样可以解决不同时间粒度混排的问题。

---

#### 3）主题
必须存在。

用于说明该时间点归属的教材章节或知识主题。

例如：

- `农业现代化与乡村振兴战略`
- `科技创新`
- `数字中国`
- `新型基础设施`

---

#### 4）原文摘录
必须存在，且必须是原文。

要求：

- 保留原教材表述
- 尽量保留最小完整语义片段
- 不以摘要替代原文

---

#### 5）来源锚点
建议存在，可为空。

用于说明该内容的提出来源、语境来源或依附来源。

例如：

- `党的十九届五中全会`
- `国务院`
- `“十四五”规划`
- `某重要讲话`

该字段不参与排序，只承担来源说明作用。

---

### 4.2 排序需求

排序规则必须满足以下约束：

1. 仅基于显式时间排序
2. 支持年、年月、年月日混排
3. 不依赖来源锚点排序
4. 没有显式时间的记录不能进入主时间轴

---

### 4.3 检索需求

虽然第一阶段重点是数据整理，但字段设计需提前支持后续使用场景：

1. 按时间顺序浏览
2. 按主题筛选
3. 按来源锚点筛选
4. 按原文关键词搜索
5. 查看原文与教材定位信息

---

## 5. 术语定义

### 5.1 显式时间（Explicit Time）

指原文中明确写出的、可直接抽取的时间表达。

示例：

- `2035年`
- `2021年3月`
- `2021年3月15日`

显式时间是主时间轴排序的唯一依据。

---

### 5.2 来源锚点（Source Anchor）

指原文中说明该知识点“由谁提出、在哪提出、基于什么会议/文件/组织/人物”的来源信息。

示例：

- `党的十九届五中全会`
- `国务院`
- `“十四五”规划`
- `政府工作报告`

说明：

- 该字段不是时间字段
- 该字段不参与排序
- 该字段主要用于补充上下文和来源语境

---

### 5.3 主题（Theme）

指该节点归属的教材章节、小节或知识点主题，用于分类和筛选。

---

### 5.4 原文摘录（Excerpt）

指直接来自教材或整理材料中的原文片段，用于支撑该时间点。

---

## 6. 数据结构设计 V1

### 6.1 TypeScript 类型定义建议

建议新增时间轴类型定义，推荐单独创建文件：

- `src/types/timeline.ts`

类型建议如下：

```ts
export type TimelineTimePrecision = 'year' | 'month' | 'day';

export type SourceAnchorType =
  | 'meeting'
  | 'document'
  | 'organization'
  | 'person'
  | 'policy'
  | 'report'
  | 'other';

export interface TimelineItem {
  id: string;

  // 显式时间原文，用于展示
  timeText: string;

  // 排序键，用于统一排序
  sortKey: string;

  // 时间精度：年 / 月 / 日
  timePrecision: TimelineTimePrecision;

  // 主题，通常对应章节或知识点
  theme: string;

  // 原文摘录，必须保留原文
  excerpt: string;

  // 来源锚点，可为空
  sourceAnchor?: string;

  // 来源锚点类型，可为空
  sourceAnchorType?: SourceAnchorType;

  // 可选：原文在教材中的定位信息
  sourcePosition?: string;
}
```

---

### 6.2 字段说明

| 字段名 | 必填 | 说明 |
|---|---|---|
| `id` | 是 | 唯一标识，建议使用稳定编号 |
| `timeText` | 是 | 原文中的显式时间表达 |
| `sortKey` | 是 | 用于排序的标准化值 |
| `timePrecision` | 是 | 时间粒度：年 / 月 / 日 |
| `theme` | 是 | 所属主题或章节 |
| `excerpt` | 是 | 原文摘录 |
| `sourceAnchor` | 否 | 来源锚点 |
| `sourceAnchorType` | 否 | 来源锚点类型 |
| `sourcePosition` | 否 | 教材定位，如章节、页码、小节 |

---

### 6.3 命名设计说明

#### 为什么不用 `implicitTime`

因为这个字段并不稳定指向“时间”，它更多时候表示的是：

- 提出来源
- 会议名称
- 文件名称
- 组织主体
- 人物主体

如果继续命名为 `implicitTime`，会误导后续开发和数据维护。

---

#### 为什么推荐 `sourceAnchor`

因为它更准确表达了这个字段的职责：

- 是一个“来源锚点”
- 是知识点的出处说明
- 是原文上下文的承载信息
- 不参与时间排序

---

## 7. JSON 文件组织方案

### 7.1 第一阶段文件建议

结合当前项目结构，建议新增：

```bash
src/data/timeline-items.json
```

采用与现有数据一致的静态 JSON 管理方式。

---

### 7.2 JSON 结构建议

建议采用统一外层包装结构：

```json
{
  "timelineItems": [
    {
      "id": "TL001",
      "timeText": "2035年",
      "sortKey": "20350000",
      "timePrecision": "year",
      "theme": "农业现代化与乡村振兴战略",
      "excerpt": "党的十九届五中全会着眼2035年基本实现社会主义现代化，提出“关键核心技术实现重大突破，进入创新型国家前列”的远景目标。",
      "sourceAnchor": "党的十九届五中全会",
      "sourceAnchorType": "meeting",
      "sourcePosition": "第X章 第X节"
    }
  ]
}
```

说明：

- `timelineItems` 命名与当前项目数据文件组织方式保持一致
- 后续若数据规模扩大，可再考虑按主题拆分多个 JSON 文件

---

## 8. 时间标准化规则

为了实现稳定排序，需要将时间文本转为标准化排序键 `sortKey`。

### 8.1 标准化规则

#### 年

- 原文：`2035年`
- `timePrecision`: `year`
- `sortKey`: `20350000`

#### 年月

- 原文：`2021年3月`
- `timePrecision`: `month`
- `sortKey`: `20210300`

#### 年月日

- 原文：`2021年3月15日`
- `timePrecision`: `day`
- `sortKey`: `20210315`

---

### 8.2 字段设计建议

- `sortKey` 建议统一保存为字符串
- 长度固定为 8 位
- 年月不足位使用 `00` 补齐

这样可以减少：

- 数字前导零问题
- 字符串排序与数值排序不一致问题
- 前端处理时的格式分支

---

### 8.3 时间合法性要求

正式数据应满足以下约束：

1. 年份必须为四位数
2. 月份必须在 `01-12`
3. 日期必须在 `01-31`
4. 非法时间不得进入正式时间轴 JSON

---
### 8.4 标题锚点与目标锚点的区分说明

在时间标准化前，应先判断当前原文中的时间究竟属于哪一类：

#### 1）提出时间锚点
用于表示某项政策、规划、文件、会议“在何时提出”。

例如：

- `《中华人民共和国国民经济和社会发展第十四个五年规划和2035年远景目标纲要》明确提出了推进产业数字化转型……`

这类句子的时间轴挂载时间，应优先取：

- 该纲要所属年份 `2021年`
- 或进一步精确到 `2021年3月`

#### 2）目标实现锚点
用于表示某项目标“到何时实现”。

例如：

- `到2035年基本实现社会主义现代化`

这类句子的时间轴挂载时间，才应直接取：

- `2035年`

因此，时间抽取不能只看句子里出现了哪个年份，还要判断该年份在语义上属于：

- **提出时间**
- 还是 **目标时间**

---

## 9. 数据抽取规则 V1

### 9.1 总体规则

#### 规则 1：没有显式时间，不入主时间轴

主时间轴只接收可明确排序的节点。

若仅有来源锚点而没有显式时间，则先不纳入主时间轴数据。

---

#### 规则 2：一段原文出现多个显式时间，应拆为多个节点

例如同一段中出现：

- `2020年`
- `2035年`
- `本世纪中叶`

若均可确定为可排序时间点，则应拆分成多条时间轴记录。

---

#### 规则 3：多个节点可共用同一段原文摘录

拆分后的多条节点可以共用：

- `theme`
- `excerpt`
- `sourceAnchor`
- `sourcePosition`

但必须拥有独立的：

- `timeText`
- `sortKey`
- `timePrecision`
- `id`

---

#### 规则 4：来源锚点不参与排序

来源锚点的职责是提供语义补充，不承担排序责任。

---

#### 规则 5：原文摘录必须尽量保真

要求：

- 不得用改写内容替代原文
- 允许适度截取，但应保留完整语义
- 以“能支撑该时间点成立的最小完整片段”为宜

#### 规则 5.1：若原始素材来自 OCR，必须先校对再入库

这里需要明确区分：

- **教材标准原文**
- **OCR 识别结果**

时间轴中的 `excerpt` 字段应保存：

- **校对后的规范原文**

而不是未经处理的 OCR 脏文本。

处理原则如下：

1. 对于明显 OCR 错字，应直接人工校正后再入库，例如：
   - `深人` → `深入`
   - `进人` → `进入`
2. 对于不确定是否识别错误的字句，不应主观猜测，应回到教材、原始资料或权威来源核对后再录入
3. 若当前只能拿到 OCR 文本而无法完成核对，则该条数据应暂缓正式入库，避免错误内容污染主数据集

这样做的目的是：

- 保证 `excerpt` 可作为后续检索与复习依据
- 避免把 OCR 噪声误当作教材原文长期沉淀
- 提高数据质量，减少后续返工成本

#### 规则 5.2：`excerpt` 字段的入库边界

`excerpt` 字段的处理必须遵循以下边界：

1. **保留原文句式**
2. **只修明显 OCR 错字**
3. **不擅自改写、不总结、不替换原句**
4. **如果怀疑句子不通顺，但又不能确定是 OCR 错误，必须先询问或标记，不得直接改写后入库**

也就是说，`excerpt` 的职责是：

- 保留知识点在原始材料中的表达方式
- 为后续查找、比对、复习提供可信原句

而不是：

- 由系统进行润色
- 改写成更通顺的表述
- 用摘要句替代原文

该规则用于确保时间轴数据既可追溯，又不会因为主观改写而偏离原始材料。

#### 规则 6：文件名或规划名中同时出现‘规划期’与‘远景目标年’时，优先取提出时间

这是时间轴抽取中的高频易错点。

例如：

- `《中华人民共和国国民经济和社会发展第十四个五年规划和2035年远景目标纲要》`

该类名称中可能同时包含：

- 规划期信息，如“第十四个五年规划”
- 远景目标信息，如“2035年远景目标”

若原文语义是：

- `某规划明确提出……`
- `某纲要提出……`
- `某文件要求……`

那么时间轴节点应优先挂载为：

- **该规划/文件的提出时间、发布年份或所属规划起始年份**

而不应直接挂载到远景目标年份。

也就是说，需要区分：

1. **提出时间**：指该政策、规划、文件、纲要被提出、发布或实施启动的时间
2. **目标时间**：指原文明确表达“到某年实现某目标”的目标年份

只有当原文语义明确指向“到2035年实现……”时，才应将 `2035年` 作为该节点的显式时间。

若原文只是说：

- `《……2035年远景目标纲要》明确提出……`

则更适合将该节点时间挂到：

- `2021年`（按该纲要所属年份归类）
- 或在资料足够精确时挂到 `2021年3月`（按正式通过/发布节点归类）

此规则的核心目的是：

- 避免将文件标题中的“远景目标年份”误当作当前知识点的发生时间
- 保证时间轴表达的是“提出/发布时间”与“目标实现时间”的真实差异

---

### 9.2 主题提取规则

主题提取建议遵循以下优先级：

1. 当前教材章节标题
2. 当前小节标题
3. 当前知识点标题
4. 无法直接归类时人工指定统一主题名

注意：

- 同类主题应统一命名
- 不应同一主题出现多个近义版本

例如不建议同时出现：

- `农业现代化`
- `农业现代化与乡村振兴`
- `乡村振兴战略`

若其本质上属于同一章节主题，应统一。

---

### 9.3 来源锚点提取规则

来源锚点优先抽取原文中最直接、最核心的来源表达。

优先级建议如下：

1. 会议名称
2. 文件/规划名称
3. 组织名称
4. 人物名称
5. 其他来源描述

若原文中存在多个来源锚点，V1 可先只保留一个最核心锚点。

---

## 10. 样例数据

以下为基于当前讨论生成的样例节点：

```json
{
  "id": "TL001",
  "timeText": "2035年",
  "sortKey": "20350000",
  "timePrecision": "year",
  "theme": "农业现代化与乡村振兴战略",
  "excerpt": "党的十九届五中全会着眼2035年基本实现社会主义现代化，提出“关键核心技术实现重大突破，进入创新型国家前列”的远景目标。",
  "sourceAnchor": "党的十九届五中全会",
  "sourceAnchorType": "meeting"
}
```

---

## 11. 与现有项目架构的对齐方案

### 11.1 数据层

新增时间轴 JSON 文件：

```bash
src/data/timeline-items.json
```

与当前项目的数据组织方式保持一致。

---

### 11.2 类型层

建议新增文件：

```bash
src/types/timeline.ts
```

原因：

- 避免 `src/types/itto.ts` 职责继续膨胀
- 便于后续扩展时间轴相关类型
- 降低不同业务域之间的耦合

如果项目当前更偏向集中维护类型，也可以先临时放在 `src/types/itto.ts`，但从中长期维护上看，独立文件更合理。

---

### 11.3 数据统一导出

后续建议在 `src/data/index.ts` 中增加：

```ts
import timelineItemsData from './timeline-items.json';
import type { TimelineItem } from '../types/timeline';

export const timelineItems: TimelineItem[] =
  timelineItemsData.timelineItems as TimelineItem[];
```

后续如有需要，可继续扩展：

- 按主题分组索引
- 按来源锚点分组索引
- 时间排序工具函数
- 时间区间筛选工具函数

---

## 12. 第一阶段实施边界

### 12.1 本阶段要完成

1. 明确字段定义
2. 明确抽取规则
3. 建立时间标准化规范
4. 建立首批时间轴 JSON 数据
5. 准备后续页面开发所需的数据基础

---

### 12.2 本阶段暂不处理

1. 自动 NLP 抽取
2. 自动时间纠错
3. 复杂时间表达解析
4. 时间轴页面 UI
5. 多条件高级检索面板
6. 时间轴与其他知识图谱的联动展示

---

## 13. 风险与注意事项

### 13.1 时间与来源混淆风险

这是当前模块最容易出错的点。

必须明确：

- 显式时间负责排序
- 来源锚点负责说明出处
- 两者不能混用

---

### 13.2 主题命名不统一风险

若主题命名粒度不统一，后续筛选与聚合会出现严重碎片化。

建议尽早制定主题命名规范，并优先以教材目录层级为准。

---

### 13.3 原文过长风险

原文摘录必须保留，但如果过长，会影响后续展示体验。

建议数据层保留完整有效片段，展示层再决定是否截断。

---

### 13.4 JSON 维护成本风险

第一阶段采用人工整理 JSON 的方式，优点是可控、准确；缺点是维护成本较高。

因此应尽早明确：

- 字段规范
- 抽取规则
- 主题命名规范
- 时间标准化规则

这样才能降低后续补录和返工成本。

---

## 14. 后续演进建议

在第一阶段数据稳定后，后续可逐步演进：

1. 时间轴浏览页面
2. 按主题筛选
3. 按来源锚点筛选
4. 原文搜索
5. 节点详情弹层
6. 同主题聚合展示
7. 与章节知识点页面联动
8. 导出 JSON / CSV

---

## 15. 当前推荐结论

第一阶段推荐采用如下最小可行数据结构：

```ts
export interface TimelineItem {
  id: string;
  timeText: string;
  sortKey: string;
  timePrecision: 'year' | 'month' | 'day';
  theme: string;
  excerpt: string;
  sourceAnchor?: string;
  sourceAnchorType?: 'meeting' | 'document' | 'organization' | 'person' | 'policy' | 'report' | 'other';
  sourcePosition?: string;
}
```

该结构已经足以支撑：

- 时间排序
- 主题归类
- 原文追溯
- 来源说明

同时也为第二阶段页面开发预留了足够扩展空间。
