151 lines
6.2 KiB
Markdown
151 lines
6.2 KiB
Markdown
# 样本特殊标记 Implementation Plan
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** 在采集/捐赠协议单样本上维护 `isSpecial` + `specialRemark`,并在 web-admin 全链路只读展示红色加粗警示。
|
||
|
||
**Architecture:** 字段仅存 `biz_protocol_sample` / `biz_research_donation_sample`;下游 API JOIN 源表补字段;前端 `SpecialSampleDisplay` 统一渲染。
|
||
|
||
**Tech Stack:** FastAPI + SQLAlchemy + Vue 3 + Element Plus
|
||
|
||
**Spec:** `docs/superpowers/specs/2026-07-01-special-sample-mark-design.md`
|
||
|
||
---
|
||
|
||
## File Map
|
||
|
||
| 文件 | 职责 |
|
||
|------|------|
|
||
| `docs/sql/migrate-special-sample-mark.sql` | DDL 增量脚本 |
|
||
| `backend/app/utils/sample_special.py` | 校验 + dict 转换工具 |
|
||
| `backend/app/models/models.py` | `BizProtocolSample` 新列 |
|
||
| `backend/app/models/research_donation.py` | `BizResearchDonationSample` 新列 |
|
||
| `backend/app/crud/collection_protocol.py` | `_sample_to_dict` / `save_samples` / list sampleItems |
|
||
| `backend/app/crud/research_donation.py` | 同上 + 转存储复制 |
|
||
| `backend/app/crud/qc_work_order.py` | `_enrich_work_order_list_items` 补字段 |
|
||
| `backend/app/crud/sample_reception.py` | 待/已接收 list item |
|
||
| `backend/app/crud/protocol_sample_collection.py` | 样本采集信息 list |
|
||
| `backend/app/crud/research_donation_sample_collection.py` | 捐赠样本采集 list |
|
||
| `backend/app/crud/pre_transit_sample.py` | 转运前样本卡片 items |
|
||
| `backend/app/crud/storage_release_review.py` | 入库审核 detail |
|
||
| `backend/app/crud/cell_product.py` | 溯源链样本信息 |
|
||
| `web-admin/src/components/business/special-sample-display/index.vue` | 公共展示组件 |
|
||
| `web-admin/src/components/business/sample-transport-form-section/index.vue` | 录入 |
|
||
| `web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue` | 采集查看 |
|
||
| `web-admin/src/views/research-donation/list/DonationViewDialog.vue` | 捐赠查看 |
|
||
| 下游 15+ vue 页面 | 样本编码旁 inline 展示 |
|
||
|
||
---
|
||
|
||
## Task 1: 数据库与 Model
|
||
|
||
**Files:**
|
||
- Create: `docs/sql/migrate-special-sample-mark.sql`
|
||
- Modify: `backend/app/models/models.py`, `backend/app/models/research_donation.py`
|
||
|
||
- [ ] **Step 1:** 执行 DDL(两表对称)
|
||
|
||
```sql
|
||
ALTER TABLE `biz_protocol_sample`
|
||
ADD COLUMN `is_special` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否特殊样本:0否 1是' AFTER `storage_expire_date`,
|
||
ADD COLUMN `special_remark` varchar(256) DEFAULT NULL COMMENT '特殊说明' AFTER `is_special`;
|
||
|
||
ALTER TABLE `biz_research_donation_sample`
|
||
ADD COLUMN `is_special` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否特殊样本:0否 1是' AFTER `storage_expire_date`,
|
||
ADD COLUMN `special_remark` varchar(256) DEFAULT NULL COMMENT '特殊说明' AFTER `is_special`;
|
||
```
|
||
|
||
- [ ] **Step 2:** ORM 增加 `is_special = Column(SmallInteger...)` 与 `special_remark = Column(String(256)...)`
|
||
|
||
---
|
||
|
||
## Task 2: 后端工具与核心 CRUD
|
||
|
||
**Files:**
|
||
- Create: `backend/app/utils/sample_special.py`
|
||
- Modify: `backend/app/crud/collection_protocol.py`, `backend/app/crud/research_donation.py`
|
||
|
||
- [ ] **Step 1:** 创建工具函数
|
||
|
||
```python
|
||
def sample_special_to_dict(sample) -> Dict[str, Any]: ...
|
||
def validate_sample_special_raw(raw: dict, *, index: Optional[int] = None) -> None: ...
|
||
def apply_sample_special_fields(obj, raw: dict) -> None: ...
|
||
```
|
||
|
||
- [ ] **Step 2:** `_sample_to_dict` 增加 `isSpecial` / `specialRemark`
|
||
|
||
- [ ] **Step 3:** `save_samples` / `_create_samples` 循环内调用 `validate_sample_special_raw` + `apply_sample_special_fields`
|
||
|
||
- [ ] **Step 4:** `research_donation.py` 转存储复制 `is_special`、`special_remark`
|
||
|
||
- [ ] **Step 5:** `collection_protocol.py` 列表 `sampleItems` 构建补字段
|
||
|
||
---
|
||
|
||
## Task 3: 下游 CRUD API
|
||
|
||
**Files:** `sample_reception.py`, `protocol_sample_collection.py`, `research_donation_sample_collection.py`, `pre_transit_sample.py`, `qc_work_order.py`, `storage_release_review.py`, `cell_product.py`
|
||
|
||
- [ ] **Step 1:** 凡已有 `BizProtocolSample` / `BizResearchDonationSample` 对象处,`item.update(sample_special_to_dict(sample))`
|
||
|
||
- [ ] **Step 2:** `qc_work_order._enrich_work_order_list_items` 在 `sampleTypeName` 赋值后补 special 字段(覆盖质检+生产工单)
|
||
|
||
---
|
||
|
||
## Task 4: 前端公共组件与录入
|
||
|
||
**Files:**
|
||
- Create: `web-admin/src/components/business/special-sample-display/index.vue`
|
||
- Modify: `web-admin/src/components/business/sample-transport-form-section/index.vue`
|
||
|
||
- [ ] **Step 1:** 创建 `SpecialSampleDisplay`(`v-if="isSpecial"`,danger 色加粗)
|
||
|
||
- [ ] **Step 2:** 样本子弹窗增加 checkbox + textarea;取消勾选清空说明
|
||
|
||
- [ ] **Step 3:** `confirmSampleDialog` 校验:`isSpecial && !specialRemark.trim()` → warning
|
||
|
||
- [ ] **Step 4:** 列表增加「特殊样本」列;`openAddSampleDialog` 初始化 `isSpecial: false, specialRemark: ''`
|
||
|
||
- [ ] **Step 5:** `normalizeSampleRow` 保留 `isSpecial` / `specialRemark`
|
||
|
||
---
|
||
|
||
## Task 5: 协议查看弹窗
|
||
|
||
**Files:** `ProtocolViewDialog.vue`, `DonationViewDialog.vue`
|
||
|
||
- [ ] **Step 1:** 样本卡片 header inline 展示 `SpecialSampleDisplay`
|
||
|
||
---
|
||
|
||
## Task 6: 下游展示页面(P1 全量)
|
||
|
||
在样本编码列/标题行旁接入 `SpecialSampleDisplay`:
|
||
|
||
- [ ] `ProtocolAuditTab.vue`, `PreTransitProtocolCardList.vue`
|
||
- [ ] `research-donation/audit/index.vue`
|
||
- [ ] `SampleCollectionInfoTab.vue`, `DonationSampleCollectionInfoTab.vue`
|
||
- [ ] `sample-reception/index.vue`, `SampleReceptionCardList.vue`
|
||
- [ ] `QcWorkOrderProtocolGroup.vue`, `QcWorkOrderSampleGroup.vue`, `QcWorkOrderTaskSubList.vue`
|
||
- [ ] `storage-release-review/index.vue`, `StorageReleaseReviewDialog.vue`, `StorageReleaseViewDialog.vue`
|
||
- [ ] `ProductionWorkOrderCardList.vue`, `SampleReceptionDialog.vue`, `DispatchTaskDialog.vue`
|
||
- [ ] `SampleCustomerViewDialog.vue`
|
||
|
||
---
|
||
|
||
## Task 7: 验证
|
||
|
||
- [ ] 本地执行 `docs/sql/migrate-special-sample-mark.sql`
|
||
- [ ] `python scripts/check_field_consistency.py`
|
||
- [ ] `./scripts/update-graph.sh frontend` + `backend`
|
||
- [ ] 手工:协议单录入特殊样本 → 查看弹窗 → 样本接收/质检卡片可见红色标记
|
||
|
||
---
|
||
|
||
## 部署前
|
||
|
||
1. 执行 `docs/sql/migrate-special-sample-mark.sql`
|
||
2. 重启 backend
|
||
3. 刷新 web-admin
|