This commit is contained in:
zlwu committed 2026-05-27 06:22:08 +08:00
1 parent 41aa90aa05
commit 7145c6c683
17 files changed
+1924 -2219

No files matched your search

+1 -1
View File
@@ -1 +1 @@
53718
60905
-23
View File
@@ -1,23 +0,0 @@
-- 输注计划管理 · 出库交接
CREATE TABLE IF NOT EXISTS `biz_outbound_handover` (
`id` varchar(64) NOT NULL COMMENT '主键ID',
`infusion_schedule_id` varchar(64) NOT NULL COMMENT '输注计划ID',
`handover_user_id` varchar(64) DEFAULT NULL COMMENT '交接人用户ID',
`handover_person` varchar(64) DEFAULT NULL COMMENT '交接人姓名快照',
`handover_time` datetime DEFAULT NULL COMMENT '交接时间',
`handover_location` varchar(200) DEFAULT NULL COMMENT '交接地点',
`receiver_person` varchar(200) DEFAULT NULL COMMENT '接收人(文本)',
`tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
`order_num` int(11) 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` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标记:0-正常 1-已删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_oh_schedule` (`infusion_schedule_id`, `del_flag`),
KEY `idx_oh_tenant` (`tenant_no`, `del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='输注计划-出库交接';
-71
View File
@@ -1,71 +0,0 @@
-- 出库放行审核 · 出库物料准备(台账,不联动库存)
CREATE TABLE IF NOT EXISTS `biz_outbound_release_material` (
`id` varchar(64) NOT NULL COMMENT '主键ID',
`infusion_schedule_id` varchar(64) NOT NULL COMMENT '输注计划ID',
`paper_attachments` varchar(4000) DEFAULT NULL COMMENT '其他纸质材料附件(逗号分隔URL)',
`tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
`order_num` int(11) 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` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标记:0-正常 1-已删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_orm_schedule` (`infusion_schedule_id`, `del_flag`),
KEY `idx_orm_tenant` (`tenant_no`, `del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='出库放行-出库物料准备主表';
CREATE TABLE IF NOT EXISTS `biz_outbound_release_cell` (
`id` varchar(64) NOT NULL COMMENT '主键ID',
`material_id` varchar(64) NOT NULL COMMENT '关联 biz_outbound_release_material.id',
`infusion_schedule_id` varchar(64) NOT NULL COMMENT '输注计划ID',
`cell_product_id` varchar(64) NOT NULL COMMENT '细胞产品ID',
`product_code` varchar(128) DEFAULT NULL COMMENT '产品编码快照',
`product_name` varchar(200) DEFAULT NULL COMMENT '产品名称快照',
`product_type_name` varchar(100) DEFAULT NULL COMMENT '产品类型快照',
`spec_name` varchar(100) DEFAULT NULL COMMENT '规格快照',
`passage` varchar(32) DEFAULT NULL COMMENT '代次快照',
`batch_no` varchar(64) DEFAULT NULL COMMENT '批次号快照',
`storage_slot_name` varchar(200) DEFAULT NULL COMMENT '储物格快照',
`product_status` varchar(32) DEFAULT NULL COMMENT '保存时状态快照',
`tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
`order_num` int(11) 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` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标记:0-正常 1-已删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_orc_schedule_product` (`infusion_schedule_id`, `cell_product_id`, `del_flag`),
KEY `idx_orc_product` (`cell_product_id`, `del_flag`),
KEY `idx_orc_material` (`material_id`, `del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='出库放行-出库细胞(台账)';
CREATE TABLE IF NOT EXISTS `biz_outbound_release_qc_material` (
`id` varchar(64) NOT NULL COMMENT '主键ID',
`material_id` varchar(64) NOT NULL COMMENT '关联 biz_outbound_release_material.id',
`infusion_schedule_id` varchar(64) NOT NULL COMMENT '输注计划ID',
`qc_material_id` varchar(64) NOT NULL COMMENT '质检物料ID',
`qty` decimal(18,4) NOT NULL COMMENT '计划用量(台账)',
`material_code` varchar(64) DEFAULT NULL COMMENT '物料编码快照',
`material_name` varchar(200) DEFAULT NULL COMMENT '物料名称快照',
`spec_model` varchar(200) DEFAULT NULL COMMENT '规格型号快照',
`unit` varchar(32) DEFAULT NULL COMMENT '单位快照',
`tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
`order_num` int(11) 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` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标记:0-正常 1-已删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_orqm_schedule_material` (`infusion_schedule_id`, `qc_material_id`, `del_flag`),
KEY `idx_orqm_material` (`material_id`, `del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='出库放行-质检物料(台账)';
@@ -1,22 +0,0 @@
-- 出库放行审核 · 其他纸质材料子表(逐条:名称、份数、附件)
CREATE TABLE IF NOT EXISTS `biz_outbound_release_paper` (
`id` varchar(64) NOT NULL COMMENT '主键ID',
`material_id` varchar(64) NOT NULL COMMENT '关联 biz_outbound_release_material.id',
`infusion_schedule_id` varchar(64) NOT NULL COMMENT '输注计划ID',
`paper_name` varchar(200) NOT NULL COMMENT '材料名称',
`copies` int(11) NOT NULL DEFAULT 1 COMMENT '份数',
`attachment_url` varchar(2000) DEFAULT NULL COMMENT '附件URL',
`tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
`order_num` int(11) 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` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标记:0-正常 1-已删除',
PRIMARY KEY (`id`),
KEY `idx_orp_schedule` (`infusion_schedule_id`, `del_flag`),
KEY `idx_orp_material` (`material_id`, `del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='出库放行-其他纸质材料(台账)';
@@ -1,4 +0,0 @@
-- 出库放行审核表新增审核附件和审核人姓名字段
ALTER TABLE biz_outbound_release_review
ADD COLUMN review_attachments VARCHAR(4000) NULL COMMENT '审核附件(逗号分隔URL)' AFTER review_remark,
ADD COLUMN review_by_name VARCHAR(64) NULL COMMENT '审核人姓名' AFTER reviewer_user_id;
+287 -994
View File
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,297 @@
# 临床应用业务 — 功能设计文档
> 日期:2026-05-27
> 状态:待审阅
> 模块:中试服务管理 > 临床应用
> 需求来源:用户提出新增临床应用业务线
---
## 1. 背景与目标
### 现状
中试服务已完成完整业务闭环:渠道管理 → 渠道服务购买订单 → 中试申请单 → 体检 → 输注计划 → 出库生产/质检/放行 → 交付 → 输注确认。现需新增**临床应用**业务线。
### 临床应用 vs 中试服务差异
| 维度 | 中试服务 | 临床应用 |
|------|---------|---------|
| 渠道充值 | 渠道有充值/余额管理,从余额扣款 | 不充值,直接按次缴费 |
| 缴费主体 | 渠道方(B 端) | 患者(C 端) |
| 金额计算 | 从渠道协议产品价格自动带入 | 手动填写 |
| 缴费流程 | 嵌入渠道服务订单内部 | 独立缴费流程(参照细胞存储缴费) |
| 其他流程 | 完整链路 | **完全一致** |
### 目标
1. 在现有中试服务的表结构和代码基础上,通过 `biz_type` 字段区分两条业务线
2. 新增缴费信息/缴费确认/退费确认三个独立菜单,实现临床应用的缴费闭环
3. 最大化复用现有页面和组件,最小化代码改动
---
## 2. 数据库变更
### 2.1 ALTER `biz_pilot_application` — 新增 `biz_type` 字段
```sql
ALTER TABLE biz_pilot_application
ADD COLUMN biz_type VARCHAR(20) NOT NULL DEFAULT 'pilot_service'
COMMENT '业务类型: pilot_service=中试服务, clinical_application=临床应用'
AFTER channel_name;
-- 更新已有数据
UPDATE biz_pilot_application SET biz_type = 'pilot_service' WHERE biz_type = 'pilot_service';
```
**影响**:
- `channel_service_order_id` 对临床应用可为 NULL(不走渠道充值)
- `channel_id` 已有,临床应用直接关联渠道
- 申请单号前缀:中试 `ZSSQ`,临床应用 `LCSQ`(需调整生成逻辑)
### 2.2 ALTER `biz_pilot_infusion_schedule` — 新增 `amount` 字段
```sql
ALTER TABLE biz_pilot_infusion_schedule
ADD COLUMN amount DECIMAL(18,2) DEFAULT NULL
COMMENT '临床应用-手动填写的输注金额(中试为NULL,从协议价格计算)'
AFTER qc_status;
```
### 2.3 新建 `biz_pilot_payment` — 缴费记录表
临床采用趸交模式,一个输注计划一条缴费记录,无需主表/明细二层结构。
```sql
CREATE TABLE biz_pilot_payment (
id VARCHAR(64) NOT NULL COMMENT '主键ID',
pilot_application_id VARCHAR(64) NOT NULL COMMENT '临床申请单ID',
infusion_schedule_id VARCHAR(64) NOT NULL COMMENT '输注计划ID(唯一约束)',
biz_type VARCHAR(20) NOT NULL DEFAULT 'clinical_application' COMMENT '业务类型',
amount DECIMAL(18,2) NOT NULL COMMENT '缴费金额(手动填写)',
transfer_type VARCHAR(16) DEFAULT NULL COMMENT '转账方式: wxzz微信 zzfbzz支付宝 yhkzz银行卡 xj现金',
transfer_amount DECIMAL(18,2) DEFAULT NULL COMMENT '实际转账金额',
transfer_time DATETIME DEFAULT NULL COMMENT '转账时间',
transfer_attachments TEXT DEFAULT NULL COMMENT '转账凭证附件(逗号分隔URL)',
pay_status VARCHAR(32) NOT NULL DEFAULT 'dfj' COMMENT '缴费状态: dfj待缴费 jfqrz缴费确认中 yjf已缴费 tfqrz退费确认中 ytf已退费',
finance_confirm_attachments TEXT DEFAULT NULL COMMENT '财务确认收款附件',
finance_remark VARCHAR(512) DEFAULT NULL COMMENT '财务确认收款备注',
finance_confirm_time DATETIME DEFAULT NULL COMMENT '财务确认收款时间',
refund_amount DECIMAL(18,2) DEFAULT NULL COMMENT '退费金额',
refund_remark VARCHAR(512) DEFAULT NULL COMMENT '退费备注',
refund_attachments TEXT DEFAULT NULL COMMENT '退费附件(逗号分隔URL)',
refund_apply_by VARCHAR(64) DEFAULT NULL COMMENT '退费申请人ID',
refund_apply_time DATETIME DEFAULT NULL COMMENT '退费申请时间',
refund_finance_confirm_attachments TEXT DEFAULT NULL COMMENT '退费财务确认附件',
refund_finance_remark VARCHAR(512) DEFAULT NULL COMMENT '退费财务确认备注',
refund_finance_confirm_time DATETIME DEFAULT NULL COMMENT '退费财务确认时间',
tenant_no VARCHAR(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
order_num INT(11) 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 TINYINT(4) NOT NULL DEFAULT '0' COMMENT '删除标记: 0-正常 1-已删除',
PRIMARY KEY (id),
UNIQUE KEY uk_infusion_schedule (infusion_schedule_id, del_flag),
KEY idx_pilot_app (pilot_application_id, del_flag),
KEY idx_pay_status (pay_status, del_flag),
KEY idx_tenant (tenant_no, del_flag)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='临床应用缴费记录';
```
---
## 3. 缴费状态流转
```
[dfj 待缴费] ── 市场发起缴费确认 ──→ [jfqrz 缴费确认中]
│
财务确认收款
│
▼
[yjf 已缴费]
│
市场发起退费
│
▼
[tfqrz 退费确认中]
│
财务确认退费
│
▼
[ytf 已退费]
```
复用已有状态枚举 `payStatus`(`status-tag-registry.ts`):
- `dfj` 待缴费 → `info`
- `jfqrz` 缴费确认中 → `warning`
- `yjf` 已缴费 → `success`
- `tfqrz` 退费确认中 → `warning`
- `ytf` 已退费 → `danger`
---
## 4. 后端 API 设计
新建 `backend/app/api/clinical_payment.py`,前缀 `/web/admin`。
### 4.1 缴费信息页面
| 方法 | 路径 | 功能 | 状态变更 |
|------|------|------|---------|
| GET | `/clinical-payments` | 缴费列表(按 payStatus 筛选) | — |
| GET | `/clinical-payments/{id}` | 缴费详情 | — |
| POST | `/clinical-payments/{id}/submit-receipt` | 单条缴费确认 | dfj → jfqrz |
| POST | `/clinical-payments/submit-receipt-batch` | 批量缴费确认 | dfj → jfqrz |
| POST | `/clinical-payments/{id}/submit-refund` | 发起退费(填退费金额/备注/附件) | yjf → tfqrz |
| POST | `/clinical-payments/submit-refund-batch` | 批量发起退费 | yjf → tfqrz |
### 4.2 缴费确认(财务)
| 方法 | 路径 | 功能 | 状态变更 |
|------|------|------|---------|
| GET | `/clinical-payments/receipt-pending` | 待确认收款列表(jfqrz) | — |
| GET | `/clinical-payments/receipt-confirmed` | 已确认收款列表(yjf) | — |
| POST | `/clinical-payments/{id}/confirm-receipt` | 确认收款(填财务备注/附件) | jfqrz → yjf |
### 4.3 退费确认(财务)
| 方法 | 路径 | 功能 | 状态变更 |
|------|------|------|---------|
| GET | `/clinical-payments/refund-pending` | 待确认退费列表(tfqrz) | — |
| GET | `/clinical-payments/refund-confirmed` | 已确认退费列表(ytf) | — |
| POST | `/clinical-payments/{id}/confirm-refund` | 确认退费(填财务备注/附件) | tfqrz → ytf |
### 4.4 自动创建缴费记录
当临床应用的输注计划创建时,自动在 `biz_pilot_payment` 中生成一条 `pay_status=dfj` 的缴费记录。触发点:`pilot_application.py` 中创建输注计划的 API,当 `biz_type='clinical_application'` 时自动插入。
---
## 5. 前端页面设计
### 5.1 菜单结构
```
临床应用管理(一级菜单,独立于"中试服务管理")
├── 临床申请单
├── 体检管理
├── 输注计划管理
├── 缴费信息 ← 独立菜单
├── 缴费确认(财务) ← 独立菜单
├── 退费确认(财务) ← 独立菜单
└── 出库放行审核
```
### 5.2 页面复用策略
| 菜单 | 前端页面目录 | 复用方式 |
|------|------------|---------|
| 临床申请单 | `pilot-service/pilot-application/` | 共用组件,路由 prop `bizType='clinical_application'`,隐藏渠道订单选择器 |
| 体检管理 | `pilot-service/checkup-management/` | 完全共用 |
| 输注计划管理 | `pilot-service/infusion-schedule-management/` | 共用,临床多渲染"金额"列和"缴费状态"列 |
| **缴费信息** | **新建** `pilot-service/clinical-payment-info/` | 参照 `cell-storage/payment-info/index.vue` |
| **缴费确认(财务)** | **新建** `pilot-service/clinical-payment-confirm/` | 参照 `cell-storage/payment-confirm/index.vue` |
| **退费确认(财务)** | **新建** `pilot-service/clinical-refund-confirm/` | 参照 `cell-storage/refund-confirm/index.vue` |
| 出库放行审核 | `pilot-service/outbound-release-review/` | 共用,按 `biz_type` 过滤 |
### 5.3 缴费信息页面 (`clinical-payment-info/index.vue`)
参照 `cell-storage/payment-info/index.vue`,核心结构:
- **Tab 切换**:`dfj` 待缴费 / `yjf` 已缴费(退费操作入口)
- **列表表格列**:申请单号、患者姓名、渠道名称、细胞类型/规格、输注时间、缴费金额、缴费状态、操作
- **操作按钮**:
- 待缴费 Tab:单条缴费确认、批量缴费确认
- 已缴费 Tab:单条退费、批量退费
- **缴费确认弹窗**:展示缴费明细只读信息,无需额外填写(直接提交)
- **退费弹窗**:填写退费金额(必填)+ 退费备注 + 退费附件
### 5.4 缴费确认页面 (`clinical-payment-confirm/index.vue`)
参照 `cell-storage/payment-confirm/index.vue`:
- **Tab 切换**:待确认(jfqrz)/ 已确认(yjf)
- **操作**:确认收款 → 弹窗填财务备注 + 财务附件
- **复用组件**:`ProtocolFinanceConfirmFields`(备注 + 附件上传表单)
### 5.5 退费确认页面 (`clinical-refund-confirm/index.vue`)
参照 `cell-storage/refund-confirm/index.vue`:
- **Tab 切换**:待确认(tfqrz)/ 已确认(ytf)
- **操作**:确认退费 → 弹窗展示退费申请信息(只读)+ 财务确认表单
- **复用组件**:`ProtocolFinanceConfirmFields`
### 5.6 申请单页面改造
`pilot-application/` 组件通过路由 prop `bizType` 控制行为差异:
| 字段/行为 | 中试 (`pilot_service`) | 临床 (`clinical_application`) |
|----------|----------------------|------------------------------|
| 渠道订单选择器 | 显示(必选) | **隐藏** |
| 渠道选择器 | 从订单自动带入 | **直接选择渠道** |
| 输注方案-协议价格 | 从渠道协议产品价格带入 | **不显示** |
| 输注计划-金额 | 不显示(从产品价格计算) | **手动填写** |
| 申请单号前缀 | ZSSQ | LCSQ |
### 5.7 输注计划管理页面改造
`infusion-schedule-management/` 新增:
- 当 `bizType === 'clinical_application'` 时,表格新增"缴费金额"列和"缴费状态"列
- 缴费状态使用 `payStatusLabel` + `payStatusTagType` 渲染
---
## 6. 复用清单
### 后端复用
| 复用项 | 来源 | 说明 |
|--------|------|------|
| `pilot_application.py` | 申请单 API | 加 `biz_type` 参数过滤和差异化逻辑 |
| `pilot_checkup.py` | 体检 API | 按 `biz_type` 过滤申请单 |
| `pilot_infusion_schedule_mgmt.py` | 输注计划管理 | 共用,临床多返回金额和缴费状态 |
| `outbound_release_review.py` | 出库放行审核 | 按 `biz_type` 过滤 |
| `crud/pilot_outbound_status_sync.py` | 出库状态同步 | 共用 |
| `crud/pilot_application.py` | 申请单 CRUD | 加 `biz_type` 字段处理 |
### 前端复用
| 复用项 | 来源 | 说明 |
|--------|------|------|
| `payStatusLabel` / `payStatusTagType` | `status-tag-registry.ts` | 缴费状态枚举直接复用 |
| `ProtocolFinanceConfirmFields` | `components/business/` | 财务确认表单(备注+附件) |
| `ProtocolPaymentDetailReadonly` | `components/business/` | 缴费明细只读展示(需微调字段映射) |
| `formatMoneyDisplay` | 金额格式化工具 | 金额展示 |
| 申请单页面组件 | `pilot-application/` | 共用,通过 prop 区分行为 |
---
## 7. 改动量估算
| 层级 | 改动内容 | 工作量 |
|------|---------|--------|
| SQL | 2 个 ALTER + 1 个 CREATE TABLE | 小 |
| 后端模型 | `BizPilotApplication` + `BizPilotInfusionSchedule` 加字段 + 新增 `BizPilotPayment` | 小 |
| 后端 CRUD | 新增 `clinical_payment.py`,改造 `pilot_application.py` | 中 |
| 后端 API | 新增 `clinical_payment.py`(10 个端点),改造申请单/输注计划 API | 中 |
| 后端注册 | `api/__init__.py` + `main.py` 注册新路由 | 小 |
| 前端路由 | `sqxp.ts` 新增临床应用一级菜单 + 7 个子路由 | 小 |
| 前端页面 | 新建 3 个缴费页面,改造申请单/输注计划页面 | 中 |
| 前端 API | `business.ts` 新增 clinical payment 接口 | 小 |
---
## 8. 约束与风险
1. **`biz_type` 一致性**:所有查询必须带 `biz_type` 过滤,防止中试和临床数据混在一起
2. **缴费记录自动创建**:输注计划创建时自动生成 `dfj` 记录,需确保事务一致性
3. **`channel_service_order_id` 可空**:临床应用不走服务订单,该字段为 NULL,需确认现有代码是否有 NOT NULL 校验
4. **前端 prop 传递**:共用页面通过路由 prop 传入 `bizType`,需确保所有子组件都能正确接收
5. **权限区分**:临床应用菜单和中试服务菜单需要独立的 `menuCode`,便于权限控制
File diff suppressed because it is too large. Load diff
+74 -58
View File
@@ -9413,112 +9413,119 @@
"label": "loadRoleOptions()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L307"
"source_location": "L318"
},
{
"id": "user_index_formatuserdeptdisplay",
"label": "formatUserDeptDisplay()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L330"
"source_location": "L341"
},
{
"id": "user_index_formatuserroledisplay",
"label": "formatUserRoleDisplay()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L336"
"source_location": "L347"
},
{
"id": "user_index_filterdeptnode",
"label": "filterDeptNode()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L378"
"source_location": "L390"
},
{
"id": "user_index_handledeptnodeclick",
"label": "handleDeptNodeClick()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L387"
"source_location": "L399"
},
{
"id": "user_index_loaddepttree",
"label": "loadDeptTree()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L393"
"source_location": "L405"
},
{
"id": "user_index_loaddata",
"label": "loadData()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L402"
"source_location": "L414"
},
{
"id": "user_index_handlesearch",
"label": "handleSearch()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L419"
"source_location": "L431"
},
{
"id": "user_index_handlereset",
"label": "handleReset()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L424"
"source_location": "L436"
},
{
"id": "user_index_resetform",
"label": "resetForm()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L433"
"source_location": "L445"
},
{
"id": "user_index_handleadd",
"label": "handleAdd()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L449"
"source_location": "L461"
},
{
"id": "user_index_handleedit",
"label": "handleEdit()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L460"
"source_location": "L472"
},
{
"id": "user_index_handlesubmit",
"label": "handleSubmit()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L486"
"source_location": "L498"
},
{
"id": "user_index_handleselectionchange",
"label": "handleSelectionChange()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L538"
},
{
"id": "user_index_handledelete",
"label": "handleDelete()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L526"
"source_location": "L542"
},
{
"id": "user_index_handleresetpwd",
"label": "handleResetPwd()",
"id": "user_index_handlebatchresetpwd",
"label": "handleBatchResetPwd()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L532"
"source_location": "L548"
},
{
"id": "user_index_handleview",
"label": "handleView()",
"file_type": "code",
"source_file": "views/system/user/index.vue",
"source_location": "L573"
"source_location": "L600"
},
{
"id": "views_system_user_detail_vue",
@@ -28387,7 +28394,7 @@
"relation": "imports_from",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L282",
"source_location": "L292",
"weight": 1.0
},
{
@@ -28396,7 +28403,7 @@
"relation": "imports_from",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L283",
"source_location": "L293",
"weight": 1.0
},
{
@@ -28405,7 +28412,7 @@
"relation": "imports_from",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L292",
"source_location": "L303",
"weight": 1.0
},
{
@@ -28414,7 +28421,7 @@
"relation": "imports_from",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L293",
"source_location": "L304",
"weight": 1.0
},
{
@@ -28423,7 +28430,7 @@
"relation": "imports_from",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L303",
"source_location": "L314",
"weight": 1.0
},
{
@@ -28432,7 +28439,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L307",
"source_location": "L318",
"weight": 1.0
},
{
@@ -28441,7 +28448,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L330",
"source_location": "L341",
"weight": 1.0
},
{
@@ -28450,7 +28457,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L336",
"source_location": "L347",
"weight": 1.0
},
{
@@ -28459,7 +28466,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L378",
"source_location": "L390",
"weight": 1.0
},
{
@@ -28468,7 +28475,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L387",
"source_location": "L399",
"weight": 1.0
},
{
@@ -28477,7 +28484,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L393",
"source_location": "L405",
"weight": 1.0
},
{
@@ -28486,7 +28493,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L402",
"source_location": "L414",
"weight": 1.0
},
{
@@ -28495,7 +28502,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L419",
"source_location": "L431",
"weight": 1.0
},
{
@@ -28504,7 +28511,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L424",
"source_location": "L436",
"weight": 1.0
},
{
@@ -28513,7 +28520,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L433",
"source_location": "L445",
"weight": 1.0
},
{
@@ -28522,7 +28529,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L449",
"source_location": "L461",
"weight": 1.0
},
{
@@ -28531,7 +28538,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L460",
"source_location": "L472",
"weight": 1.0
},
{
@@ -28540,7 +28547,16 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L486",
"source_location": "L498",
"weight": 1.0
},
{
"source": "views_system_user_index_vue",
"target": "user_index_handleselectionchange",
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L538",
"weight": 1.0
},
{
@@ -28549,16 +28565,16 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L526",
"source_location": "L542",
"weight": 1.0
},
{
"source": "views_system_user_index_vue",
"target": "user_index_handleresetpwd",
"target": "user_index_handlebatchresetpwd",
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L532",
"source_location": "L548",
"weight": 1.0
},
{
@@ -28567,7 +28583,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L573",
"source_location": "L600",
"weight": 1.0
},
{
@@ -28576,7 +28592,7 @@
"relation": "calls",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L390",
"source_location": "L402",
"weight": 1.0
},
{
@@ -28585,7 +28601,7 @@
"relation": "calls",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L421",
"source_location": "L433",
"weight": 1.0
},
{
@@ -28594,7 +28610,7 @@
"relation": "calls",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L430",
"source_location": "L442",
"weight": 1.0
},
{
@@ -28603,7 +28619,7 @@
"relation": "calls",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L452",
"source_location": "L464",
"weight": 1.0
},
{
@@ -28612,7 +28628,7 @@
"relation": "calls",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L518",
"source_location": "L530",
"weight": 1.0
},
{
@@ -28621,7 +28637,7 @@
"relation": "calls",
"confidence": "EXTRACTED",
"source_file": "views/system/user/index.vue",
"source_location": "L529",
"source_location": "L545",
"weight": 1.0
},
{
@@ -38585,7 +38601,7 @@
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "views/system/user/index.vue",
"source_location": "L309",
"source_location": "L320",
"weight": 1.0
},
{
@@ -38595,7 +38611,7 @@
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "views/system/user/index.vue",
"source_location": "L333",
"source_location": "L344",
"weight": 1.0
},
{
@@ -38605,7 +38621,7 @@
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "views/system/user/index.vue",
"source_location": "L395",
"source_location": "L407",
"weight": 1.0
},
{
@@ -38615,7 +38631,7 @@
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "views/system/user/index.vue",
"source_location": "L405",
"source_location": "L417",
"weight": 1.0
},
{
@@ -38625,7 +38641,7 @@
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "views/system/user/index.vue",
"source_location": "L465",
"source_location": "L477",
"weight": 1.0
},
{
@@ -38635,7 +38651,7 @@
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "views/system/user/index.vue",
"source_location": "L487",
"source_location": "L499",
"weight": 1.0
},
{
@@ -38645,7 +38661,7 @@
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "views/system/user/index.vue",
"source_location": "L491",
"source_location": "L503",
"weight": 1.0
},
{
@@ -38655,7 +38671,7 @@
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "views/system/user/index.vue",
"source_location": "L503",
"source_location": "L515",
"weight": 1.0
},
{
@@ -38665,17 +38681,17 @@
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "views/system/user/index.vue",
"source_location": "L528",
"source_location": "L544",
"weight": 1.0
},
{
"source": "user_index_handleresetpwd",
"source": "user_index_handlebatchresetpwd",
"target": "api_admin_fetchresetpassword",
"relation": "calls",
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "views/system/user/index.vue",
"source_location": "L536",
"source_location": "L560",
"weight": 1.0
},
{
@@ -38685,7 +38701,7 @@
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "views/system/user/index.vue",
"source_location": "L575",
"source_location": "L602",
"weight": 1.0
},
{
+119 -70
View File
@@ -1,10 +1,10 @@
# Graph Report - src (2026-05-27)
## Corpus Check
- Large corpus: 641 files · ~402,707 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
- Large corpus: 641 files · ~402,748 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
## Summary
- 1844 nodes · 2394 edges · 41 communities detected
- 1845 nodes · 2395 edges · 48 communities detected
- Extraction: 77% EXTRACTED · 23% INFERRED · 0% AMBIGUOUS · INFERRED: 550 edges (avg confidence: 0.8)
- Token cost: 0 input · 0 output
@@ -38,18 +38,25 @@
- [[_COMMUNITY_Community 26|Community 26]]
- [[_COMMUNITY_Community 27|Community 27]]
- [[_COMMUNITY_Community 29|Community 29]]
- [[_COMMUNITY_Community 31|Community 31]]
- [[_COMMUNITY_Community 30|Community 30]]
- [[_COMMUNITY_Community 32|Community 32]]
- [[_COMMUNITY_Community 33|Community 33]]
- [[_COMMUNITY_Community 34|Community 34]]
- [[_COMMUNITY_Community 35|Community 35]]
- [[_COMMUNITY_Community 36|Community 36]]
- [[_COMMUNITY_Community 37|Community 37]]
- [[_COMMUNITY_Community 38|Community 38]]
- [[_COMMUNITY_Community 39|Community 39]]
- [[_COMMUNITY_Community 41|Community 41]]
- [[_COMMUNITY_Community 42|Community 42]]
- [[_COMMUNITY_Community 43|Community 43]]
- [[_COMMUNITY_Community 45|Community 45]]
- [[_COMMUNITY_Community 46|Community 46]]
- [[_COMMUNITY_Community 47|Community 47]]
- [[_COMMUNITY_Community 48|Community 48]]
- [[_COMMUNITY_Community 50|Community 50]]
- [[_COMMUNITY_Community 52|Community 52]]
- [[_COMMUNITY_Community 59|Community 59]]
- [[_COMMUNITY_Community 60|Community 60]]
## God Nodes (most connected - your core abstractions)
1. `get()` - 196 edges
@@ -68,71 +75,71 @@
views/basic-info/collection-region/index.vue → utils/fullscreen-loading.ts
- `handleAttachmentDownload()` --calls--> `downloadAttachmentFile()` [INFERRED]
views/cell-storage/refund-confirm/index.vue → utils/download-attachment.ts
- `handleAttachmentDownload()` --calls--> `downloadAttachmentFile()` [INFERRED]
views/cell-storage/payment-confirm/index.vue → utils/download-attachment.ts
- `subscribeTokenRefresh()` --calls--> `push()` [INFERRED]
utils/http/index.ts → views/operations/storage-facility/index.vue
- `handleUnauthorizedResponse()` --calls--> `fetchRefreshToken()` [INFERRED]
utils/http/index.ts → api/auth.ts
- `toLogin()` --calls--> `logOut()` [INFERRED]
components/core/layouts/art-screen-lock/index.vue → utils/http/index.ts
- `fetchLeaveList()` --calls--> `get()` [INFERRED]
api/leave.ts → views/production/process-route/index.vue
## Communities
### Community 0 - "Community 0"
Cohesion: 0.01
Nodes (102): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchCellSampleTypeList() (+94 more)
Nodes (112): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchCellSampleTypeList() (+104 more)
### Community 1 - "Community 1"
Cohesion: 0.02
Nodes (99): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionList(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchCheckupInstitutionProjects(), fetchPilotCheckupDetail(), markPilotCheckupChecked() (+91 more)
Nodes (67): fetchBatchGenerateProtocolNos(), fetchBatchGenerateSampleCodes(), fetchBatchIssueProtocolNos(), fetchBatchIssueSampleCodes(), fetchCollectionProtocolNoList(), fetchCreateCollectionProtocolNo(), fetchCreateSampleCode(), fetchDeleteCollectionProtocolNo() (+59 more)
### Community 2 - "Community 2"
Cohesion: 0.02
Nodes (66): fetchBatchGenerateProtocolNos(), fetchBatchGenerateSampleCodes(), fetchBatchIssueProtocolNos(), fetchBatchIssueSampleCodes(), fetchCollectionProtocolNoList(), fetchCreateCollectionProtocolNo(), fetchCreateSampleCode(), fetchDeleteCollectionProtocolNo() (+58 more)
### Community 3 - "Community 3"
Cohesion: 0.03
Nodes (40): fetchGetMenuList(), fetchGetMenuCodes(), fetchGetUserInfo(), fetchLogin(), fetchRefreshToken(), clickTab(), handleTouchEnd(), setTransition() (+32 more)
### Community 3 - "Community 3"
Cohesion: 0.04
Nodes (65): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionList(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchCheckupInstitutionProjects(), fetchPilotCheckupActualItems(), fetchPilotCheckupDetail() (+57 more)
### Community 4 - "Community 4"
Cohesion: 0.03
Nodes (22): fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllConsumableStockLogs(), fetchAllOutputTypes(), fetchAllProcessCategories(), fetchAllProcesses(), fetchAllReagents(), fetchAllReagentStockLogs() (+14 more)
Cohesion: 0.04
Nodes (39): fetchUploadAttachment(), FireworkSystem, reload(), handleReportUpload(), handleReportUpload(), handleAttachmentChange(), subscribeTokenRefresh(), handleMenuJump() (+31 more)
### Community 5 - "Community 5"
Cohesion: 0.03
Nodes (22): fetchLeaveDetail(), fetchLeaveList(), fetchMaterialList(), fetchMaterialOptions(), fetchMaterialStockLogList(), fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList(), fetchQcMaterialList() (+14 more)
Cohesion: 0.05
Nodes (35): fetchServiceOrderTxnList(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolList(), fetchPaymentDetailList(), fetchReceiptConfirmedList(), fetchReceiptConfirmList(), fetchReceiptConfirmSubmit(), fetchRefundConfirmedList() (+27 more)
### Community 6 - "Community 6"
Cohesion: 0.05
Nodes (36): fetchServiceOrderTxnList(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolList(), fetchPaymentDetailList(), fetchReceiptConfirmedList(), fetchReceiptConfirmList(), fetchReceiptConfirmSubmit(), fetchRefundConfirmedList() (+28 more)
### Community 7 - "Community 7"
Cohesion: 0.07
Nodes (8): updateInfusionScheduleStatus(), handleSubmit(), handleReset(), handleSearch(), WebSocketClient, TableCache, emit(), handleSubmit()
### Community 8 - "Community 8"
### Community 7 - "Community 7"
Cohesion: 0.04
Nodes (28): fetchAttachmentDownloadUrl(), fetchOrderAdjusts(), fetchOrderDetail(), fetchOrderItems(), fetchOrderList(), fetchPriceVersionDetail(), fetchSystemConfig(), handleDownloadAttachment() (+20 more)
Nodes (29): fetchAttachmentDownloadUrl(), fetchOrderAdjusts(), fetchOrderDetail(), fetchOrderItems(), fetchOrderList(), fetchPriceVersionDetail(), fetchSystemConfig(), handleDownloadAttachment() (+21 more)
### Community 9 - "Community 9"
### Community 8 - "Community 8"
Cohesion: 0.07
Nodes (21): auditorDisplay(), dash(), expressName(), formatYm(), formatYmd(), sampleTypeName(), siteName(), unitName() (+13 more)
### Community 10 - "Community 10"
Cohesion: 0.08
Nodes (32): toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes() (+24 more)
### Community 11 - "Community 11"
### Community 9 - "Community 9"
Cohesion: 0.07
Nodes (22): handleBlur(), handleFocus(), handleInput(), fetchEthnicList(), addSample(), applyDonationBundleToForm(), confirmBatchTransportApply(), createEmptyTransport() (+14 more)
### Community 12 - "Community 12"
### Community 10 - "Community 10"
Cohesion: 0.09
Nodes (30): base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes(), sha256Hex() (+22 more)
### Community 11 - "Community 11"
Cohesion: 0.09
Nodes (8): getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager, validateStorageData()
### Community 13 - "Community 13"
### Community 12 - "Community 12"
Cohesion: 0.07
Nodes (17): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), collectIds(), postorder(), preorder(), applyTreeExpand() (+9 more)
### Community 13 - "Community 13"
Cohesion: 0.07
Nodes (24): fetchCreateSite(), fetchDeleteSite(), fetchDictDataOptions(), fetchSiteList(), fetchUpdateSite(), fetchUserList(), formatNowDatetime(), formatHandoverUserLabel() (+16 more)
### Community 14 - "Community 14"
Cohesion: 0.08
Nodes (11): maskIdCard(), buildOutboundPilotContextSections(), applicationStatusLabel(), applicationStatusTagType(), infusionMethodLabel(), infusionStatusLabel(), infusionStatusTagType(), qcStatusLabel() (+3 more)
@@ -142,21 +149,21 @@ Cohesion: 0.09
Nodes (9): fetchGetAllUpgradeLogs(), fetchGetChinaMapData(), fetchGetComments(), fetchGetCurrentVersion(), fetchGetLatestUpgradeLog(), fetchGetSystemConfig(), fetchGetUpgradeLogs(), systemUpgrade() (+1 more)
### Community 16 - "Community 16"
Cohesion: 0.09
Nodes (20): fetchCreateSite(), fetchDeleteSite(), fetchSiteList(), fetchUpdateSite(), fetchUserList(), formatHandoverUserLabel(), formatNowDatetime(), remoteSearchHandoverUsers() (+12 more)
### Community 17 - "Community 17"
Cohesion: 0.11
Nodes (21): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolDetail(), buildInsuranceAttachmentsValue(), buildInsurancePayload(), formatYmdFromAny(), fullFileUrl(), handleBatchEdit() (+13 more)
### Community 18 - "Community 18"
### Community 17 - "Community 17"
Cohesion: 0.1
Nodes (19): fetchCollectionRegionList(), fetchCreateCollectionRegion(), fetchCreateHospital(), fetchDeleteCollectionRegion(), fetchDeleteHospital(), fetchHospitalList(), fetchUpdateCollectionRegion(), fetchUpdateHospital() (+11 more)
### Community 19 - "Community 19"
### Community 18 - "Community 18"
Cohesion: 0.13
Nodes (18): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), clearTableSelection(), handleBatchComplete(), handleBatchStart() (+10 more)
### Community 19 - "Community 19"
Cohesion: 0.11
Nodes (19): fetchCreateUser(), fetchDeleteUser(), fetchResetPassword(), fetchRoleOptions(), fetchUpdateUser(), fetchUserDetail(), formatUserDeptDisplay(), handleAdd() (+11 more)
### Community 20 - "Community 20"
Cohesion: 0.12
Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
@@ -166,8 +173,8 @@ Cohesion: 0.1
Nodes (6): fetchProductionTaskDetail(), fetchProductionTaskList(), fetchUpdateProductionTask(), handleClose(), handleSubmit(), loadTaskDetail()
### Community 22 - "Community 22"
Cohesion: 0.14
Nodes (17): fetchCreateUser(), fetchDeleteUser(), fetchResetPassword(), fetchUpdateUser(), fetchUserDetail(), formatUserDeptDisplay(), handleAdd(), handleDelete() (+9 more)
Cohesion: 0.12
Nodes (12): fetchApproveTask(), fetchBusinessAllTasks(), fetchCompletedTasks(), fetchDesignerData(), fetchInstanceDetail(), fetchMyInstances(), fetchPendingTasks(), fetchProcessDefList() (+4 more)
### Community 23 - "Community 23"
Cohesion: 0.16
@@ -190,86 +197,128 @@ Cohesion: 0.14
Nodes (8): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), useCeremony(), useTheme(), themeAnimation(), toggleTheme(), toggleTransition()
### Community 29 - "Community 29"
Cohesion: 0.17
Nodes (3): fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList()
Cohesion: 0.18
Nodes (3): fetchMaterialList(), fetchMaterialOptions(), fetchMaterialStockLogList()
### Community 31 - "Community 31"
### Community 30 - "Community 30"
Cohesion: 0.2
Nodes (2): fetchQcMaterialList(), fetchQcMaterialOptions()
### Community 32 - "Community 32"
Cohesion: 0.39
Nodes (6): isIgnorableScriptError(), normalizeErrorMessage(), registerPromiseErrorHandler(), registerResourceErrorHandler(), scriptErrorHandler(), setupErrorHandle()
### Community 32 - "Community 32"
### Community 33 - "Community 33"
Cohesion: 0.36
Nodes (1): TableHeightCalculator
### Community 33 - "Community 33"
### Community 34 - "Community 34"
Cohesion: 0.25
Nodes (2): fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList()
### Community 35 - "Community 35"
Cohesion: 0.25
Nodes (2): fetchQcTaskDetail(), fetchQcTaskList()
### Community 34 - "Community 34"
Cohesion: 0.32
Nodes (3): annotateForkEdges(), chainApiToElements(), nextAncestorLink()
### Community 36 - "Community 36"
Cohesion: 0.25
Nodes (3): fetchOutboundQcDetail(), fetchQcWorkOrderDetail(), fetchQcWorkOrderList()
### Community 35 - "Community 35"
### Community 37 - "Community 37"
Cohesion: 0.33
Nodes (2): logApiCryptoBootInfo(), maskSecret()
### Community 36 - "Community 36"
### Community 38 - "Community 38"
Cohesion: 0.29
Nodes (2): fetchLeaveDetail(), fetchLeaveList()
### Community 39 - "Community 39"
Cohesion: 0.47
Nodes (3): isPaymentDueWithinWarnWindow(), parsePaymentDueYmd(), startOfLocalDay()
### Community 39 - "Community 39"
### Community 42 - "Community 42"
Cohesion: 0.33
Nodes (2): fetchQcLabTestItemList(), fetchQcLabTestItemsActive()
Nodes (2): fetchSampleReceptionCheckItemList(), fetchSampleReceptionCheckItemsActive()
### Community 41 - "Community 41"
### Community 43 - "Community 43"
Cohesion: 0.33
Nodes (2): fetchQcThirdPartyCompanyList(), fetchQcThirdPartyCompanyOptions()
### Community 45 - "Community 45"
Cohesion: 0.5
Nodes (2): focusInput(), handleKeydown()
### Community 42 - "Community 42"
### Community 46 - "Community 46"
Cohesion: 0.67
Nodes (2): if(), logSidebarMenu()
### Community 43 - "Community 43"
### Community 47 - "Community 47"
Cohesion: 0.5
Nodes (1): fetchStorageEntrySmsList()
### Community 45 - "Community 45"
### Community 48 - "Community 48"
Cohesion: 0.5
Nodes (1): fetchSampleSmsNotificationList()
### Community 50 - "Community 50"
Cohesion: 1.0
Nodes (2): getSettingDefaults(), resetToDefaults()
### Community 47 - "Community 47"
### Community 52 - "Community 52"
Cohesion: 1.0
Nodes (2): defaultAvatarPathByRole(), resolveUserAvatarUrl()
### Community 59 - "Community 59"
Cohesion: 0.67
Nodes (1): fetchInfusionScheduleOutboundHandover()
### Community 60 - "Community 60"
Cohesion: 0.67
Nodes (2): fetchDeleteProjectSystemItem(), if()
## Knowledge Gaps
- **Thin community `Community 24`** (17 nodes): `ComponentLoader`, `.constructor()`, `.createEmptyComponent()`, `.createErrorComponent()`, `.load()`, `.loadIframe()`, `.loadLayout()`, `.load()`, `RouteTransformer`, `.extractFirstSegment()`, `.handleFirstLevelRoute()`, `.handleIframeRoute()`, `.handleNormalRoute()`, `.isFirstLevelRoute()`, `.transform()`, `ComponentLoader.ts`, `RouteTransformer.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 32`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
- **Thin community `Community 30`** (10 nodes): `fetchBatchStockInQcMaterial()`, `fetchBatchStockOutQcMaterial()`, `fetchCreateQcMaterial()`, `fetchDeleteQcMaterial()`, `fetchQcMaterialList()`, `fetchQcMaterialOptions()`, `fetchStockInQcMaterial()`, `fetchStockOutQcMaterial()`, `fetchUpdateQcMaterial()`, `qc-material.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 33`** (8 nodes): `fetchCompleteQcTask()`, `fetchCreateQcTask()`, `fetchDeleteQcTask()`, `fetchQcTaskDetail()`, `fetchQcTaskList()`, `fetchStartQcTask()`, `fetchUpdateQcTaskAttachments()`, `qc-task.ts`
- **Thin community `Community 33`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 35`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
- **Thin community `Community 34`** (8 nodes): `fetchCompleteProductionWorkOrder()`, `fetchConfigureProductionWorkOrder()`, `fetchCreateProductionWorkOrder()`, `fetchDeleteProductionWorkOrder()`, `fetchProductionWorkOrderDetail()`, `fetchProductionWorkOrderList()`, `fetchUpdateProductionWorkOrder()`, `production-work-order.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 39`** (6 nodes): `fetchCreateQcLabTestItem()`, `fetchDeleteQcLabTestItem()`, `fetchQcLabTestItemList()`, `fetchQcLabTestItemsActive()`, `fetchUpdateQcLabTestItem()`, `qc-lab-test-item.ts`
- **Thin community `Community 35`** (8 nodes): `fetchCompleteQcTask()`, `fetchCreateQcTask()`, `fetchDeleteQcTask()`, `fetchQcTaskDetail()`, `fetchQcTaskList()`, `fetchStartQcTask()`, `fetchUpdateQcTaskAttachments()`, `qc-task.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 41`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
- **Thin community `Community 37`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 42`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
- **Thin community `Community 38`** (7 nodes): `fetchCreateLeave()`, `fetchDeleteLeave()`, `fetchLeaveDetail()`, `fetchLeaveList()`, `fetchSubmitLeave()`, `fetchUpdateLeave()`, `leave.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 43`** (4 nodes): `fetchGenerateStorageEntrySms()`, `fetchStorageEntrySmsList()`, `fetchToggleStorageEntrySmsNotified()`, `storage-entry-sms-notification.ts`
- **Thin community `Community 42`** (6 nodes): `fetchCreateSampleReceptionCheckItem()`, `fetchDeleteSampleReceptionCheckItem()`, `fetchSampleReceptionCheckItemList()`, `fetchSampleReceptionCheckItemsActive()`, `fetchUpdateSampleReceptionCheckItem()`, `sample-reception-check-item.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 45`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
- **Thin community `Community 43`** (6 nodes): `fetchCreateQcThirdPartyCompany()`, `fetchDeleteQcThirdPartyCompany()`, `fetchQcThirdPartyCompanyList()`, `fetchQcThirdPartyCompanyOptions()`, `fetchUpdateQcThirdPartyCompany()`, `qc-third-party-company.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 47`** (3 nodes): `defaultAvatarPathByRole()`, `resolveUserAvatarUrl()`, `user-avatar.ts`
- **Thin community `Community 45`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 46`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 47`** (4 nodes): `fetchGenerateStorageEntrySms()`, `fetchStorageEntrySmsList()`, `fetchToggleStorageEntrySmsNotified()`, `storage-entry-sms-notification.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 48`** (4 nodes): `fetchGenerateSms()`, `fetchSampleSmsNotificationList()`, `fetchToggleSmsNotified()`, `sample-sms-notification.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 50`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 52`** (3 nodes): `defaultAvatarPathByRole()`, `resolveUserAvatarUrl()`, `user-avatar.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 59`** (3 nodes): `fetchInfusionScheduleOutboundHandover()`, `saveInfusionScheduleOutboundHandover()`, `infusion-schedule-handover.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 60`** (3 nodes): `fetchDeleteProjectSystemItem()`, `if()`, `index.vue`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 8`, `Community 9`, `Community 11`, `Community 13`, `Community 15`, `Community 16`, `Community 17`, `Community 18`, `Community 19`, `Community 21`, `Community 22`, `Community 26`, `Community 29`, `Community 33`, `Community 34`, `Community 39`, `Community 43`?**
_High betweenness centrality (0.283) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 1` to `Community 0`, `Community 7`, `Community 8`, `Community 10`, `Community 11`, `Community 14`, `Community 15`, `Community 16`, `Community 17`?**
_High betweenness centrality (0.122) - this node is a cross-community bridge._
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 7`, `Community 8`, `Community 9`, `Community 12`, `Community 13`, `Community 15`, `Community 16`, `Community 17`, `Community 18`, `Community 19`, `Community 21`, `Community 22`, `Community 26`, `Community 29`, `Community 30`, `Community 34`, `Community 35`, `Community 36`, `Community 38`, `Community 42`, `Community 43`, `Community 47`, `Community 48`, `Community 59`?**
_High betweenness centrality (0.265) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 4` to `Community 0`, `Community 3`, `Community 6`, `Community 7`, `Community 9`, `Community 13`, `Community 14`, `Community 15`, `Community 16`?**
_High betweenness centrality (0.120) - this node is a cross-community bridge._
- **Are the 195 inferred relationships involving `get()` (e.g. with `collectLeafFacilityNodesInTreeOrder()` and `buildTreePathLabelFromFlat()`) actually correct?**
_`get()` has 195 INFERRED edges - model-reasoned connections that need verification._
- **Are the 33 inferred relationships involving `push()` (e.g. with `collectLeafFacilityNodesInTreeOrder()` and `fetchAllPagedRecords()`) actually correct?**
+4 -4
View File
@@ -57,12 +57,12 @@
</div>
<div id="legend"></div>
</div>
<div id="stats">1844 nodes &middot; 2394 edges &middot; 262 communities</div>
<div id="stats">1845 nodes &middot; 2395 edges &middot; 269 communities</div>
</div>
<script>
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 35, "community_name": "Community 35", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 35, "community_name": "Community 35", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 35, "community_name": "Community 35", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 35, "community_name": "Community 35", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 35, "community_name": "Community 35", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 35, "community_name": "Community 35", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 79, "community_name": "Community 79", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 80, "community_name": "Community 80", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 20, "community_name": "Community 20", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 20, "community_name": "Community 20", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 20, "community_name": "Community 20", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 20, "community_name": "Community 20", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 20, "community_name": "Community 20", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_setuprolesdirective", "laLine truncated
const RAW_EDGES = [{"from": "app_vue", "to": "src_app_refreshbuttonautoicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "src_app_refreshpaneltitleicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "main_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "utils_sys_console_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_masksecret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_logapicryptobootinfo", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_main_masksecret", "to": "src_main_logapicryptobootinfo", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_ts", "to": "directives_index_setupglobdirectives", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_setupglobdirectives", "to": "core_auth_setupauthdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "core_roles_setuprolesdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_highlight_setuphighlightdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_ripple_setuprippledirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_core_roles_ts", "to": "core_roles_checkrolepermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_setuprolesdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_roles_checkrolepermission", "to": "core_roles_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_checkauthpermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_setupauthdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_checkauthpermission", "to": "core_auth_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_ripple_ts", "to": "business_ripple_setuprippledirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_highlightcode", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_insertlinenumbers", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_addcopybutton", "label": "contains", "title": "contains [EXTRACTED]", "dLine truncated
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 303}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 146}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 113}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 104}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 65}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 59}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 58}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 54}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 53}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 43}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 40}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 40}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 36}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 35}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 31}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 31}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 30}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 27}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 27}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 24}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 22}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 22}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 20}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 17}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 17}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 16}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 16}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 15}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 13}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 12}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 9}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 8}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 8}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 8}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 8}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 7}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 6}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 6}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 6}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 6}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 6}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 5}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 4}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 4}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 4}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 3}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 3}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 3}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 3}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 3}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 3}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 3}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 3}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 3}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 2}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 2}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 2}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 2}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 2}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 2}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 2}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 2}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 2}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 2}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 2}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 2}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 2}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 2}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 2}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 2}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "count": 2},Line truncated
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 37, "community_name": "Community 37", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 37, "community_name": "Community 37", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 37, "community_name": "Community 37", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 37, "community_name": "Community 37", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 37, "community_name": "Community 37", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 37, "community_name": "Community 37", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 86, "community_name": "Community 86", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 87, "community_name": "Community 87", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 20, "community_name": "Community 20", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 20, "community_name": "Community 20", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 20, "community_name": "Community 20", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 20, "community_name": "Community 20", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 20, "community_name": "Community 20", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_setuprolesdirective", "laLine truncated
const RAW_EDGES = [{"from": "app_vue", "to": "src_app_refreshbuttonautoicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "src_app_refreshpaneltitleicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "main_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "utils_sys_console_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_masksecret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_logapicryptobootinfo", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_main_masksecret", "to": "src_main_logapicryptobootinfo", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_ts", "to": "directives_index_setupglobdirectives", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_setupglobdirectives", "to": "core_auth_setupauthdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "core_roles_setuprolesdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_highlight_setuphighlightdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_ripple_setuprippledirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_core_roles_ts", "to": "core_roles_checkrolepermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_setuprolesdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_roles_checkrolepermission", "to": "core_roles_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_checkauthpermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_setupauthdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_checkauthpermission", "to": "core_auth_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_ripple_ts", "to": "business_ripple_setuprippledirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_highlightcode", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_insertlinenumbers", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_addcopybutton", "label": "contains", "title": "contains [EXTRACTED]", "dLine truncated
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 353}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 113}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 103}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 87}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 70}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 57}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 54}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 54}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 43}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 40}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 38}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 36}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 35}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 35}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 31}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 31}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 27}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 27}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 24}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 23}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 22}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 22}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 19}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 17}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 17}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 16}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 16}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 15}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 13}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 11}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 10}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 9}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 8}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 8}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 8}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 8}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 8}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 7}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 7}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 6}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 6}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 6}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 6}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 6}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 6}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 5}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 4}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 4}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 4}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 4}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 3}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 3}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 3}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 3}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 3}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 3}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 3}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 3}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 3}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 3}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 3}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 2}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 2}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 2}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 2}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 2}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 2}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 2}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 2}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 2}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "count": 2},Line truncated
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
function esc(s) {
+3 -3
View File
@@ -17,8 +17,8 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/common/index.ts": 1778582068.0254738,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/directive/directive.d.ts": 1778582068.026978,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/api/api.d.ts": 1778582068.0246184,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1779830492.5032978,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1779829952.0242388,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1779833050.885841,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1779833011.8080041,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/store/index.ts": 1778582068.0293276,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/router/index.ts": 1778775532.895603,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/locales/index.ts": 1778582068.004279,
@@ -269,7 +269,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/post/index.vue": 1779790369.3803756,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/category/index.vue": 1779790365.9680545,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/express/index.vue": 1779790366.8246427,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue": 1779790371.5427713,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue": 1779833149.3494532,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/detail.vue": 1779790371.4357243,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/modules/user-dialog.vue": 1779790371.5651114,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/modules/user-search.vue": 1779525781.643876,
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_system_user_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L1"}, {"id": "user_index_loadroleoptions", "label": "loadRoleOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L318"}, {"id": "user_index_formatuserdeptdisplay", "label": "formatUserDeptDisplay()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L341"}, {"id": "user_index_formatuserroledisplay", "label": "formatUserRoleDisplay()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L347"}, {"id": "user_index_filterdeptnode", "label": "filterDeptNode()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L390"}, {"id": "user_index_handledeptnodeclick", "label": "handleDeptNodeClick()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L399"}, {"id": "user_index_loaddepttree", "label": "loadDeptTree()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L405"}, {"id": "user_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L414"}, {"id": "user_index_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L431"}, {"id": "user_index_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L436"}, {"id": "user_index_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L445"}, {"id": "user_index_handleadd", "label": "handleAdd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L461"}, {"id": "user_index_handleedit", "label": "handleEdit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L472"}, {"id": "user_index_handlesubmit", "label": "handleSubmit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L498"}, {"id": "user_index_handleselectionchange", "label": "handleSelectionChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L538"}, {"id": "user_index_handledelete", "label": "handleDelete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L542"}, {"id": "user_index_handlebatchresetpwd", "label": "handleBatchResetPwd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L548"}, {"id": "user_index_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L600"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_system_user_index_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L292", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_system_user_index_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L293", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_system_user_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_system_view_dialog_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue", "source_location": "L303", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_system_user_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_admin", "relation": "imports_from", "confidence": "EXTRACTED", "source_fileLine truncated
@@ -70,12 +70,33 @@
</el-form>
</div>
<div v-if="activeTypeTab !== 'all' && activeTypeTab !== 'outbound'" class="list-toolbar">
<div v-if="activeTypeTab !== 'all'" class="list-toolbar">
<div class="list-toolbar-row">
<el-button class="btn-main" type="primary" @click="handleAdd">
<div class="list-toolbar-selected">
已选 <span class="sel-num">{{ selectedRows.length }}</span> 项
</div>
<el-button
v-if="activeTypeTab !== 'outbound'"
class="btn-main"
type="primary"
@click="handleAdd"
>
<el-icon><Plus /></el-icon
>{{ activeTypeTab === 'temporary' ? '新增临时工单' : '新增生产工单' }}
</el-button>
<el-button
class="btn-ghost"
:disabled="selectedRows.length !== 1"
@click="handleToolbarEditTask"
>
<el-icon><EditPen /></el-icon>编辑任务
</el-button>
<el-button class="btn-ghost" :disabled="!canToolbarDispatch" @click="handleToolbarDispatch">
<el-icon><Position /></el-icon>派发任务
</el-button>
<el-button class="btn-ghost" :disabled="!canToolbarComplete" @click="handleToolbarComplete">
<el-icon><Check /></el-icon>完成工单
</el-button>
</div>
</div>
@@ -86,8 +107,17 @@
:data="tableData"
v-loading="loading"
stripe
row-key="id"
@selection-change="handleSelectionChange"
@row-dblclick="handleView"
>
<el-table-column
v-if="activeTypeTab !== 'all'"
type="selection"
min-width="55"
align="center"
header-align="center"
/>
<el-table-column
type="index"
label="序号"
@@ -260,35 +290,18 @@
<el-table-column
v-if="activeTypeTab !== 'all'"
label="操作"
min-width="600"
min-width="260"
fixed="right"
align="center"
header-align="center"
>
<template #default="{ row }">
<el-button class="btn-op-item" @click="handleView(row)"
><el-icon><View /></el-icon>查看详情</el-button
><el-icon><View /></el-icon>查看</el-button
>
<el-button class="btn-op-item" @click="handleEditRemark(row)">
<el-icon><EditPen /></el-icon>编辑
</el-button>
<el-button class="btn-op-item" @click="handleEditTask(row)"
><el-icon><EditPen /></el-icon>编辑任务</el-button
>
<el-button
v-if="row.workOrderStatus === 'dpz' || row.workOrderStatus === 'jxz'"
class="btn-op-item primary"
@click="handleOpenDispatch(row)"
>
<el-icon><Position /></el-icon>派发任务
</el-button>
<el-button
v-if="row.workOrderStatus === 'dpz' || row.workOrderStatus === 'jxz'"
class="btn-op-item"
@click="handleComplete(row)"
>
<el-icon><Check /></el-icon>完成工单
</el-button>
<el-button
v-if="row.workOrderStatus !== 'ywc'"
class="btn-op-item"
@@ -668,6 +681,7 @@
function handleTypeTabChange() {
pagination.page = 1
clearSelection()
loadData()
}
@@ -767,10 +781,77 @@
const searchForm = reactive({ keyword: '', workOrderStatus: '' })
const createTimeRange = ref<[string, string] | null>(getDefaultLast30DaysRange())
const tableData = ref<any[]>([])
const selectedRows = ref<any[]>([])
const workOrderListTableRef = ref<TableInstance>()
const loading = ref(false)
const pagination = reactive({ page: 1, pageSize: 10, total: 0 })
const canToolbarDispatch = computed(() => {
if (selectedRows.value.length !== 1) return false
const status = selectedRows.value[0].workOrderStatus
return status === 'dpz' || status === 'jxz'
})
const canToolbarComplete = computed(() => {
if (!selectedRows.value.length) return false
return selectedRows.value.every(
(row) => row.workOrderStatus === 'dpz' || row.workOrderStatus === 'jxz'
)
})
function handleSelectionChange(rows: any[]) {
selectedRows.value = rows
}
function clearSelection() {
selectedRows.value = []
workOrderListTableRef.value?.clearSelection?.()
}
function requireSingleSelection(action: string) {
if (selectedRows.value.length !== 1) {
ElMessage.warning(`请选择一个工单后再${action}`)
return null
}
return selectedRows.value[0]
}
function handleToolbarEditTask() {
const row = requireSingleSelection('编辑任务')
if (row) handleEditTask(row)
}
function handleToolbarDispatch() {
const row = requireSingleSelection('派发任务')
if (!row) return
if (row.workOrderStatus !== 'dpz' && row.workOrderStatus !== 'jxz') {
ElMessage.warning('仅待配置或进行中的工单可派发任务')
return
}
handleOpenDispatch(row)
}
async function handleToolbarComplete() {
const rows = selectedRows.value.filter(
(row) => row.workOrderStatus === 'dpz' || row.workOrderStatus === 'jxz'
)
if (!rows.length) {
ElMessage.warning('请选择待配置或进行中的工单')
return
}
const message =
rows.length === 1
? `确定要完成工单「${rows[0].workOrderNo || ''}」吗?`
: `确定要完成选中的 ${rows.length} 个工单吗?`
await ElMessageBox.confirm(message, '提示', { type: 'warning' })
for (const row of rows) {
await fetchCompleteProductionWorkOrder(row.id, {})
}
ElMessage.success(rows.length === 1 ? '工单已完成' : `已完成 ${rows.length} 个工单`)
clearSelection()
loadData()
}
async function layoutWorkOrderTable() {
await nextTick()
workOrderListTableRef.value?.doLayout?.()
@@ -1074,12 +1155,6 @@
detail.value = await fetchProductionWorkOrderDetail(row.id)
viewVisible.value = true
}
async function handleComplete(row: any) {
await ElMessageBox.confirm('确定要完成该工单吗?', '提示', { type: 'warning' })
await fetchCompleteProductionWorkOrder(row.id, {})
ElMessage.success('工单已完成')
loadData()
}
// ── 派发任务 ──────────────────────────────────────────
const dispatchVisible = ref(false)
+94 -24
View File
@@ -65,11 +65,45 @@
<div class="list-toolbar">
<div class="list-toolbar-row">
<div class="list-toolbar-selected">
已选 <span class="sel-num">{{ selectedRows.length }}</span> 项
</div>
<el-button class="btn-main" type="primary" @click="handleAdd">
<el-icon><Plus /></el-icon>
新增用户
</el-button>
</div>
<el-button
class="btn-ghost"
:disabled="selectedRows.length === 0"
@click="handleBatchResetPwd"
>
<el-icon><Key /></el-icon>
重置密码
</el-button>
<el-button
class="btn-ghost"
:disabled="selectedRows.length !== 1"
@click="handleToolbarView"
>
<el-icon><View /></el-icon>
查看
</el-button>
<el-button
class="btn-ghost"
:disabled="selectedRows.length !== 1"
@click="handleToolbarEdit"
>
<el-icon><Edit /></el-icon>
编辑
</el-button>
<el-button
class="btn-ghost"
type="danger"
:disabled="selectedRows.length === 0"
@click="handleBatchDelete"
>
<el-icon><Delete /></el-icon>
删除
</el-button>
</div>
</div>
@@ -80,8 +114,10 @@
v-loading="loading"
stripe
row-key="id"
@selection-change="handleSelectionChange"
@row-dblclick="handleView"
>
<el-table-column type="selection" min-width="55" align="center" header-align="center" />
<el-table-column
type="index"
label="序号"
@@ -146,22 +182,6 @@
align="center"
header-align="center"
/>
<el-table-column
label="操作"
min-width="400"
fixed="right"
align="center"
header-align="center"
>
<template #default="{ row }">
<el-button class="btn-op-item" @click="handleView(row)"
><el-icon><View /></el-icon>查看</el-button
>
<el-button class="btn-op-item primary" @click="handleEdit(row)">编辑</el-button>
<el-button class="btn-op-item" @click="handleResetPwd(row)">重置密码</el-button>
<el-button class="btn-op-item" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination list-pager-bar">
@@ -287,7 +307,10 @@
View,
UserFilled,
RefreshLeft,
Search
Search,
Key,
Edit,
Delete
} from '@element-plus/icons-vue'
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
import {
@@ -344,6 +367,7 @@
const searchForm = reactive<{ keyword: string; status: string }>({ keyword: '', status: '' })
const tableData = ref<Api.User.UserItem[]>([])
const selectedRows = ref<Api.User.UserItem[]>([])
const loading = ref(false)
const pagination = reactive({ page: 1, pageSize: 10, total: 0 })
@@ -523,18 +547,64 @@
}
}
async function handleDelete(row: Api.User.UserItem) {
await ElMessageBox.confirm(`确定删除用户「${row.nickName}」吗?`, '提示', { type: 'warning' })
const handleSelectionChange = (rows: Api.User.UserItem[]) => {
selectedRows.value = rows
}
function requireSingleSelection(action: string): Api.User.UserItem | null {
if (selectedRows.value.length !== 1) {
ElMessage.warning(`请选择一个用户后再${action}`)
return null
}
return selectedRows.value[0]
}
function handleToolbarView() {
const row = requireSingleSelection('查看')
if (row) handleView(row)
}
function handleToolbarEdit() {
const row = requireSingleSelection('编辑')
if (row) handleEdit(row)
}
async function handleBatchDelete() {
const rows = selectedRows.value
if (!rows.length) {
ElMessage.warning('请至少选择一项')
return
}
const message =
rows.length === 1
? `确定删除用户「${rows[0].nickName}」吗?`
: `确定删除选中的 ${rows.length} 个用户吗?`
await ElMessageBox.confirm(message, '提示', { type: 'warning' })
for (const row of rows) {
await fetchDeleteUser(row.id)
}
ElMessage.success('删除成功')
selectedRows.value = []
await loadData()
}
async function handleResetPwd(row: Api.User.UserItem) {
await ElMessageBox.confirm(`确定将用户「${row.nickName}」的密码重置为 111111 吗?`, '提示', {
type: 'warning'
})
async function handleBatchResetPwd() {
const rows = selectedRows.value
if (!rows.length) {
ElMessage.warning('请至少选择一项')
return
}
const message =
rows.length === 1
? `确定将用户「${rows[0].nickName}」的密码重置为 111111 吗?`
: `确定将选中的 ${rows.length} 个用户的密码重置为 111111 吗?`
await ElMessageBox.confirm(message, '提示', { type: 'warning' })
for (const row of rows) {
await fetchResetPassword(row.id)
}
ElMessage.success('密码重置成功')
selectedRows.value = []
}
// ---- 查看弹窗 ----
const viewVisible = ref(false)