# 需求文档：前后端分离 — Java API 后端与 PostgreSQL 数据库

## 简介

本项目旨在将现有的 Next.js 16 前端生产管理子系统进行前后端分离改造。当前前端所有页面均使用硬编码的模拟数据，需要搭建 Java Spring Boot 3.3.6 后端 API 服务和 PostgreSQL 数据库，用真实的 RESTful API 接口和持久化数据替换前端模拟数据。

系统为地球物理仪器（高密度电法仪等）的全生命周期管理平台，包含以下核心页面模块：
- 首页 Dashboard（`/`）— 8项统计指标、设备状态分布、4组待处理任务
- 设备列表（`/devices`）— 卡片式设备列表，按批次侧边栏分组
- 设备详情（`/devices/[sn]`）— 6个Tab页（概览、装机清单、装配记录、授权项信息、配置文件、操作日志）
- 设备登记（`/registration`）— 装机信息表单、BOM清单、装配Checklist
- 设备型号管理（`/models`）— 型号列表、装配Checklist模板
- 板卡列表（`/calibration`）— 板卡实例管理，含统计卡片和筛选
- 板卡登记（`/calibration/register`）— 单个/批量板卡登记
- 板卡版本管理（`/boards`）— 板卡型号版本管理，Tab筛选
- 固件库（`/firmware`）— 固件版本卡片列表，支持从板卡版本页跳转筛选
- 授权管理（`/licenses`）— 授权列表，11项授权模块勾选
- 配置文件管理（`/config-files`）— 配置文件列表，含详细参数
- 维修工单（`/repair`）— 卡片式工单列表，新建/处理/详情抽屉
- 报废管理（`/scrap`）— 审批流程、物料回收

## 术语表

- **API_Server**：基于 Spring Boot 3.3.6 的 Java 后端 API 服务，项目路径 `apps/geo-bps-api/`
- **Database**：PostgreSQL 12.14 数据库实例，设备管理模块使用 `dev` schema
- **Frontend**：现有 Next.js 16 前端应用，位于 `src/app/` 目录
- **Device_Module**：设备管理业务模块，包名 `com.geomative.bps.device`，数据库 schema `dev`
- **Common_Module**：公共模块，包名 `com.geomative.bps.common`，提供统一响应体、全局异常处理、工具类
- **API_Admin**：后台管理入口模块，提供需登录鉴权的 API 端点
- **DDD**：领域驱动设计分层架构（interfaces / application / domain / infrastructure）
- **Board_Card**：板卡实例，指具体的单个板卡物理实体，拥有唯一SN号、状态（在库/已装配/故障/报废）、校准状态
- **Board_Type**：板卡版本（型号），指板卡的设计版本（如 MB-V1.8、RX-V2.3），管理版本的在产/停产状态
- **DO**：数据库映射对象（Data Object）
- **VO**：视图对象（View Object），用于 API 响应
- **Query**：查询参数对象
- **Command**：命令对象，用于创建/更新操作
- **Calibration_File**：校准文件，采集板校准时由上位机生成并上传的文件，通过采集板SN号关联
- **Upper_Computer**：上位机，校准设备的PC端软件，负责执行采集板校准并上传校准文件
- **API_Portal**：前端门户入口模块，提供无需登录鉴权的公开 API 端点

## 需求

### 需求 1：后端项目骨架搭建

**用户故事：** 作为开发者，我希望搭建一个符合技术规范的 Java Spring Boot 多模块 Maven 项目骨架，以便后续各业务模块可以在此基础上开发。

#### 验收标准

1. THE API_Server SHALL 采用多模块 Maven 项目结构，父 POM 统一管理 Spring Boot 3.3.6、MyBatis-Plus、Lombok 等依赖版本
2. THE API_Server SHALL 包含以下子模块：api-admin、api-portal、business（含 device 子模块）、common
3. THE Common_Module SHALL 提供统一 JSON 响应格式，包含 code（整数）、message（字符串）、data（泛型）三个字段
4. THE Common_Module SHALL 提供全局异常处理器，捕获业务异常和参数校验异常并返回统一格式的错误响应
5. THE Common_Module SHALL 提供 MyBatis-Plus 的 MetaObjectHandler 实现，自动填充 created_at 和 updated_at 审计字段
6. THE API_Admin SHALL 配置 CORS 策略，允许前端开发服务器（localhost:3000）的跨域请求
7. THE API_Server SHALL 在 application.yml 中配置 PostgreSQL 数据源连接和 MyBatis-Plus 逻辑删除策略

