状态:待评审 日期:2025-05-23 需求来源:客户提出"样本入库也需要给客户发短信"
客户已完成样本接收信息页面(/cell-storage/sample-reception-info),用于管理样本接收后的短信通知(提取短信内容 → 复制到剪贴板 → 用户线下发送)。现需增加样本入库信息页面,在样本完成入库(或拒绝入库)后提供同样的短信通知管理能力。
核心模式:克隆样本接收信息的完整链路(前端页面 + 后端 API + 独立通知表),调整为入库场景。
关键约束:短信不通过系统自动发送,由用户线下手动发送。系统只负责生成短信内容供复制。
| 决策项 | 选择 | 理由 |
|---|---|---|
| 数据范围 | 已入库(yrk) + 拒绝入库(review_conclusion='btg') |
展示最终结果的记录 |
| 短信模板 | 系统预设,后续可调 | 先上线后迭代 |
| 页面位置 | 细胞存储模块下,与样本接收信息同级 | 用户操作习惯一致 |
| 查看弹窗 | 复用 ProtocolViewDialog |
与样本接收信息一致,查看协议完整信息 |
| 后端存储 | 新建独立表 | 代码独立,不影响现有功能 |
数据源为 biz_storage_release_review 表,筛选条件:
storage_status = 'yrk'(已入库),或review_conclusion = 'btg'(审核不通过/拒绝入库)不展示 storage_status = 'drk'(待入库)且审核未出结论的记录。
重要:仅展示 reception_source = 'cell_storage'(细胞存储)的记录,不包含科研捐赠来源的数据。此过滤条件同时应用于「样本接收信息」和「样本入库信息」两个页面。
新建表 biz_storage_entry_sms_notification:
CREATE TABLE biz_storage_entry_sms_notification (
id VARCHAR(64) NOT NULL COMMENT 'UUID主键',
storage_review_id VARCHAR(64) NOT NULL COMMENT '关联 biz_storage_release_review.id',
protocol_id VARCHAR(64) DEFAULT NULL COMMENT '冗余协议单ID',
sms_content VARCHAR(500) DEFAULT NULL COMMENT '生成的短信内容',
sms_notified TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0=未通知 1=已通知',
notified_by VARCHAR(64) DEFAULT NULL COMMENT '通知操作人ID',
notified_by_name VARCHAR(64) DEFAULT NULL COMMENT '通知操作人姓名',
notified_time DATETIME DEFAULT NULL COMMENT '通知操作时间',
tenant_no VARCHAR(64) DEFAULT NULL COMMENT '租户编号',
order_num INT DEFAULT 0 COMMENT '排序',
remark VARCHAR(512) DEFAULT NULL COMMENT '备注',
create_by VARCHAR(64) DEFAULT NULL,
create_dept_id VARCHAR(64) DEFAULT NULL,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_by VARCHAR(64) DEFAULT NULL,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
del_flag CHAR(1) DEFAULT '0' COMMENT '0=正常 1=删除',
PRIMARY KEY (id),
KEY idx_storage_review_id (storage_review_id),
KEY idx_tenant_no (tenant_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='样本入库短信通知';
在 backend/app/models/models.py 追加 BizStorageEntrySmsNotification,字段与表结构对应。
新建 backend/app/crud/storage_entry_sms_notification.py,克隆 sample_sms_notification.py 并调整:
BizStorageReleaseReview LEFT JOIN BizStorageEntrySmsNotification(通过 storage_review_id + tenant_no) LEFT JOIN BizCollectionProtocol LEFT JOIN BizProtocolPartyCustomer LEFT JOIN BizProtocolSampledel_flag=0,reception_source='cell_storage',(storage_status='yrk' OR review_conclusion='btg'),租户隔离,数据权限(apply_data_scope)sms_notified=0)_row_to_dict():蛇形→驼峰,返回前端所需字段已入库:尊敬的{母亲}女士,您的样本(编码:{code})已于{date}完成入库处理。如有疑问请联系客服。
拒绝入库:尊敬的{母亲}女士,您的样本(编码:{code})入库审核未通过。如有疑问请联系客服。
变量来源:
{母亲}:BizProtocolPartyCustomer.mother_name{code}:BizStorageReleaseReview.sample_code{date}:入库时间 storage_time(拒绝入库用审核时间 review_time)新建 backend/app/api/storage_entry_sms_notification.py,前缀 /api/web/admin:
| 方法 | 路径 | 功能 | 权限码 |
|---|---|---|---|
| GET | /storage-entry-sms-notifications/list |
分页列表 | cell-storage:storage-entry-info:list |
| PUT | /storage-entry-sms-notifications/{id}/toggle-status |
切换通知状态 | 同上 |
| POST | /storage-entry-sms-notifications/{id}/generate-sms |
生成短信内容 | 同上 |
路由注册:backend/app/api/__init__.py + backend/app/main.py。
在 web-admin/src/router/modules/sqxp.ts 的 CellStorage 子项下添加:
path: 'storage-entry-info'
name: 'CellStorageStorageEntryInfo'
component: '/cell-storage/storage-entry-info/index'
meta: { title: '样本入库信息', keepAlive: true, menuCode: 'cell-storage:storage-entry-info:list' }
新建 web-admin/src/api/storage-entry-sms-notification.ts,3 个函数:
fetchStorageEntrySmsList(params) → GET /storage-entry-sms-notifications/listfetchToggleStorageEntrySmsNotified(id, data) → PUT /storage-entry-sms-notifications/{id}/toggle-statusfetchGenerateStorageEntrySms(id) → POST /storage-entry-sms-notifications/{id}/generate-sms新建 web-admin/src/views/cell-storage/storage-entry-info/index.vue,克隆 sample-reception-info/index.vue 并调整:
筛选区:
| 字段 | 控件 | 绑定 |
|---|---|---|
| 关键词 | el-input | keyword(协议号/姓名/样本编码) |
| 入库状态 | el-select | storageStatus(已入库 yrk / 拒绝入库 btg) |
| 通知状态 | el-select | smsNotified(已通知 1 / 未通知 0) |
表格列(全部 min-width,align="center"):
| 列 | prop | 宽度 | 说明 |
|---|---|---|---|
| 序号 | type=index | 68 | 自动序号 |
| 协议号 | protocolNo | 140 | |
| 母亲姓名 | motherName | 100 | |
| 新生儿姓名 | newbornName | 110 | show-overflow-tooltip |
| 样本编码 | sampleCode | 130 | |
| 样本类型 | sampleTypeName | 110 | |
| 入库时间 | storageTime | 170 | 已入库显示入库时间,拒绝入库显示审核时间 |
| 入库状态 | storageStatusLabel | 100 | el-tag:已入库=success,拒绝入库=danger |
| 通知状态 | smsNotified | 100 | el-tag:已通知=success,未通知=info |
| 操作 | — | 260 | fixed="right" |
操作按钮:
<el-icon><View /></el-icon> — 打开 ProtocolViewDialog(含 show-audit-history、show-storage-cert)<el-icon><ChatDotRound /></el-icon> — 调用 fetchGenerateStorageEntrySms,复制到剪贴板<el-icon><Bell /></el-icon> — 调用 fetchToggleStorageEntrySmsNotified交互:双击行 → handleView,分页 [10, 20, 50]
App.vue:在 panelTitleBarTextRules 注册「样本入库列表」标题文案cell-storage:storage-entry-info:list| 场景 | 处理方式 |
|---|---|
拒绝入库记录无 storageTime |
短信模板用 review_time 替代,表格列也显示审核时间 |
| 协议单为空 | 查看按钮提示"缺少关联协议单",不打开弹窗 |
| 文件 | 说明 |
|---|---|
docs/sql/biz_storage_entry_sms_notification.sql |
建表 DDL |
backend/app/crud/storage_entry_sms_notification.py |
CRUD 层(联查+懒创建+短信生成) |
backend/app/api/storage_entry_sms_notification.py |
API 路由(3 个端点) |
web-admin/src/api/storage-entry-sms-notification.ts |
前端 API 封装 |
web-admin/src/views/cell-storage/storage-entry-info/index.vue |
前端页面 |
| 文件 | 修改内容 |
|---|---|
backend/app/models/models.py |
追加 BizStorageEntrySmsNotification 模型 |
backend/app/api/__init__.py |
注册新路由 |
backend/app/main.py |
挂载新路由 |
web-admin/src/router/modules/sqxp.ts |
添加路由条目(CellStorage 子项) |
sample-reception-info 任何逻辑