日期:2026-10-03
状态:现状梳理(非改造设计)
用途:后续按新思路改代码前的权威对照基线;描述「当前代码实际如何工作」,而非「应当如何」。
覆盖模块:
| 菜单 | Hash 路由 | menuCode |
|---|---|---|
| 采集协议单 | /#/cell-storage/protocol-audit |
biz:cellStorageProtocolAudit:list |
| 样本信息管理 | /#/cell-storage/sample-info |
cell-storage:sample-info:list |
| 缴退费财务确认及开票 | /#/cell-storage/payment-confirm |
biz:cellStoragePaymentConfirm:list |
需求权威:docs/中科兴皖需求V0.3.md §2.2.6~2.2.9
相关设计文档(增量能力):
docs/superpowers/specs/2026-05-13-cell-storage-protocol-modules-design.md(早期模块设计)docs/superpowers/specs/2026-05-19-protocol-donation-convert-design.md(转科研)docs/superpowers/specs/2026-06-04-protocol-pay-mode-switch-design.md(缴费模式切换,若存在)docs/superpowers/specs/2026-06-17-protocol-invoice-request-design.md(开票)docs/superpowers/specs/2026-06-01-sample-qc-sms-notification-design.mddocs/superpowers/specs/2025-05-23-storage-entry-sms-notification-design.mdopenspec/changes/zkxw-engineering-standards/specs/api-conventions/spec.md(细胞存储样本跨表关联键)采集协议单是源头。创建后并行两条线:
┌──────────────────── 细胞存储 ────────────────────┐
│ 【采集协议单】 合同 + 客户 + 样本源头 + 缴费配置 │
│ │ │
│ ├──────────────┬─────────────────────────┤
│ ▼ ▼ │
│ 【样本信息管理】 【缴退费财务确认及开票】 │
│ 只读运营台+短信 财务终审+开票完成 │
│ │ ▲ │
│ ▼ │ 业务侧发起 │
│ 接收→质检→生产→入库 缴费信息 Tab / 满月待办 │
└──────────────────────────────────────────────────┘
| 模块 | 角色 | 本质 |
|---|---|---|
| 采集协议单 | 市场/采集专员 | 主单据 CRUD、状态变更、缴费发起、开票申请入口 |
| 样本信息管理 | 运营 | 只读查询台 + 线下短信提取/标记(不登记接收、不做质检入库操作) |
| 缴退费财务确认及开票 | 财务 | 收款/退费确认 + 开票完成 |
菜单演进:样本相关 Tab、缴费确认、开票已从早期「单一协议管理页」拆出;隐藏路由仍保留 protocol(录入表格版)、payment-info 等兼容入口。
biz_collection_protocol (1)
├── biz_protocol_party_customer (1) 当事人/客户
├── biz_protocol_collection_info (1) 采集信息
├── biz_protocol_sample (N)
│ └── biz_protocol_sample_transport
├── biz_protocol_payment (1)
│ └── biz_protocol_payment_detail (N)
├── biz_protocol_audit (N) 审核记录(不改协议状态)
├── biz_protocol_storage_cert
├── biz_protocol_fullmoon_todo
├── biz_protocol_invoice_request (N)
│ └── biz_protocol_invoice_request_item (N)
└── biz_protocol_donation_convert (0..1) 与科研捐赠互转
关联键 = tenant_no + sample_code
禁止用 collection_protocol_id / protocol_sample_id 做业务匹配
原因:协议编辑可能重建样本行 id;协议可转科研;样本编码不变。接收防重、详情回显、质检/入库 JOIN 均按此规则。
| 字段 | 含义 |
|---|---|
protocol_no / protocol_no_id |
协议号(可自动分配号池) |
protocol_status |
dsx 待生效 / sxz 生效中 / ygq 已过期 / yzf 已作废 / sdfq 属地废弃 / zky 转科研 |
protocol_attachments / consent_form_urls / health_survey_form_urls |
附件 URL 逗号分隔 |
void_type |
作废类型(字典);作废时必填 |
collector_user_id |
采集专员 |
effective_* / expire_* / void_* / to_research_* |
各状态变更时间与描述 |
无效态 yzf / sdfq:下游接收、生产列表会过滤。
web-admin/src/views/cell-storage/
├── protocol/ # 隐藏录入列表
│ ├── index.vue
│ ├── ProtocolFormDialog.vue # 新增/编辑大表单(权威录入)
│ ├── ProtocolViewDialog.vue
│ ├── ProtocolAuditDialog.vue
│ └── ProtocolStatusChangeDialog.vue
└── protocol-audit/ # 主管理页
├── index.vue # Pill Tab
├── ProtocolAuditTab.vue
├── PaymentInfoTab.vue # 业务侧缴费看板
├── StorageCertTab.vue
├── FullmoonTodoTab.vue # 满月保险 + 开票申请入口
└── Sample*InfoTab.vue # 被 sample-info 复用
API:web-admin/src/api/collection-protocol.ts
创建 → [dsx] 待生效
│ 协议生效
▼
[sxz] 生效中 ──┬── 过期 → [ygq]
├── 作废 → [yzf](须 voidType)
├── 属地废弃 → [sdfq]
└── 转科研 → [zky](convert API,建捐赠单)
biz_protocol_audit(shtg/shth),不驱动 protocol_status。allocate_next_biz_no;已存在不可改。_persist_protocol_sub_resources(backend/app/api/collection_protocol.py):
1. party_customer(可 upsert biz_customer)
2. collection_info
3. payment + payment_details ← 必须在样本之前
4. samples(含运输)
5. storage_cert
原因:缴费校验失败时不得已占用样本编码。创建失败补偿 soft_delete_collection_protocol。
| Tab | 主要字段 | payload 路径 |
|---|---|---|
| 基本信息 | 协议状态*、登记日、采集专员、备注、三类附件 | 主表字段 + attachments |
| 采集信息 | 地区、医院、医护、销售、样本/母血采集时间 | collectionInfo |
| 样本及运输 | 类型、编码、价格、年限、状态、特殊标记、运输 | samples[] + transport |
| 客户信息 | 关联客户、母亲/父亲/新生儿全套 | partyCustomer |
| 缴费信息 | 模式、合同额、分期参数、明细行 | payment + paymentDetails |
formRules 仅强制 protocolStatus。sample-transport-form-section(样本+运输权威 UI)。提交前前端校验顺序:
djfq 仅 2 样本)usedInProtocol 占用拦截syncFqPaymentDetailRowCount → POST/PUTweb-admin/src/utils/protocol-payment-presets.ts:
| 有效样本数(≠ yzf) | 可选模式 | 合同金额示例 |
|---|---|---|
| 1 | dj / fq |
趸交 22880;分期 25880(6 期) |
| 2 | dj / djfq / fq |
趸交 37880;趸交+分期 41000;分期 44000 |
前端:protocol-pay-mode-switch.ts
后端:protocol_pay_mode_switch.py(LOCKED_STATUSES / BLOCKING_STATUSES)
| 从 → 到 | 条件 | 结果 |
|---|---|---|
| 任意 | 存在进行中确认(前端还拦 ytf) |
阻断 |
dj → fq/djfq |
已有锁定明细 | 阻断 |
dj → fq/djfq |
全待缴 | 确认后按期数重建 |
fq/djfq → dj |
已全部缴清 | 阻断 |
fq/djfq → dj |
有已缴+未缴 | 保留 yjf,作废 dfj,新增剩余趸交 |
fq ↔ djfq |
已有锁定 | 阻断;否则重建 |
后端保存 P0:jfqrz/tfqrz 禁止保存;分期条数=期数;比例合计 100%;期数不少于已缴最大期次。
注意:前端 BLOCKING 含 ytf,后端不含(已退费允许随协议保存只读明细)。
| 路径 | 角色 |
|---|---|
backend/app/api/collection_protocol.py |
协议/缴费/储存证/满月/开票 API |
backend/app/crud/collection_protocol.py |
核心 CRUD(约 3900+ 行) |
backend/app/services/protocol_pay_mode_switch.py |
缴费校验 |
backend/app/crud/collection_protocol_no.py |
协议号池 |
backend/app/models/models.py |
ORM |
不是样本录入页,不是接收/质检/入库操作台。
是协议样本的 全链路查询 + 客户短信触达台(组件复用自 protocol-audit/):
| Tab | 职责 | 短信 |
|---|---|---|
| 样本采集信息 | 采集进度 | 无 |
| 样本接收信息 | 接收结论 | 有 |
| 样本质检信息 | 入库质检结论 | 有 |
| 样本入库信息 | 入库/拒入库 | 有 |
深链:?tab=sample-collection|sample-reception|sample-qc|storage-entry
旧路由 sample-reception-info / storage-entry-info 重定向到本页。
sample_status(空) 未采集 → ycj 已采集 → jcz 检测中 → yrk 已入库
任意 → yzf 已作废
ycj。sample_status。store_sample 按 sample_code 回写 yrk + storage_in_date。yrk → 回退 jcz,清空 storage_in_date。接收结论 = js 时(create_sample_reception):
写 biz_sample_reception + 检查项
→ create_work_order_from_reception # 入库质检工单 dpz
→ create_production_work_order_from_reception
→ try_auto_dispatch_builtin_tasks… # 内置任务派发
→ create_review_from_reception # 入库放行审核 drk
结论 = bj:只写接收,不创建工单/审核。
防重:tenant_no + reception_source + sample_code。
实验室入库编码:结论为 js 时必填且租户唯一。
backend/app/services/qc_work_order_conclusion.py:
任一任务 conclusion == btg → 工单 btg
全部任务 conclusion == tg → 工单 tg
否则 → ""(尚无结论)
工单状态:dpz → ypz →(全部任务 ywc)ywc 并落库 wo.conclusion。
try_reopen_work_order:回退 ypz,清空 conclusion。
质检 Tab 列表派生(_qc_status_label):
| 条件 | 码 |
|---|---|
| 无工单等 | dzj 待质检 |
ypz |
zjz 质检中 |
ywc + tg/btg |
tg / btg |
ywc 结论未齐 |
zjz |
工单 yzf |
yzf |
协议详情回显:get_qc_info_map_for_samples 细胞存储侧必须按 sample_code 关联(trigger_source=reception)。
submit_review(production / qc 两侧):
btg → 聚合 btgtg → 聚合 tg → storage_transition = store → store_samplebtg → unstore前置:生产与质检均通过且 storage_status=drk 才能入库。
系统不自动发送。运营:提取文案 → 复制 → 线下发 → 标记已通知。
| Tab | 模板要点 |
|---|---|
| 接收 | 已于{日期}完成接收,结论:{接收/拒收} |
| 质检 | 合格 / 未通过;未完成返回「暂无短信内容…」 |
| 入库 | 已入库日期 / 审核未通过;待确认暂无内容 |
| 路径 | 角色 |
|---|---|
web-admin/.../sample-info/index.vue |
壳页 |
web-admin/.../protocol-audit/Sample*InfoTab.vue |
四 Tab |
backend/app/api/protocol_sample_collection.py |
采集列表 |
backend/app/api/sample_sms_notification.py 等 |
三短信 API |
backend/app/crud/sample_reception.py |
接收写库 |
backend/app/crud/qc_work_order.py |
质检工单 |
backend/app/crud/storage_release_review.py |
入库放行 |
业务(缴费信息 / 满月待办) 财务(本模块)
提交缴费确认 dfj→jfqrz → 确认收款 → yjf(或退回→dfj)
提交退费确认 yjf→tfqrz → 确认退费 → ytf(或退回→yjf)
发起开票申请 → dkp → 完成开票 → ykp(上传发票)
前端:
payment-confirm/index.vue(缴费确认)RefundConfirmTab.vueInvoiceRequestTab.vuePaymentInfoTab.vue、FullmoonTodoTab.vuepay_status)dfj → jfqrz → yjf → tfqrz → ytf
↑退回 ↑退回
| 状态 | 业务可做 | 财务可做 | 关键写入 |
|---|---|---|---|
dfj |
编辑草稿、提交确认 | — | 转账方式/金额/时间/凭证 |
jfqrz |
— | 确认/退回 | finance_* → yjf 或 → dfj |
yjf |
发起退费 | — | refund_* → tfqrz |
tfqrz |
— | 确认/退回 | refundfinance* → ytf 或 → yjf |
ytf |
— | — | 终态 |
提交收款强制:转账方式非空 + transfer_amount > 0。
提交退费强制:仅 yjf + refund_amount > 0。
注意:批量提交收款不跑单条草稿完整性校验(假定已是合格 dfj)。
pay_status)可开票 = pay_status=yjf AND 明细未在有效申请子表(dkp|ykp)
金额 = Σ transfer_amount(快照 line_amount / invoice_amount)
完成 = 仅 dkp + 发票附件必填 → ykp
不做 = 驳回、冲红、改缴费状态、结构化发票号/日期
函数:create_invoice_request / complete_invoice_request / list_invoice_eligible_payment_details。
| 模块 | 差异 |
|---|---|
| 临床缴退费财务确认 | biz_pilot_payment;无开票 Tab |
| 渠道服务订单财务确认 | 另一套流水状态机 |
zky)边界入口:research_donation.convert_from_storage。
sxzbiz_protocol_donation_convert| 拷贝 | 不拷贝 |
|---|---|
捐赠主单(同号 donation_no) |
缴费主表/明细 |
| party / collection | 审核 / 开票 / 储存证 / 满月 |
| samples(同 sample_code)+ transports | 接收/质检/入库审核记录 |
源协议 → zky + to_research_*;写关联表 convert_type=storage_to_research。
配对后两边可暂共用 sample_code;保存唯一性对配对 ID 豁免(get_partner_sample_codes)。
之后两边可各自改号,不自动同步;关联表 biz_no 只留转移快照。
产品含义:转科研是合同形态切换,不是财务结算迁移;退费/开票仍对原协议缴费明细。
协议保存
客户 → 采集 →【缴费校验+明细】→ 样本编码占用 → 储存证
│ │
▼ ▼
缴费明细状态机 sample_code
dfj→jfqrz→yjf→… │
│ ▼
│ 接收(js) → QC + 生产 + 入库审核(drk)
│ │
▼ ▼ 双审 tg
财务确认 / 开票(dkp→ykp) store → sample_status=yrk
转科研(sxz→zky):新捐赠同号同码;缴费不跟走
tenant_no + sample_code,勿用样本行 id 做业务匹配。pay_status。ytf)。#10b981),勿混小程序三墙绿。| 模块 | 路径 |
|---|---|
| 协议主页 | web-admin/src/views/cell-storage/protocol-audit/ |
| 协议表单 | web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue |
| 样本信息 | web-admin/src/views/cell-storage/sample-info/index.vue |
| 财务确认 | web-admin/src/views/cell-storage/payment-confirm/ |
| API | web-admin/src/api/collection-protocol.ts 等 |
| 缴费工具 | web-admin/src/utils/protocol-payment-*.ts、protocol-pay-mode-switch.ts |
| 路由 | web-admin/src/router/modules/sqxp.ts |
| 模块 | 路径 |
|---|---|
| 协议 API/CRUD | backend/app/api/collection_protocol.py、crud/collection_protocol.py |
| 样本采集列表 | api/protocol_sample_collection.py、crud/protocol_sample_collection.py |
| 接收 | crud/sample_reception.py |
| 质检 | crud/qc_work_order.py、services/qc_work_order_conclusion.py |
| 入库 | crud/storage_release_review.py |
| 短信 | crud/sample_sms_notification.py、qc_sms_notification.py、storage_entry_sms_notification.py |
| 转科研 | crud/research_donation.py(convert_from_storage)、crud/protocol_donation_convert.py |
| 缴费模式 | services/protocol_pay_mode_switch.py |
docs/superpowers/specs/YYYY-MM-DD-*-design.md。_row_to_dict、前端 formData(见 docs/dev-field-consistency.md)。文档维护:若实现偏离本文描述,请同步更新本节或标注「已失效段落」,避免后续改码基于过时基线。