### 需求 2：数据库 Schema 与表结构设计

**用户故事：** 作为开发者，我希望设计并创建 PostgreSQL 数据库表结构，以便持久化存储各业务模块的数据。

#### 验收标准

1. THE Database SHALL 在 `dev` schema 下创建设备管理相关的数据表
2. THE Database SHALL 包含 `dev.devices` 表，存储设备信息（SN号唯一索引、型号ID、型号名称、状态[装配中/已出厂/已激活/报废]、固件版本、生产日期、客户名称、批次号[YYYY-WXX格式]、登记人）
3. THE Database SHALL 包含 `dev.device_models` 表，存储设备型号信息（型号名称如GD-30 Supreme、型号代码如GD30唯一索引、状态[在产/停产]、描述、创建日期）
4. THE Database SHALL 包含 `dev.board_types` 表，存储板卡版本信息（板卡类型[主协板/采集板/发射板/升压板]、版本号如MB-V1.8唯一索引、生产日期、状态[在产/停产]）
5. THE Database SHALL 包含 `dev.board_cards` 表，存储板卡实例信息（板卡SN号唯一索引、板卡类型[主协板/采集板/发射板/升压板]、版本号、固件版本、状态[在库/已装配/故障/报废]、所属设备SN、生产日期、校准状态[合格/不合格/待校准/无需校准]、校准日期、备注）
6. THE Database SHALL 包含 `dev.device_boards` 表，存储设备与板卡的装配关联关系（设备ID、设备SN、板卡实例ID、板卡SN、板卡名称、板卡型号、校准状态）
7. THE Database SHALL 包含 `dev.firmware_versions` 表，存储固件版本信息（版本号、关联板卡版本ID、板卡版本号、固件类型[主协板/采集板/发射板/升压板/主机固件/计算单元固件]、发布日期、状态[已发布/草稿]、文件大小、下载次数、硬件版本范围、升级类型[可选/强制]、是否签名、MD5、SHA256、发布说明JSON数组、文件存储路径）
8. THE Database SHALL 包含 `dev.calibration_records` 表，存储校准记录（采集板SN号、板卡版本ID、板卡版本号、校准日期、到期日期、校准人员、状态[合格/不合格/待校准]、通道数、综合偏差、各通道校准结果JSONB）
9. THE Database SHALL 包含 `dev.config_files` 表，存储配置文件信息（配置名称、适配型号ID、型号名称、版本、状态[生效/已停用]、发射参数JSONB含电压/电流/占空比/脉宽/迭代次数/波形、采集参数JSONB含通道数/采样率/电压量程/全波形、保护参数JSONB含过压/过流/短路/高温、网络参数JSONB含WiFi SSID前缀）
10. THE Database SHALL 包含 `dev.licenses` 表，存储授权信息（设备型号ID、型号代码、授权模块列表JSONB含11项模块[1D SP/2D SP/3D SP/1D VES/2D ERT/3D ERT/1D IP/2D IP/3D IP/跨孔/水上]、有效期类型[永久/1年/2年/3年/自定义]、到期日期、状态[生效/草稿/已停用]）
11. THE Database SHALL 包含 `dev.repair_orders` 表，存储维修工单信息（工单号唯一索引、设备SN、故障类型[板卡故障/固件异常/通信故障/电源故障/传感器故障/其他]、状态[待处理/处理中/已处理]、优先级[高/中/低]、负责人、故障描述、故障现象、预计修复日期、备注、处理记录JSONB时间线、板卡更换记录JSONB）
12. THE Database SHALL 包含 `dev.scrap_records` 表，存储报废记录（设备SN、设备型号名称、报废原因、申请人、状态[待审批/审批中/已审批/已驳回/回收中/已回收]、来源工单号、残值评估金额、可回收物料列表JSONB、审批记录时间线JSONB、审批意见）
13. THE Database SHALL 包含 `dev.checklist_templates` 表和 `dev.checklist_items` 表，存储装配 Checklist 模板及其检查项（检查项含名称、是否必填、排序序号）
14. WHEN 创建任何业务表时，THE Database SHALL 包含 id（VARCHAR(64) 主键）、created_at、created_by、updated_at、updated_by、deleted 审计字段

