docs: add cell storage protocol modules design for 2.2.6–2.2.10
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
058811ae77
commit
246ad2228e
153 files changed
+20578
-2040
No files matched your search
@@ -0,0 +1,20 @@
|
||||
-- 组织管理初始化数据(需求 2.1.3)
|
||||
-- 市场营销部门下设:采集部、临床部、中试服务部、支持中心、客服部
|
||||
|
||||
SET @marketing_id = UUID();
|
||||
|
||||
INSERT INTO sys_dept (id, parent_id, dept_name, dept_category_code, status, leader, leader_phone, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
(UUID(), '0', '中科兴皖', 'gs', '1', NULL, NULL, 'zkxw', 0, '', 0),
|
||||
(@marketing_id, '0', '市场营销部门', 'bm', '1', NULL, NULL, 'zkxw', 1, '', 0),
|
||||
(UUID(), '0', '技术研发部', 'bm', '1', NULL, NULL, 'zkxw', 2, '', 0),
|
||||
(UUID(), '0', '生产部', 'bm', '1', NULL, NULL, 'zkxw', 3, '', 0),
|
||||
(UUID(), '0', '质量安全部', 'bm', '1', NULL, NULL, 'zkxw', 4, '', 0),
|
||||
(UUID(), '0', '财务部', 'bm', '1', NULL, NULL, 'zkxw', 5, '', 0),
|
||||
(UUID(), '0', '综合部', 'bm', '1', NULL, NULL, 'zkxw', 6, '', 0);
|
||||
|
||||
INSERT INTO sys_dept (id, parent_id, dept_name, dept_category_code, status, leader, leader_phone, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
(UUID(), @marketing_id, '采集部', 'bm', '1', NULL, NULL, 'zkxw', 1, '', 0),
|
||||
(UUID(), @marketing_id, '临床部', 'bm', '1', NULL, NULL, 'zkxw', 2, '', 0),
|
||||
(UUID(), @marketing_id, '中试服务部', 'bm', '1', NULL, NULL, 'zkxw', 3, '', 0),
|
||||
(UUID(), @marketing_id, '支持中心', 'bm', '1', NULL, NULL, 'zkxw', 4, '', 0),
|
||||
(UUID(), @marketing_id, '客服部', 'bm', '1', NULL, NULL, 'zkxw', 5, '', 0);
|
||||
@@ -0,0 +1,24 @@
|
||||
-- ============================================================
|
||||
-- 字典管理初始数据(sys_dict_type / sys_dict_data)
|
||||
-- 执行前提:zkxw-requirements-v0.3-schema.sql 已建表
|
||||
-- ============================================================
|
||||
|
||||
-- 字典类型
|
||||
INSERT INTO sys_dict_type (id, dict_name, dict_type, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
(UUID(), '组织类别编码', 'zzlbbm', 'zkxw', 1, '', 0),
|
||||
(UUID(), '站点类型', 'zdlx', 'zkxw', 2, '', 0),
|
||||
(UUID(), '站点业务范围', 'zdywfw', 'zkxw', 3, '', 0),
|
||||
(UUID(), '部门状态', 'bmzt', 'zkxw', 4, '', 0);
|
||||
|
||||
-- 字典数据
|
||||
INSERT INTO sys_dict_data (id, dict_label, dict_value, dict_type, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
(UUID(), '公司', 'gs', 'zzlbbm', 'zkxw', 1, '', 0),
|
||||
(UUID(), '分公司', 'fgs', 'zzlbbm', 'zkxw', 2, '', 0),
|
||||
(UUID(), '部门', 'bm', 'zzlbbm', 'zkxw', 3, '', 0),
|
||||
(UUID(), '中心基地', 'zxjd', 'zdlx', 'zkxw', 1, '', 0),
|
||||
(UUID(), '样本采集', 'ybcj', 'zdywfw', 'zkxw', 1, '', 0),
|
||||
(UUID(), '样本制备', 'ybzb', 'zdywfw', 'zkxw', 2, '', 0),
|
||||
(UUID(), '质量检测', 'zljc', 'zdywfw', 'zkxw', 3, '', 0),
|
||||
(UUID(), '细胞存储', 'xbcc', 'zdywfw', 'zkxw', 4, '', 0),
|
||||
(UUID(), '停用', '0', 'bmzt', 'zkxw', 1, '', 0),
|
||||
(UUID(), '正常', '1', 'bmzt', 'zkxw', 2, '', 0);
|
||||
@@ -0,0 +1,24 @@
|
||||
-- 2.1.6 菜单管理初始化数据
|
||||
-- Web端根节点与移动端根节点,parent_id = 0
|
||||
|
||||
-- 根节点:Web端菜单、移动端菜单
|
||||
INSERT INTO sys_menu (id, menu_name, parent_id, menu_type, path, component, visible, status, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
('1', 'Web端菜单', '0', 'M', '/system', NULL, '1', '1', 'zkxw', 1, '', 0),
|
||||
('2', '移动端菜单', '0', 'M', '/mini', NULL, '1', '1', 'zkxw', 2, '', 0);
|
||||
|
||||
-- Web端菜单 - 系统管理目录
|
||||
INSERT INTO sys_menu (id, menu_name, parent_id, menu_type, path, component, perms, visible, status, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
('100', '系统管理', '1', 'M', '/system', '/index/index', NULL, '1', '1', 'zkxw', 1, '', 0);
|
||||
|
||||
-- 系统管理子菜单
|
||||
INSERT INTO sys_menu (id, menu_name, parent_id, menu_type, path, component, perms, visible, status, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
('101', '租户管理', '100', 'C', 'tenant', '/system/tenant/index', 'system:tenant:list', '1', '1', 'zkxw', 1, '', 0),
|
||||
('102', '字典管理', '100', 'C', 'dict', '/system/dict/index', 'system:dict:list', '1', '1', 'zkxw', 2, '', 0),
|
||||
('103', '组织管理', '100', 'C', 'dept', '/system/dept/index', 'system:dept:list', '1', '1', 'zkxw', 3, '', 0),
|
||||
('104', '用户管理', '100', 'C', 'user', '/system/user/index', 'system:user:list', '1', '1', 'zkxw', 4, '', 0),
|
||||
('105', '角色管理', '100', 'C', 'role', '/system/role/index', 'system:role:list', '1', '1', 'zkxw', 5, '', 0),
|
||||
('106', '菜单管理', '100', 'C', 'menu', '/system/menu/index', 'system:menu:list', '1', '1', 'zkxw', 6, '', 0),
|
||||
('107', '站点管理', '100', 'C', 'site', '/system/site/index', 'system:site:list', '1', '1', 'zkxw', 7, '', 0),
|
||||
('108', '职位管理', '100', 'C', 'post', '/system/post/index', 'system:post:list', '1', '1', 'zkxw', 8, '', 0),
|
||||
('109', '物品单位', '100', 'C', 'unit', '/system/unit/index', 'system:unit:list', '1', '1', 'zkxw', 9, '', 0),
|
||||
('110', '快递公司', '100', 'C', 'express', '/system/express/index', 'system:express:list', '1', '1', 'zkxw', 10, '', 0);
|
||||
@@ -0,0 +1,28 @@
|
||||
-- V0.3 角色初始数据
|
||||
-- sys_role_data_scope_detail 建表语句
|
||||
CREATE TABLE IF NOT EXISTS `sys_role_data_scope_detail` (
|
||||
`id` varchar(64) NOT NULL COMMENT '主键ID',
|
||||
`role_id` varchar(64) NOT NULL COMMENT '角色ID',
|
||||
`scope_type` varchar(20) NOT NULL COMMENT '范围类型:dept/user',
|
||||
`scope_value` varchar(100) NOT NULL COMMENT '范围值:部门ID/用户ID',
|
||||
`tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
|
||||
`order_num` int DEFAULT NULL COMMENT '排序号',
|
||||
`remark` varchar(512) DEFAULT NULL COMMENT '备注',
|
||||
`create_by` varchar(64) DEFAULT NULL COMMENT '创建人id',
|
||||
`create_dept_id` varchar(64) NOT NULL DEFAULT '' COMMENT '创建人部门ID',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` varchar(64) DEFAULT NULL COMMENT '更新人id',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` smallint NOT NULL DEFAULT '0' COMMENT '删除标记',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_role_id` (`role_id`),
|
||||
KEY `idx_tenant_no` (`tenant_no`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色自定义数据权限明细';
|
||||
|
||||
-- 角色初始数据
|
||||
INSERT INTO sys_role (id, role_name, data_scope, status, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
(UUID(), '超级管理员', '1', '1', 'zkxw', 1, '', 0),
|
||||
(UUID(), '运营管理员', '1', '1', 'zkxw', 2, '', 0),
|
||||
(UUID(), '采集专员', '2', '1', 'zkxw', 3, '', 0),
|
||||
(UUID(), '市场支持专员', '2', '1', 'zkxw', 4, '', 0),
|
||||
(UUID(), '质检专员', '2', '1', 'zkxw', 5, '', 0);
|
||||
@@ -0,0 +1,26 @@
|
||||
-- 站点、职位、物品单位、快递公司 初始化数据
|
||||
-- 对应模型:SysSite, SysPost, BizItemUnit, BizExpressCompany
|
||||
|
||||
-- 站点
|
||||
INSERT INTO sys_site (id, site_name, site_code, site_type, status, address, contact_name, contact_phone, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
(UUID(), '中科兴皖中心基地', 'zkxw-zxjd', 'zxjd', '1', '', NULL, NULL, 'zkxw', 1, '', 0);
|
||||
|
||||
-- 职位
|
||||
INSERT INTO sys_post (id, post_name, post_code, status, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
(UUID(), '采集专员', 'cjzy', '1', 'zkxw', 1, '', 0),
|
||||
(UUID(), '市场支持专员', 'sczczy', '1', 'zkxw', 2, '', 0),
|
||||
(UUID(), '质检专员', 'zjzy', '1', 'zkxw', 3, '', 0);
|
||||
|
||||
-- 物品单位
|
||||
INSERT INTO biz_item_unit (id, unit_code, unit_name, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
(UUID(), 'g', '克', 'zkxw', 1, '', 0),
|
||||
(UUID(), 'ml', '毫升', 'zkxw', 2, '', 0),
|
||||
(UUID(), 'ge', '个', 'zkxw', 3, '', 0),
|
||||
(UUID(), 'fen', '份', 'zkxw', 4, '', 0);
|
||||
|
||||
-- 快递公司
|
||||
INSERT INTO biz_express_company (id, express_code, express_name, tenant_no, order_num, create_dept_id, del_flag) VALUES
|
||||
(UUID(), 'sf', '顺丰速运', 'zkxw', 1, '', 0),
|
||||
(UUID(), 'jd', '京东快递', 'zkxw', 2, '', 0),
|
||||
(UUID(), 'zt', '中通快递', 'zkxw', 3, '', 0),
|
||||
(UUID(), 'yt', '圆通速递', 'zkxw', 4, '', 0);
|
||||
@@ -0,0 +1,24 @@
|
||||
-- zkxw-init-user-data.sql
|
||||
-- V0.3 用户管理初始化数据(测试用户)
|
||||
-- 默认 admin 用户已在骨架 SQL 中创建,此处补充测试账号
|
||||
-- 注意:密码需通过后端 API 创建以获得正确的 bcrypt hash
|
||||
|
||||
INSERT INTO sys_user (
|
||||
id, dept_id, user_no, nick_name, email, phone_no, sex,
|
||||
password, status, tenant_no, order_num,
|
||||
create_dept_id, create_by, create_time, update_by, update_time, del_flag
|
||||
) VALUES
|
||||
(
|
||||
REPLACE(UUID(),'-',''),
|
||||
(SELECT id FROM sys_dept WHERE dept_name='市场营销部' AND del_flag=0 LIMIT 1),
|
||||
'zhangsan', '张三', 'zhangsan@zkxw.com', '13800000001', '0',
|
||||
'$2b$12$placeholder_hash_use_api_to_set', '1', 'zkxw', 2,
|
||||
'', NULL, NOW(), NULL, NOW(), 0
|
||||
),
|
||||
(
|
||||
REPLACE(UUID(),'-',''),
|
||||
(SELECT id FROM sys_dept WHERE dept_name='市场营销部' AND del_flag=0 LIMIT 1),
|
||||
'lisi', '李四', 'lisi@zkxw.com', '13800000002', '1',
|
||||
'$2b$12$placeholder_hash_use_api_to_set', '1', 'zkxw', 3,
|
||||
'', NULL, NOW(), NULL, NOW(), 0
|
||||
);
|
||||
@@ -0,0 +1,159 @@
|
||||
# 细胞存储管理(2.2.6~2.2.10)— 实现设计(方案 C)
|
||||
|
||||
**依据**:`docs/中科兴皖需求V0.3.md` 菜单 2.2.6~2.2.10;数据模型 `docs/sql/zkxw-requirements-v0.3-schema.sql`(`biz_collection_protocol` 及其子表)。
|
||||
|
||||
**范围**:Web 管理端 `web-admin` + FastAPI `backend`;租户隔离与既有 `/web/admin` 响应风格保持一致。
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标与非目标
|
||||
|
||||
### 1.1 目标
|
||||
|
||||
- 新增一级菜单 **细胞存储管理**,下挂 5 个页面,路由与目录命名已定稿。
|
||||
- **最小闭环**:协议单列表/概要详情;审核(仅写审核表);财务收款确认与退费确认(限定状态流转);分期缴费预警(固定规则)。
|
||||
- **审核(2.2.7)**:采用用户确认的 **方案 A**——审核仅写入 `biz_protocol_audit`,**不修改** `biz_collection_protocol.protocol_status`。
|
||||
- **审核记录策略**:采用 **A1**——同一协议单**允许多条**审核记录,保留历史。
|
||||
- **收款确认(2.2.8)**:仅处理 `pay_status = jfqrz` → `yjf`。
|
||||
- **退费确认(2.2.9)**:仅处理 `pay_status = tfqrz` → `ytf`;**不包含**退费发起(不把状态推到 `tfqrz`)。
|
||||
- **分期预警(2.2.10)**:预警窗口 **未来 15 天**;列表仅包含 `pay_status = dfj` 的分期明细(**不包含 `jfqrz`**);逾期定义为应缴日早于当天。
|
||||
|
||||
### 1.2 非目标(本阶段不做)
|
||||
|
||||
- 不实现科研捐赠、临床应用等非本菜单范围模块。
|
||||
- 不把 2.2.6 下所有子表(采集信息、样本、运输、当事人等)一次性做全量录入与维护 UI;**第一版协议单详情以主表 + 缴费相关信息为主**,子表可后续迭代。
|
||||
- 不引入工作流引擎驱动上述 5 个菜单(除非后续产品明确要求);审核与财务确认以**表字段 + 接口**为准。
|
||||
- 退费发起、待缴费→提交财务确认等业务动作若未在本阶段定义接口,**不实现**。
|
||||
|
||||
---
|
||||
|
||||
## 2. 前端:菜单与路由
|
||||
|
||||
### 2.1 一级菜单
|
||||
|
||||
- **标题**:细胞存储管理
|
||||
- **路径前缀**:`/cell-storage`
|
||||
- **组件容器**:与现有模块一致,使用布局父级 ` /index/index`。
|
||||
|
||||
### 2.2 子菜单与文件路径
|
||||
|
||||
| 需求编号 | 菜单名称 | path | 组件路径 |
|
||||
|----------|--------------------|--------------------------|----------|
|
||||
| 2.2.6 | 采集协议单 | `protocol` | `views/cell-storage/protocol/index.vue` |
|
||||
| 2.2.7 | 采集协议单审核 | `protocol-audit` | `views/cell-storage/protocol-audit/index.vue` |
|
||||
| 2.2.8 | 收款确认(财务) | `payment-confirm` | `views/cell-storage/payment-confirm/index.vue` |
|
||||
| 2.2.9 | 退费确认(财务) | `refund-confirm` | `views/cell-storage/refund-confirm/index.vue` |
|
||||
| 2.2.10 | 分期缴费用户预警 | `installment-warning` | `views/cell-storage/installment-warning/index.vue` |
|
||||
|
||||
### 2.3 与后端菜单对齐
|
||||
|
||||
- 同步更新 `web-admin/src/router/modules/sqxp.ts` 与 `backend/app/api/menu.py` 中的静态菜单树,保证 **前端路由与后端菜单接口一致**(与仓库现有约定相同)。
|
||||
|
||||
### 2.4 UI 约定
|
||||
|
||||
- 列表页对齐模板:`web-admin/src/views/system/unit/index.vue`(筛选、工具栏、表格、分页)。
|
||||
- 弹窗表单:`label-position="top"`,`.dialog-form-layout`,无 backdrop blur;色板遵循 `docs/web-admin-ui-spec-fresh-mint.md`。
|
||||
|
||||
---
|
||||
|
||||
## 3. 数据与后端建模范围(方案 C)
|
||||
|
||||
### 3.1 本阶段必须落地的表(SQLAlchemy Model + CRUD)
|
||||
|
||||
| 表名 | 用途 |
|
||||
|------|------|
|
||||
| `biz_collection_protocol` | 协议单主表:列表、概要详情 |
|
||||
| `biz_protocol_audit` | 审核记录:列表、提交审核 |
|
||||
| `biz_protocol_payment` | 缴费主表:展示缴费模式、合同金额、分期参数(与协议单 1:1) |
|
||||
| `biz_protocol_payment_detail` | 缴费明细:财务确认列表、状态变更、分期预警 |
|
||||
|
||||
可选后续迭代再补:`biz_protocol_collection_info`、`biz_protocol_sample`、`biz_protocol_party_customer` 等。
|
||||
|
||||
### 3.2 租户与软删除
|
||||
|
||||
- 所有查询默认 `tenant_no = 当前用户租户`、`del_flag = 0`。
|
||||
- 写入时设置 `tenant_no`、`create_by` / `update_by` 等公共字段(与现有 CRUD 一致)。
|
||||
|
||||
### 3.3 列表默认排序
|
||||
|
||||
- 无自定义排序时:`order_num ASC, create_time DESC`(与工程规范一致);预警列表可按 `installment_due_date ASC` 等业务需求单独约定。
|
||||
|
||||
---
|
||||
|
||||
## 4. API 设计(前缀 `/api`,路由挂载与现有 `basic_info`、`admin` 一致)
|
||||
|
||||
以下路径均在 **`/web/admin`** 下(与现有基础信息管理相同前缀),具体以路由注册为准。
|
||||
|
||||
### 4.1 采集协议单(2.2.6)
|
||||
|
||||
- `GET .../collection-protocols`
|
||||
- Query:`page`, `pageSize`, `keyword`(协议号等), `protocolStatus`(可选)
|
||||
- `GET .../collection-protocols/{id}`
|
||||
- 返回:协议单主表字段 + 缴费主表概要(若存在)+ 缴费明细分页或摘要(实现时可先返回主表 + payment 一行)
|
||||
|
||||
创建/编辑协议单若产品未在本次冻结字段,可:**第一版仅只读列表 + 详情**,或最小字段新增——以 OpenSpec tasks 为准。
|
||||
|
||||
### 4.2 采集协议单审核(2.2.7)
|
||||
|
||||
- `GET .../collection-protocol-audits`
|
||||
- 列表:关联协议单展示协议号、审核状态、审核时间等;支持按 `auditStatus`、`keyword` 筛选
|
||||
- `POST .../collection-protocols/{id}/audit`
|
||||
- Body:`auditStatus`(`shtg` | `shth`), `auditRemark`(可选)
|
||||
- 行为:插入一条 `biz_protocol_audit`(**A1:允许多条**);**不更新** `biz_collection_protocol.protocol_status`
|
||||
- `auditor_user_id` / `create_by` 使用当前登录用户
|
||||
|
||||
### 4.3 收款确认(2.2.8)
|
||||
|
||||
- `GET .../protocol-payment-details/receipt-confirm`
|
||||
- 仅 `pay_status = jfqrz`
|
||||
- `POST .../protocol-payment-details/{detailId}/receipt-confirm`
|
||||
- 校验当前行必须为 `jfqrz`
|
||||
- 更新为 `yjf`,写入 `finance_confirm_attachments`(若前端上传)、备注等
|
||||
- **幂等**:已为 `yjf` 则返回业务错误提示
|
||||
|
||||
### 4.4 退费确认(2.2.9)
|
||||
|
||||
- `GET .../protocol-payment-details/refund-confirm`
|
||||
- 仅 `pay_status = tfqrz`
|
||||
- `POST .../protocol-payment-details/{detailId}/refund-confirm`
|
||||
- 校验当前行必须为 `tfqrz`
|
||||
- 更新为 `ytf`
|
||||
- **幂等**:已为 `ytf` 则返回业务错误提示
|
||||
|
||||
### 4.5 分期缴费预警(2.2.10)
|
||||
|
||||
- `GET .../protocol-payment-details/installment-warning`
|
||||
- 条件:`installment_no IS NOT NULL`、`pay_status = dfj`
|
||||
- 计算字段(可由后端计算返回):
|
||||
- `warningType = warn`:`today <= due <= today+15天`
|
||||
- `warningType = overdue`:`due < today`
|
||||
- Query:`warningType`(`warn` | `overdue` | `all`)、`page`、`pageSize`
|
||||
- 排序建议:`installment_due_date ASC`
|
||||
|
||||
日期计算使用服务器本地日期(YYYYMMDD 字符串与当天对比)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 权限(建议)
|
||||
|
||||
- 五个菜单默认 **`admin` / `super_admin`** 可见(与 Demo 体系一致);若需细分「财务」角色,在 OpenSpec 任务中增加 `perms` 与角色菜单种子 SQL,不阻塞第一版。
|
||||
|
||||
---
|
||||
|
||||
## 6. 风险与后续迭代
|
||||
|
||||
- **协议单详情不完整**:第一版可能无法满足采集专员全量录入,需在后续变更中按子表拆分页面或 Tab。
|
||||
- **退费链路不完整**:仅确认 `tfqrz→ytf`,需业务侧在其他模块或后续任务中补齐「发起退费」。
|
||||
- **附件字段**:`finance_confirm_attachments` 等与 MinIO 上传组件对齐现有项目用法。
|
||||
|
||||
---
|
||||
|
||||
## 7. OpenSpec 后续步骤
|
||||
|
||||
1. 使用 `openspec new change` 创建变更(例如 `cell-storage-protocol-modules`)。
|
||||
2. 按 `openspec-propose` 生成 `proposal.md`、`design.md`、`tasks.md` 及 capabilities 下各 `spec.md`,与本设计对齐。
|
||||
3. `openspec-apply-change` 按 tasks 实现后端 Model、CRUD、路由注册、`sqxp.ts` + `menu.py`、五个 Vue 页面及 `web-admin/src/api` 封装。
|
||||
|
||||
---
|
||||
|
||||
**文档状态**:已定稿上述边界(含 A、A1、财务状态、预警 C+1、菜单与路径)。审阅通过后进入 implementation plan(writing-plans)与 OpenSpec 变更落地。
|
||||
Reference in new issue
Block a user