### 需求 3：设备管理 API

**用户故事：** 作为前端开发者，我希望通过 API 获取和管理设备数据，以便替换设备列表页面（`/devices`）和设备详情页面（`/devices/[sn]`）的模拟数据。

#### 验收标准

1. WHEN 前端请求 GET `/api/admin/devices` 时，THE API_Server SHALL 返回分页的设备列表，支持按型号、状态、生产日期、SN号、批次号筛选，每条记录包含 sn、model、type、status、firmware、productionDate、customer、batch 字段
2. WHEN 前端请求 GET `/api/admin/devices/{sn}` 时，THE API_Server SHALL 返回指定设备的完整详情，包含6个Tab页所需的全部数据：
   - 概览Tab：基本信息（SN、型号、类型、固件版本、生产日期、登记人、状态）
   - 装机清单Tab：BOM列表（物料名称、板卡SN、型号、校准状态）
   - 装配记录Tab：Checklist检查项列表（项目名称、通过状态、照片URL列表、装配记录备注），含通过数/总数统计
   - 授权项信息Tab：授权模块列表、到期时间、授权状态
   - 配置文件Tab：配置文件名称、版本、发射参数（电压/电流/占空比/脉宽/波形/全波形）、采集参数（通道数/采样率/电压量程/迭代次数）、保护参数（过压/过流/短路/高温阈值）、网络参数（WiFi SSID前缀）
   - 操作日志Tab：操作记录时间线（日期、操作类型、操作人、详情描述）
3. WHEN 前端请求 POST `/api/admin/devices` 时，THE API_Server SHALL 创建新设备记录（设备登记），包含装机信息（型号、主机SN、主板SN、测试状态、生产日期、登记人）、BOM清单列表和装配Checklist状态
4. WHEN 前端请求 GET `/api/admin/devices/batches` 时，THE API_Server SHALL 返回所有生产批次列表，每个批次包含批次号（YYYY-WXX格式）、设备数量，按年份分组并按时间倒序排列
5. IF 请求参数中的 SN 号已存在，THEN THE API_Server SHALL 返回 409 冲突错误码和描述性错误消息

### 需求 4：设备型号管理 API

**用户故事：** 作为前端开发者，我希望通过 API 管理设备型号和装配 Checklist 模板，以便替换型号管理页面（`/models`）的模拟数据。

#### 验收标准

1. WHEN 前端请求 GET `/api/admin/device-models` 时，THE API_Server SHALL 返回所有设备型号列表，每条记录包含 name、code、status、description、createDate 字段
2. WHEN 前端请求 POST `/api/admin/device-models` 时，THE API_Server SHALL 创建新设备型号记录，包含型号名称、型号编码、描述、状态[在产/停产]
3. WHEN 前端请求 PUT `/api/admin/device-models/{id}` 时，THE API_Server SHALL 更新指定型号的状态（在产/停产切换）
4. WHEN 前端请求 GET `/api/admin/checklist-templates?modelCode={code}` 时，THE API_Server SHALL 返回指定型号的装配 Checklist 模板及其检查项列表（含名称、是否必填、排序序号）
5. WHEN 前端请求 POST `/api/admin/checklist-templates` 时，THE API_Server SHALL 创建新的 Checklist 模板，包含关联型号和检查项列表
6. IF 请求的型号代码已存在，THEN THE API_Server SHALL 返回 409 冲突错误码

### 需求 5：板卡版本管理 API

**用户故事：** 作为前端开发者，我希望通过 API 管理板卡版本（型号）数据，以便替换板卡版本管理页面（`/boards`）的模拟数据。该页面管理的是板卡的设计版本（如 MB-V1.8），而非单个板卡实例。

#### 验收标准

1. WHEN 前端请求 GET `/api/admin/board-types` 时，THE API_Server SHALL 返回板卡版本列表，支持按板卡类型（全部/主协板/采集板/发射板/升压板）Tab筛选，每条记录包含 type、version、productionDate、status 字段
2. WHEN 前端请求 GET `/api/admin/board-types/{id}` 时，THE API_Server SHALL 返回板卡版本详情，包含基本信息（类型、版本、生产日期、状态）
3. WHEN 前端请求 POST `/api/admin/board-types` 时，THE API_Server SHALL 创建新板卡版本记录，包含板卡类型、版本号、生产日期、状态
4. WHEN 前端请求 PUT `/api/admin/board-types/{id}/toggle-status` 时，THE API_Server SHALL 切换板卡版本的状态（在产↔停产）

### 需求 6：板卡实例管理 API

**用户故事：** 作为前端开发者，我希望通过 API 管理板卡实例数据，以便替换板卡列表页面（`/calibration`）的模拟数据。该页面管理的是具体的单个板卡物理实体，每个板卡有唯一SN号、库存状态和校准状态。

#### 验收标准

1. WHEN 前端请求 GET `/api/admin/board-cards` 时，THE API_Server SHALL 返回分页的板卡实例列表，支持按板卡类型（全部/主协板/采集板/发射板/升压板）、板卡状态（全部/在库/已装配/故障/报废）、校准状态（全部/合格/不合格/待校准）筛选，支持按板卡SN或设备SN搜索，每条记录包含 sn、type、version、firmware、status、deviceSn、productionDate、calibStatus、calibDate 字段
2. WHEN 前端请求 GET `/api/admin/board-cards/{id}` 时，THE API_Server SHALL 返回板卡实例详情，包含基本信息（SN、类型、版本、固件版本、生产日期、状态）、装配信息（所属设备SN）、校准信息（校准状态、校准日期，仅采集板显示）
3. WHEN 前端请求 GET `/api/admin/board-cards/stats` 时，THE API_Server SHALL 返回板卡统计数据，包含板卡总数、在库数量、已装配数量、故障数量、待校准数量
4. IF 请求参数中的板卡SN号已存在，THEN THE API_Server SHALL 返回 409 冲突错误码和描述性错误消息

### 需求 7：板卡登记 API

**用户故事：** 作为前端开发者，我希望通过 API 登记新板卡，以便替换板卡登记页面（`/calibration/register`）的模拟数据。该页面支持单个和批量登记板卡。

#### 验收标准

1. WHEN 前端请求 POST `/api/admin/board-cards` 时，THE API_Server SHALL 创建单个板卡实例记录，包含板卡类型、版本号、固件版本（根据版本自动填充）、板卡SN号、生产日期、备注
2. WHEN 前端请求 POST `/api/admin/board-cards/batch` 时，THE API_Server SHALL 支持批量创建多个板卡实例记录，请求体为板卡信息数组
3. WHEN 创建采集板类型的板卡时，THE API_Server SHALL 自动将校准状态设置为"待校准"
4. WHEN 创建非采集板类型的板卡时，THE API_Server SHALL 自动将板卡状态设置为"在库"，校准状态设置为无需校准
5. THE API_Server SHALL 提供 GET `/api/admin/board-types/{type}/versions` 接口，返回指定板卡类型的可选版本列表及对应固件版本，用于板卡登记表单的版本下拉选择

### 需求 8：固件库管理 API

**用户故事：** 作为前端开发者，我希望通过 API 管理固件版本数据，以便替换固件库页面（`/firmware`）的模拟数据。

#### 验收标准

1. WHEN 前端请求 GET `/api/admin/firmware` 时，THE API_Server SHALL 返回固件版本列表，支持按固件类型（全部/主协板/采集板/发射板/升压板/主机固件/计算单元固件）Tab筛选
2. WHEN 前端请求 GET `/api/admin/firmware?boardVersion={version}` 时，THE API_Server SHALL 返回指定板卡版本的固件列表，用于从板卡版本管理页面（`/boards`）通过 `?board=` 参数跳转后的筛选展示
3. WHEN 前端请求 POST `/api/admin/firmware` 时，THE API_Server SHALL 创建新固件版本记录，包含版本号、硬件版本范围、升级类型[可选/强制]、签名状态、发布说明（多行文本，每行一条）
4. WHEN 前端请求 GET `/api/admin/firmware/{id}/download` 时，THE API_Server SHALL 返回固件文件的下载流，并将该固件的下载次数加 1
5. IF 上传的固件版本号与同一板卡版本的已有版本重复，THEN THE API_Server SHALL 返回 409 冲突错误码

### 需求 9：校准记录管理 API

**用户故事：** 作为前端开发者，我希望通过 API 管理采集板校准数据。校准功能是板卡实例管理的一部分，校准状态直接关联到板卡实例（`dev.board_cards`）的 calibStatus 和 calibDate 字段。

#### 验收标准

1. WHEN 前端请求 GET `/api/admin/calibrations` 时，THE API_Server SHALL 返回分页的校准记录列表，支持按采集板SN号、校准状态[合格/不合格/待校准]、校准人员筛选
2. WHEN 前端请求 GET `/api/admin/calibrations/{id}` 时，THE API_Server SHALL 返回校准详情，包含各通道的校准结果（参考值、测量值、偏差、结果）
3. WHEN 前端请求 POST `/api/admin/calibrations/import` 时，THE API_Server SHALL 支持批量导入校准记录数据，并同步更新对应板卡实例（`dev.board_cards`）的校准状态和校准日期

### 需求 10：配置文件管理 API

**用户故事：** 作为前端开发者，我希望通过 API 管理设备配置文件，以便替换配置文件管理页面（`/config-files`）的模拟数据。

#### 验收标准

1. WHEN 前端请求 GET `/api/admin/config-files` 时，THE API_Server SHALL 返回分页的配置文件列表，支持按适配型号、版本、关键字筛选，每条记录包含 name、model、version、createTime、status 字段
2. WHEN 前端请求 GET `/api/admin/config-files/{id}` 时，THE API_Server SHALL 返回配置文件详情，包含基本信息（名称、型号、版本、状态、创建时间）、发射参数（电压、电流、占空比、脉宽范围、迭代次数）、采集参数（通道数、采样率、电压量程、全波形采集）、网络参数（WiFi SSID前缀）
3. WHEN 前端请求 POST `/api/admin/config-files` 时，THE API_Server SHALL 创建新配置文件记录，包含适配型号、版本、发射参数、采集参数、网络参数
4. WHEN 前端请求 PUT `/api/admin/config-files/{id}` 时，THE API_Server SHALL 更新指定配置文件记录
5. WHEN 前端请求 DELETE `/api/admin/config-files/{id}` 时，THE API_Server SHALL 逻辑删除指定配置文件（设置 deleted=1）

### 需求 11：授权管理 API

**用户故事：** 作为前端开发者，我希望通过 API 管理设备授权数据，以便替换授权管理页面（`/licenses`）的模拟数据。

#### 验收标准

1. WHEN 前端请求 GET `/api/admin/licenses` 时，THE API_Server SHALL 返回分页的授权列表，支持按设备型号（GD-10/GD-20/GD-30）和状态（生效/草稿/已停用）筛选，每条记录包含 model、modules、expiry、date、status 字段
2. WHEN 前端请求 POST `/api/admin/licenses` 时，THE API_Server SHALL 创建新授权记录，包含设备型号、授权模块列表（从11项模块中勾选）、授权期限[1年/2年/3年/永久/自定义]、自定义到期日期
3. WHEN 前端请求 PUT `/api/admin/licenses/{id}` 时，THE API_Server SHALL 更新指定授权记录
4. WHEN 前端请求 PUT `/api/admin/licenses/{id}/disable` 时，THE API_Server SHALL 将指定授权记录状态设置为已停用
5. THE API_Server SHALL 提供 GET `/api/admin/licenses/auth-items` 接口，返回全部11项授权模块定义（ID、名称、描述）
6. THE API_Server SHALL 提供 GET `/api/admin/licenses/model-presets` 接口，返回各型号的默认授权模块预选配置（GD-10: 6项, GD-20: 9项, GD-30: 全部11项）

### 需求 12：维修工单管理 API

**用户故事：** 作为前端开发者，我希望通过 API 管理维修工单数据，以便替换维修工单页面（`/repair`）的模拟数据。

#### 验收标准

1. WHEN 前端请求 GET `/api/admin/repair-orders` 时，THE API_Server SHALL 返回分页的维修工单列表，支持按状态[全部/待处理/处理中/已处理]、优先级[全部/高/中/低]、负责人、日期范围（开始~结束）、设备SN筛选，每条记录包含 id、sn、faultType、status、priority、assignee、createDate、description 字段
2. WHEN 前端请求 GET `/api/admin/repair-orders/{id}` 时，THE API_Server SHALL 返回工单详情，包含：
   - 工单信息（工单号、状态、优先级、创建时间、负责人、预计修复时间）
   - 设备信息（设备SN、型号、类型、固件版本、位置，通过 deviceInfoMap 查询）
   - 故障信息（故障类型、描述、现象）
   - 处理记录时间线（日期、操作人、操作类型、备注）
   - 板卡更换记录（原板卡SN、新板卡SN、板卡类型、板卡型号、更换日期、操作人）
3. WHEN 前端请求 POST `/api/admin/repair-orders` 时，THE API_Server SHALL 创建新维修工单，包含设备SN（从设备列表选择）、故障类型（单选6种）、故障描述、故障现象、优先级（低/中/高）、维修人员、预计修复时间、备注
4. WHEN 前端请求 PUT `/api/admin/repair-orders/{id}/process` 时，THE API_Server SHALL 更新工单处理信息，包含处理操作类型[更换板卡/固件修复/参数重置/其他处理]、板卡更换信息（板卡类型、板卡型号、原SN、新SN）、授权处理（重新生成授权文件/推送适配固件）、处理备注
5. WHEN 前端请求 PUT `/api/admin/repair-orders/{id}/close` 时，THE API_Server SHALL 关闭工单并将状态设置为已处理
6. THE API_Server SHALL 提供 GET `/api/admin/repair-orders/device-info/{sn}` 接口，返回指定设备SN的设备信息（型号、类型、固件版本、位置），用于新建工单时选择设备后展示设备信息

### 需求 13：报废管理 API

**用户故事：** 作为前端开发者，我希望通过 API 管理报废审批和物料回收数据，以便替换报废管理页面（`/scrap`）的模拟数据。

#### 验收标准

1. WHEN 前端请求 GET `/api/admin/scrap-records` 时，THE API_Server SHALL 返回分页的报废记录列表，支持按设备SN、状态[全部/待审批/审批中/已审批/已驳回/回收中/已回收]、日期筛选，每条记录包含 sn、model、reason、applicant、status、orderId、date、value、materials 字段
2. WHEN 前端请求 GET `/api/admin/scrap-records/{id}` 时，THE API_Server SHALL 返回报废详情，包含设备信息（SN、型号、报废日期、报废原因、残值评估）、审批信息（申请人、状态、来源工单号）、可回收物料标签列表、审批记录时间线（日期、操作类型、操作人、备注）
3. WHEN 前端请求 PUT `/api/admin/scrap-records/{id}/approve` 时，THE API_Server SHALL 审批通过报废申请，更新状态为已审批，记录审批意见
4. WHEN 前端请求 PUT `/api/admin/scrap-records/{id}/reject` 时，THE API_Server SHALL 驳回报废申请，更新状态为已驳回，记录驳回意见
5. WHEN 前端请求 PUT `/api/admin/scrap-records/{id}/recover` 时，THE API_Server SHALL 完成物料回收入库，更新状态为已回收，记录已检测的回收物料清单和回收备注
6. THE API_Server SHALL 提供 GET `/api/admin/scrap-records/stats` 接口，返回报废统计数据（报废总数、待审批数、已审批待回收数、已回收数）

### 需求 14：首页 Dashboard 统计 API

**用户故事：** 作为前端开发者，我希望通过 API 获取首页仪表盘的统计数据，以便替换首页（`/`）的模拟数据。

#### 验收标准

1. WHEN 前端请求 GET `/api/admin/dashboard/metrics` 时，THE API_Server SHALL 返回8项统计指标：设备总数、装配中数量、已激活数量、有新版本数量、维修中数量、报废数量、授权即将到期数量、可升级数量，每项指标包含当前值和趋势变化百分比
2. WHEN 前端请求 GET `/api/admin/dashboard/device-status` 时，THE API_Server SHALL 返回设备状态分布数据，包含已装配、已出厂、已激活、报废四种状态的数量，用于横向条形图展示
3. WHEN 前端请求 GET `/api/admin/dashboard/tasks` 时，THE API_Server SHALL 返回待处理任务列表，包含4个分组（校准即将到期、维修工单、固件升级通知、授权即将到期），每组包含总数和最近2条任务详情（设备SN/名称、描述、时间、跳转链接）

### 需求 15：前端 API 集成层

**用户故事：** 作为前端开发者，我希望在前端建立统一的 API 调用层，以便各页面组件可以方便地调用后端接口替换模拟数据。

#### 验收标准

1. THE Frontend SHALL 创建统一的 API 客户端模块（`src/lib/api/client.ts`），配置后端 API 基础 URL（通过 NEXT_PUBLIC_API_URL 环境变量）、请求超时时间（5秒）、统一错误处理
2. THE Frontend SHALL 为每个业务模块创建独立的 API 服务文件：deviceApi.ts、modelApi.ts、boardTypeApi.ts、boardCardApi.ts、firmwareApi.ts、calibrationApi.ts、configFileApi.ts、licenseApi.ts、repairApi.ts、scrapApi.ts、dashboardApi.ts
3. WHEN API 请求失败时，THE Frontend SHALL 在页面上展示友好的错误提示信息
4. WHEN API 请求正在进行时，THE Frontend SHALL 展示加载状态指示器
5. THE Frontend SHALL 将各页面组件中的硬编码模拟数据替换为 API 调用，使用 React 的 useState 和 useEffect 管理数据获取状态

### 需求 16：分页与筛选标准化

**用户故事：** 作为前端开发者，我希望前后端采用统一的分页和筛选参数规范，以便各列表页面的数据交互保持一致。

#### 验收标准

1. THE API_Server SHALL 对所有列表接口采用统一的分页参数格式：page（页码，从1开始）、pageSize（每页条数，默认10）
2. THE API_Server SHALL 对所有列表接口返回统一的分页响应格式，包含 total（总记录数）、page（当前页码）、pageSize（每页条数）、records（数据列表）
3. THE API_Server SHALL 对所有筛选参数进行服务端校验，无效参数返回 400 错误码和描述性错误消息
4. WHEN 筛选条件为空或为"全部"时，THE API_Server SHALL 返回不带该条件过滤的完整数据集

### 需求 17：采集板校准文件管理

**用户故事：** 作为上位机（校准设备PC端软件）操作员，我希望在完成采集板校准后将校准文件上传到设备管理平台，并通过采集板SN号自动匹配关联，以便前端板卡详情中可以查看和下载校准文件。

#### 验收标准

1. THE Database SHALL 包含 `dev.calibration_files` 表，存储校准文件信息（采集板SN号、原始文件名、存储路径、文件大小（字节）、文件MD5校验值、上传时间），并包含标准审计字段
2. WHEN 上位机请求 POST `/api/portal/calibration-files/upload` 并携带采集板SN号和校准文件时，THE API_Server SHALL 保存校准文件到服务器存储目录，并在 `dev.calibration_files` 表中创建关联记录
3. WHEN 上传校准文件时，THE API_Server SHALL 通过采集板SN号匹配 `dev.board_cards` 表中的板卡实例记录，将校准文件与对应的采集板关联
4. IF 上传请求中的采集板SN号在 `dev.board_cards` 表中不存在，THEN THE API_Server SHALL 返回 404 错误码和描述性错误消息
5. THE API_Server SHALL 将校准文件上传接口注册在 `api-portal` 模块中，该接口无需登录鉴权
6. WHEN 前端请求 GET `/api/admin/board-cards/{id}/calibration-files` 时，THE API_Server SHALL 返回指定采集板关联的校准文件列表，每条记录包含 id、fileName（原始文件名）、fileSize（文件大小）、md5（校验值）、uploadTime（上传时间）字段，按上传时间倒序排列
7. WHEN 前端请求 GET `/api/admin/calibration-files/{id}/download` 时，THE API_Server SHALL 返回校准文件的下载流，响应头包含正确的文件名和 Content-Type
8. IF 请求下载的校准文件在存储目录中不存在，THEN THE API_Server SHALL 返回 404 错误码和描述性错误消息
9. THE Frontend SHALL 在板卡详情抽屉的校准信息区域中展示关联的校准文件列表，每条记录显示文件名、文件大小、上传时间，并提供下载按钮
10. WHEN 同一采集板SN号多次上传校准文件时，THE API_Server SHALL 保留所有历史校准文件记录，支持查看完整的校准文件历史
