提交
This commit is contained in:
1 parent
fb85230d25
commit
05684ba2a4
56 files changed
+26110
-13601
No files matched your search
@@ -68,6 +68,7 @@ Full specs: `openspec/changes/zkxw-engineering-standards/specs/*/spec.md`. Below
|
||||
- **Backend**: Python 3.9, FastAPI + SQLAlchemy + Pydantic v2. Routes stay thin; business logic goes in `app/services/` and `app/crud/`. Config via `pydantic-settings` + `.env` files.
|
||||
- **DB changes**: SHALL maintain SQL in `docs/sql/`. Schema changes SHALL align with `database-conventions` public field rules.
|
||||
- **Commit messages**: SHALL be complete sentences describing "what changed and why". Follow Conventional Commits (`feat|fix|docs|…`).
|
||||
- **Field consistency (CRUD ↔ Schema ↔ Frontend)**: When implementing CRUD for any entity, the `_row_to_dict` function is the **single source of truth** for all readable fields. The CreateBody/UpdateBody Pydantic schemas and the frontend `formData` initialization SHALL include every writable field present in `_row_to_dict` (excluding computed/read-only fields like `id`, `createTime`, `updateTime`, `stockQty`). Run `python scripts/check_field_consistency.py` after implementation to verify. See `docs/dev-field-consistency.md` for details.
|
||||
|
||||
### Permission Conventions
|
||||
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
55545
|
||||
65187
|
||||
@@ -74,6 +74,8 @@ class ConsumableCreateBody(BaseModel):
|
||||
standard_usage: Optional[str] = Field(None, alias="standardUsage")
|
||||
unit: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
warning_qty: Optional[float] = Field(0, alias="warningQty")
|
||||
status: Optional[str] = Field("1", alias="status")
|
||||
order_num: Optional[int] = Field(0, alias="orderNum")
|
||||
remark: Optional[str] = None
|
||||
|
||||
@@ -86,6 +88,8 @@ class ConsumableUpdateBody(BaseModel):
|
||||
standard_usage: Optional[str] = Field(None, alias="standardUsage")
|
||||
unit: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
warning_qty: Optional[float] = Field(None, alias="warningQty")
|
||||
status: Optional[str] = Field(None, alias="status")
|
||||
order_num: Optional[int] = Field(None, alias="orderNum")
|
||||
remark: Optional[str] = None
|
||||
|
||||
@@ -131,6 +135,8 @@ async def create_consumable(
|
||||
unit=body.unit,
|
||||
description=body.description,
|
||||
tenant_no=tenant_no,
|
||||
warning_qty=body.warning_qty,
|
||||
status=body.status,
|
||||
order_num=body.order_num,
|
||||
remark=body.remark,
|
||||
user_id=user.get("user_id"),
|
||||
@@ -158,6 +164,8 @@ async def update_consumable(
|
||||
standard_usage=payload.get("standard_usage"),
|
||||
unit=payload.get("unit"),
|
||||
description=payload.get("description"),
|
||||
warning_qty=payload.get("warning_qty"),
|
||||
status=payload.get("status"),
|
||||
order_num=payload.get("order_num"),
|
||||
remark=payload.get("remark"),
|
||||
user_id=user.get("user_id"),
|
||||
@@ -358,6 +366,8 @@ class ReagentCreateBody(BaseModel):
|
||||
standard_usage: Optional[str] = Field(None, alias="standardUsage")
|
||||
unit: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
warning_qty: Optional[float] = Field(0, alias="warningQty")
|
||||
status: Optional[str] = Field("1", alias="status")
|
||||
order_num: Optional[int] = Field(0, alias="orderNum")
|
||||
remark: Optional[str] = None
|
||||
|
||||
@@ -370,6 +380,8 @@ class ReagentUpdateBody(BaseModel):
|
||||
standard_usage: Optional[str] = Field(None, alias="standardUsage")
|
||||
unit: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
warning_qty: Optional[float] = Field(None, alias="warningQty")
|
||||
status: Optional[str] = Field(None, alias="status")
|
||||
order_num: Optional[int] = Field(None, alias="orderNum")
|
||||
remark: Optional[str] = None
|
||||
|
||||
@@ -415,6 +427,8 @@ async def create_reagent(
|
||||
unit=body.unit,
|
||||
description=body.description,
|
||||
tenant_no=tenant_no,
|
||||
warning_qty=body.warning_qty,
|
||||
status=body.status,
|
||||
order_num=body.order_num,
|
||||
remark=body.remark,
|
||||
user_id=user.get("user_id"),
|
||||
@@ -442,6 +456,8 @@ async def update_reagent(
|
||||
standard_usage=payload.get("standard_usage"),
|
||||
unit=payload.get("unit"),
|
||||
description=payload.get("description"),
|
||||
warning_qty=payload.get("warning_qty"),
|
||||
status=payload.get("status"),
|
||||
order_num=payload.get("order_num"),
|
||||
remark=payload.get("remark"),
|
||||
user_id=user.get("user_id"),
|
||||
|
||||
@@ -126,6 +126,8 @@ def create_consumable(
|
||||
unit: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
tenant_no: str = "zkxw",
|
||||
warning_qty: Optional[float] = None,
|
||||
status: Optional[str] = None,
|
||||
order_num: Optional[int] = None,
|
||||
remark: Optional[str] = None,
|
||||
user_id: Optional[str] = None,
|
||||
@@ -144,6 +146,8 @@ def create_consumable(
|
||||
unit=(unit or "").strip() or None,
|
||||
description=(description or "").strip() or None,
|
||||
tenant_no=tenant_no,
|
||||
warning_qty=warning_qty if warning_qty is not None else 0,
|
||||
status=_norm_status(status),
|
||||
order_num=order_num if order_num is not None else 0,
|
||||
remark=(remark or "").strip() or None,
|
||||
create_by=user_id,
|
||||
@@ -169,6 +173,8 @@ def update_consumable(
|
||||
standard_usage: Optional[str] = None,
|
||||
unit: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
warning_qty: Optional[float] = None,
|
||||
status: Optional[str] = None,
|
||||
order_num: Optional[int] = None,
|
||||
remark: Optional[str] = None,
|
||||
user_id: Optional[str] = None,
|
||||
@@ -193,6 +199,10 @@ def update_consumable(
|
||||
obj.unit = (unit or "").strip() or None
|
||||
if description is not None:
|
||||
obj.description = (description or "").strip() or None
|
||||
if warning_qty is not None:
|
||||
obj.warning_qty = warning_qty
|
||||
if status is not None:
|
||||
obj.status = _norm_status(status)
|
||||
if order_num is not None:
|
||||
obj.order_num = order_num
|
||||
if remark is not None:
|
||||
|
||||
@@ -72,6 +72,7 @@ def _row_to_dict(r: BizConsumableStockLog, *, create_by_name: str = "") -> Dict[
|
||||
"stockBefore": float(r.stock_before) if r.stock_before is not None else 0,
|
||||
"stockAfter": float(r.stock_after) if r.stock_after is not None else 0,
|
||||
"stepId": r.step_id or "",
|
||||
"stepName": r.step_name or "",
|
||||
"taskId": r.task_id or "",
|
||||
"taskNo": r.task_no or "",
|
||||
"receiver": receiver,
|
||||
@@ -204,6 +205,7 @@ def revert_step_stock_changes(
|
||||
def deduct_for_step(
|
||||
db: Session,
|
||||
step_id: str,
|
||||
step_name: str,
|
||||
task_id: str,
|
||||
task_no: str,
|
||||
consumable_items: List[Dict[str, Any]],
|
||||
@@ -265,6 +267,7 @@ def deduct_for_step(
|
||||
stock_after=new_stock,
|
||||
source_type="step_save",
|
||||
step_id=step_id,
|
||||
step_name=(step_name or "").strip() or None,
|
||||
task_id=task_id,
|
||||
task_no=task_no,
|
||||
tenant_no=tenant_no,
|
||||
|
||||
@@ -839,7 +839,9 @@ def replace_step_reagents(
|
||||
).first()
|
||||
task_id = ""
|
||||
task_no = ""
|
||||
step_name = ""
|
||||
if step_row:
|
||||
step_name = step_row.process_name or ""
|
||||
task_row = db.query(BizProductionTask).filter(
|
||||
and_(BizProductionTask.id == step_row.task_id, BizProductionTask.del_flag == 0)
|
||||
).first()
|
||||
@@ -871,7 +873,7 @@ def replace_step_reagents(
|
||||
|
||||
# Deduct stock based on actual_usage
|
||||
reagent_stock_log_crud.deduct_for_step(
|
||||
db, step_id, task_id, task_no, items, tenant_no, user_id, "",
|
||||
db, step_id, step_name, task_id, task_no, items, tenant_no, user_id, "",
|
||||
)
|
||||
|
||||
db.commit()
|
||||
@@ -891,7 +893,9 @@ def replace_step_consumables(
|
||||
).first()
|
||||
task_id = ""
|
||||
task_no = ""
|
||||
step_name = ""
|
||||
if step_row:
|
||||
step_name = step_row.process_name or ""
|
||||
task_row = db.query(BizProductionTask).filter(
|
||||
and_(BizProductionTask.id == step_row.task_id, BizProductionTask.del_flag == 0)
|
||||
).first()
|
||||
@@ -923,7 +927,7 @@ def replace_step_consumables(
|
||||
|
||||
# Deduct stock based on actual_usage
|
||||
consumable_stock_log_crud.deduct_for_step(
|
||||
db, step_id, task_id, task_no, items, tenant_no, user_id, "",
|
||||
db, step_id, step_name, task_id, task_no, items, tenant_no, user_id, "",
|
||||
)
|
||||
|
||||
db.commit()
|
||||
|
||||
@@ -126,6 +126,8 @@ def create_reagent(
|
||||
unit: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
tenant_no: str = "zkxw",
|
||||
warning_qty: Optional[float] = None,
|
||||
status: Optional[str] = None,
|
||||
order_num: Optional[int] = None,
|
||||
remark: Optional[str] = None,
|
||||
user_id: Optional[str] = None,
|
||||
@@ -144,6 +146,8 @@ def create_reagent(
|
||||
unit=(unit or "").strip() or None,
|
||||
description=(description or "").strip() or None,
|
||||
tenant_no=tenant_no,
|
||||
warning_qty=warning_qty if warning_qty is not None else 0,
|
||||
status=_norm_status(status),
|
||||
order_num=order_num if order_num is not None else 0,
|
||||
remark=(remark or "").strip() or None,
|
||||
create_by=user_id,
|
||||
@@ -169,6 +173,8 @@ def update_reagent(
|
||||
standard_usage: Optional[str] = None,
|
||||
unit: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
warning_qty: Optional[float] = None,
|
||||
status: Optional[str] = None,
|
||||
order_num: Optional[int] = None,
|
||||
remark: Optional[str] = None,
|
||||
user_id: Optional[str] = None,
|
||||
@@ -193,6 +199,10 @@ def update_reagent(
|
||||
obj.unit = (unit or "").strip() or None
|
||||
if description is not None:
|
||||
obj.description = (description or "").strip() or None
|
||||
if warning_qty is not None:
|
||||
obj.warning_qty = warning_qty
|
||||
if status is not None:
|
||||
obj.status = _norm_status(status)
|
||||
if order_num is not None:
|
||||
obj.order_num = order_num
|
||||
if remark is not None:
|
||||
|
||||
@@ -72,6 +72,7 @@ def _row_to_dict(r: BizReagentStockLog, *, create_by_name: str = "") -> Dict[str
|
||||
"stockBefore": float(r.stock_before) if r.stock_before is not None else 0,
|
||||
"stockAfter": float(r.stock_after) if r.stock_after is not None else 0,
|
||||
"stepId": r.step_id or "",
|
||||
"stepName": r.step_name or "",
|
||||
"taskId": r.task_id or "",
|
||||
"taskNo": r.task_no or "",
|
||||
"receiver": receiver,
|
||||
@@ -204,6 +205,7 @@ def revert_step_stock_changes(
|
||||
def deduct_for_step(
|
||||
db: Session,
|
||||
step_id: str,
|
||||
step_name: str,
|
||||
task_id: str,
|
||||
task_no: str,
|
||||
reagent_items: List[Dict[str, Any]],
|
||||
@@ -264,6 +266,7 @@ def deduct_for_step(
|
||||
stock_after=new_stock,
|
||||
source_type="step_save",
|
||||
step_id=step_id,
|
||||
step_name=(step_name or "").strip() or None,
|
||||
task_id=task_id,
|
||||
task_no=task_no,
|
||||
tenant_no=tenant_no,
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_stock_log_py", "label": "consumable_stock_log.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L1"}, {"id": "crud_consumable_stock_log_user_nick_name_map", "label": "_user_nick_name_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L16"}, {"id": "crud_consumable_stock_log_parse_receiver_purpose_from_remark", "label": "_parse_receiver_purpose_from_remark()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L24"}, {"id": "crud_consumable_stock_log_resolve_receiver_purpose", "label": "_resolve_receiver_purpose()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L35"}, {"id": "crud_consumable_stock_log_display_remark", "label": "_display_remark()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L45"}, {"id": "crud_consumable_stock_log_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L60"}, {"id": "crud_consumable_stock_log_list_stock_logs", "label": "list_stock_logs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L89"}, {"id": "crud_consumable_stock_log_revert_step_stock_changes", "label": "revert_step_stock_changes()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L157"}, {"id": "crud_consumable_stock_log_deduct_for_step", "label": "deduct_for_step()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L204"}, {"id": "crud_consumable_stock_log_rationale_1", "label": "\u8017\u6750\u53d8\u52a8\u8bb0\u5f55 CRUD\uff08biz_consumable_stock_log\uff09", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L1"}, {"id": "crud_consumable_stock_log_rationale_163", "label": "\u64a4\u9500\u6b65\u9aa4\u6b64\u524d step_save \u6263\u51cf\uff0c\u4fbf\u4e8e\u91cd\u65b0\u586b\u62a5\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L163"}, {"id": "crud_consumable_stock_log_rationale_214", "label": "\u6263\u51cf\u8017\u6750\u5e93\u5b58\u5e76\u751f\u6210\u53d8\u52a8\u8bb0\u5f55\u3002\u8c03\u7528\u65b9\u63a7\u5236\u4e8b\u52a1\uff0c\u672c\u51fd\u6570\u4e0d commit\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L214"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_stock_log_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_stock_log_py", "target": "decimal", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_stock_log_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L6", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_stock_log_py", "target": "fastapi", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L8", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_stock_log_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L9", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_stock_log_py", "target": "sqlalchemy_orm", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py", "source_location": "L10", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_stock_log_py", "target": "appLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_production_task_py", "label": "production_task.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L1"}, {"id": "crud_production_task_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L43"}, {"id": "crud_production_task_generate_task_no", "label": "_generate_task_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L47"}, {"id": "crud_production_task_task_to_dict", "label": "_task_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L61"}, {"id": "crud_production_task_step_to_dict", "label": "_step_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L83"}, {"id": "crud_production_task_step_reagent_to_dict", "label": "_step_reagent_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L103"}, {"id": "crud_production_task_step_consumable_to_dict", "label": "_step_consumable_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L118"}, {"id": "crud_production_task_step_output_to_dict", "label": "_step_output_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L133"}, {"id": "crud_production_task_step_data_collection_to_dict", "label": "_step_data_collection_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L144"}, {"id": "crud_production_task_task_input_to_dict", "label": "_task_input_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L155"}, {"id": "crud_production_task_task_output_to_dict", "label": "_task_output_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L177"}, {"id": "crud_production_task_soft_delete_sub", "label": "_soft_delete_sub()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L202"}, {"id": "crud_production_task_clone_step_reagents", "label": "_clone_step_reagents()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L215"}, {"id": "crud_production_task_clone_step_consumables", "label": "_clone_step_consumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L233"}, {"id": "crud_production_task_clone_step_outputs", "label": "_clone_step_outputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L251"}, {"id": "crud_production_task_clone_step_data_collections", "label": "_clone_step_data_collections()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L268"}, {"id": "crud_production_task_clone_route_to_task", "label": "_clone_route_to_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L284"}, {"id": "crud_production_task_create_production_task", "label": "create_production_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L317"}, {"id": "crud_production_task_list_production_tasks", "label": "list_production_tasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L359"}, {"id": "crud_production_task_get_production_task_detail", "label": "get_production_task_detail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L479"}, {"id": "crud_production_task_update_production_task", "label": "update_production_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L569"}, {"id": "crud_production_task_update_task_status", "label": "update_task_status()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L594"}, {"id": "crud_production_task_add_task_step", "label": "add_task_step()", "file_type": Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_py", "label": "reagent.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L1"}, {"id": "crud_reagent_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L16"}, {"id": "crud_reagent_norm_status", "label": "_norm_status()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L22"}, {"id": "crud_reagent_is_enabled_status", "label": "_is_enabled_status()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L38"}, {"id": "crud_reagent_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L42"}, {"id": "crud_reagent_list_reagents", "label": "list_reagents()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L62"}, {"id": "crud_reagent_get_reagent", "label": "get_reagent()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L102"}, {"id": "crud_reagent_reagent_code_exists", "label": "reagent_code_exists()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L110"}, {"id": "crud_reagent_create_reagent", "label": "create_reagent()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L119"}, {"id": "crud_reagent_update_reagent", "label": "update_reagent()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L162"}, {"id": "crud_reagent_soft_delete_reagent", "label": "soft_delete_reagent()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L208"}, {"id": "crud_reagent_stock_in", "label": "stock_in()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L220"}, {"id": "crud_reagent_batch_stock_in", "label": "batch_stock_in()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L276"}, {"id": "crud_reagent_stock_out", "label": "stock_out()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L351"}, {"id": "crud_reagent_batch_stock_out", "label": "batch_stock_out()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L422"}, {"id": "crud_reagent_total_pages", "label": "total_pages()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L510"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_py", "target": "math", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_py", "target": "decimal", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L6", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L7", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L9", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_py", "target": "sqlalchemy_orm", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location": "L10", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_py", "target": "app_core_utils", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py", "source_location"Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_stock_log_py", "label": "reagent_stock_log.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L1"}, {"id": "crud_reagent_stock_log_user_nick_name_map", "label": "_user_nick_name_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L16"}, {"id": "crud_reagent_stock_log_parse_receiver_purpose_from_remark", "label": "_parse_receiver_purpose_from_remark()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L24"}, {"id": "crud_reagent_stock_log_resolve_receiver_purpose", "label": "_resolve_receiver_purpose()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L35"}, {"id": "crud_reagent_stock_log_display_remark", "label": "_display_remark()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L45"}, {"id": "crud_reagent_stock_log_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L60"}, {"id": "crud_reagent_stock_log_list_stock_logs", "label": "list_stock_logs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L89"}, {"id": "crud_reagent_stock_log_revert_step_stock_changes", "label": "revert_step_stock_changes()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L157"}, {"id": "crud_reagent_stock_log_deduct_for_step", "label": "deduct_for_step()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L204"}, {"id": "crud_reagent_stock_log_rationale_1", "label": "\u8bd5\u5242\u53d8\u52a8\u8bb0\u5f55 CRUD\uff08biz_reagent_stock_log\uff09", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L1"}, {"id": "crud_reagent_stock_log_rationale_163", "label": "\u64a4\u9500\u6b65\u9aa4\u6b64\u524d step_save \u6263\u51cf\uff0c\u4fbf\u4e8e\u91cd\u65b0\u586b\u62a5\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L163"}, {"id": "crud_reagent_stock_log_rationale_214", "label": "\u6263\u51cf\u8bd5\u5242\u5e93\u5b58\u5e76\u751f\u6210\u53d8\u52a8\u8bb0\u5f55\u3002\u8c03\u7528\u65b9\u63a7\u5236\u4e8b\u52a1\uff0c\u672c\u51fd\u6570\u4e0d commit\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L214"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_stock_log_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_stock_log_py", "target": "decimal", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_stock_log_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L6", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_stock_log_py", "target": "fastapi", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L8", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_stock_log_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L9", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_stock_log_py", "target": "sqlalchemy_orm", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py", "source_location": "L10", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_reagent_stock_log_py", "target": "app_core_utils", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxwLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_production_py", "label": "production.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L1"}, {"id": "api_production_get_tenant_no", "label": "_get_tenant_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L56"}, {"id": "api_production_consumablecreatebody", "label": "ConsumableCreateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L69"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_production_consumableupdatebody", "label": "ConsumableUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L81"}, {"id": "api_production_list_consumables", "label": "list_consumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L94"}, {"id": "api_production_list_all_consumables", "label": "list_all_consumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L108"}, {"id": "api_production_create_consumable", "label": "create_consumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L118"}, {"id": "api_production_update_consumable", "label": "update_consumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L144"}, {"id": "api_production_delete_consumable", "label": "delete_consumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L171"}, {"id": "api_production_stockinbody", "label": "StockInBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L183"}, {"id": "api_production_stockoutbody", "label": "StockOutBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L189"}, {"id": "api_production_batchstockinitem", "label": "BatchStockInItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L197"}, {"id": "api_production_batchstockinbody", "label": "BatchStockInBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L204"}, {"id": "api_production_batchstockoutitem", "label": "BatchStockOutItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L210"}, {"id": "api_production_batchstockoutbody", "label": "BatchStockOutBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L216"}, {"id": "api_production_consumable_stock_in", "label": "consumable_stock_in()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L225"}, {"id": "api_production_consumable_stock_out", "label": "consumable_stock_out()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L247"}, {"id": "api_production_consumable_batch_stock_in", "label": "consumable_batch_stock_in()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L271"}, {"id": "api_production_consumable_batch_stock_out", "label": "consumable_batch_stock_out()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L289"}, {"id": "api_production_list_consumable_stock_logs", "label": "list_consumable_stock_logs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L308"}, {"id": "api_production_list_all_consumable_stock_logs", "label": "list_all_consumable_stock_logs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L327"}, {"id": "api_production_reagentcreatebody", "label": "ReagentCreateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L353"}, {"id": "api_production_reagentupdatebody", "label": "ReagentUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L365"}, {"id": "api_production_list_reagents", "label": "list_reagents()", "file_type": "code", "source_filLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_models_models_py", "label": "models.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L1"}, {"id": "models_models_userrole", "label": "UserRole", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L10"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "models_models_sysuser", "label": "SysUser", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L22"}, {"id": "base", "label": "Base", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "models_models_sysrole", "label": "SysRole", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L48"}, {"id": "models_models_sysuserrole", "label": "SysUserRole", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L68"}, {"id": "models_models_sysrolemenu", "label": "SysRoleMenu", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L87"}, {"id": "models_models_sysroledatascopedetail", "label": "SysRoleDataScopeDetail", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L106"}, {"id": "models_models_sysmenu", "label": "SysMenu", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L126"}, {"id": "models_models_sysdept", "label": "SysDept", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L152"}, {"id": "models_models_systenant", "label": "SysTenant", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L175"}, {"id": "models_models_syssite", "label": "SysSite", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L195"}, {"id": "models_models_syspost", "label": "SysPost", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L220"}, {"id": "models_models_sysuserpost", "label": "SysUserPost", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L240"}, {"id": "models_models_bizitemunit", "label": "BizItemUnit", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L259"}, {"id": "models_models_bizexpresscompany", "label": "BizExpressCompany", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L278"}, {"id": "models_models_bizcustomer", "label": "BizCustomer", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L297"}, {"id": "models_models_bizcellsampletype", "label": "BizCellSampleType", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L320"}, {"id": "models_models_bizcollectionregion", "label": "BizCollectionRegion", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L341"}, {"id": "models_models_bizcollectionhospital", "label": "BizCollectionHospital", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L359"}, {"id": "models_models_bizcollectionprotocolno", "label": "BizCollectionProtocolNo", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L378"}, {"id": "models_models_bizsamplecode", "label": "BizSampleCode", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L400"}, {"id": "models_models_sysdicttype", "label": "SysDictType", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L428"}, {"id": "models_models_sysethnic", "label": "SysEthnic", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L447"}, {"id": "models_models_sysdictdata", "label": "SysDictData", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L466"}, {"id": "models_models_sysapirequestlog", "label": "SysApiRequestLog", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location"Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_py", "label": "consumable.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L1"}, {"id": "crud_consumable_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L16"}, {"id": "crud_consumable_norm_status", "label": "_norm_status()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L22"}, {"id": "crud_consumable_is_enabled_status", "label": "_is_enabled_status()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L38"}, {"id": "crud_consumable_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L42"}, {"id": "crud_consumable_list_consumables", "label": "list_consumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L62"}, {"id": "crud_consumable_get_consumable", "label": "get_consumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L102"}, {"id": "crud_consumable_consumable_code_exists", "label": "consumable_code_exists()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L110"}, {"id": "crud_consumable_create_consumable", "label": "create_consumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L119"}, {"id": "crud_consumable_update_consumable", "label": "update_consumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L162"}, {"id": "crud_consumable_soft_delete_consumable", "label": "soft_delete_consumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L208"}, {"id": "crud_consumable_build_manual_out_remark", "label": "_build_manual_out_remark()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L220"}, {"id": "crud_consumable_stock_in", "label": "stock_in()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L240"}, {"id": "crud_consumable_batch_stock_in", "label": "batch_stock_in()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L296"}, {"id": "crud_consumable_stock_out", "label": "stock_out()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L371"}, {"id": "crud_consumable_batch_stock_out", "label": "batch_stock_out()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L442"}, {"id": "crud_consumable_total_pages", "label": "total_pages()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L530"}, {"id": "crud_consumable_rationale_1", "label": "\u8017\u6750 CRUD\uff08biz_consumable\uff09", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_py", "target": "math", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_py", "target": "decimal", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L6", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py", "source_location": "L7", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_consumable_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00coLine truncated
|
||||
@@ -2556,6 +2556,7 @@ class BizConsumableStockLog(Base):
|
||||
stock_after = Column(Numeric(18, 4), nullable=False, comment="变动后库存")
|
||||
source_type = Column(String(16), nullable=False, comment="来源:manual_in/manual_out/step_save")
|
||||
step_id = Column(String(64), nullable=True, comment="生产任务步骤ID")
|
||||
step_name = Column(String(200), nullable=True, comment="步骤名称快照")
|
||||
task_id = Column(String(64), nullable=True, comment="生产任务ID")
|
||||
task_no = Column(String(32), nullable=True, comment="生产任务编号快照")
|
||||
receiver = Column(String(64), nullable=True, comment="领用人")
|
||||
@@ -2585,6 +2586,7 @@ class BizReagentStockLog(Base):
|
||||
stock_after = Column(Numeric(18, 4), nullable=False, comment="变动后库存")
|
||||
source_type = Column(String(16), nullable=False, comment="来源:manual_in/manual_out/step_save")
|
||||
step_id = Column(String(64), nullable=True, comment="生产任务步骤ID")
|
||||
step_name = Column(String(200), nullable=True, comment="步骤名称快照")
|
||||
task_id = Column(String(64), nullable=True, comment="生产任务ID")
|
||||
task_no = Column(String(32), nullable=True, comment="生产任务编号快照")
|
||||
receiver = Column(String(64), nullable=True, comment="领用人")
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
+8431
-4074
File diff suppressed because it is too large.
Load diff
@@ -1,12 +1,12 @@
|
||||
# Graph Report - app (2026-05-23)
|
||||
|
||||
## Corpus Check
|
||||
- 140 files · ~125,737 words
|
||||
- 142 files · ~130,208 words
|
||||
- Verdict: corpus is large enough that graph structure adds value.
|
||||
|
||||
## Summary
|
||||
- 2481 nodes · 9810 edges · 52 communities detected
|
||||
- Extraction: 42% EXTRACTED · 58% INFERRED · 0% AMBIGUOUS · INFERRED: 5728 edges (avg confidence: 0.63)
|
||||
- 2542 nodes · 10216 edges · 51 communities detected
|
||||
- Extraction: 41% EXTRACTED · 59% INFERRED · 0% AMBIGUOUS · INFERRED: 6029 edges (avg confidence: 0.63)
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Community Hubs (Navigation)
|
||||
@@ -55,25 +55,24 @@
|
||||
- [[_COMMUNITY_Community 42|Community 42]]
|
||||
- [[_COMMUNITY_Community 43|Community 43]]
|
||||
- [[_COMMUNITY_Community 44|Community 44]]
|
||||
- [[_COMMUNITY_Community 45|Community 45]]
|
||||
- [[_COMMUNITY_Community 47|Community 47]]
|
||||
- [[_COMMUNITY_Community 48|Community 48]]
|
||||
- [[_COMMUNITY_Community 49|Community 49]]
|
||||
- [[_COMMUNITY_Community 50|Community 50]]
|
||||
- [[_COMMUNITY_Community 51|Community 51]]
|
||||
- [[_COMMUNITY_Community 52|Community 52]]
|
||||
- [[_COMMUNITY_Community 53|Community 53]]
|
||||
|
||||
## God Nodes (most connected - your core abstractions)
|
||||
1. `success_response()` - 391 edges
|
||||
2. `error_response()` - 314 edges
|
||||
3. `SysUser` - 218 edges
|
||||
4. `BizQcMaterialUsage` - 201 edges
|
||||
5. `BizMaterialStockLog` - 197 edges
|
||||
6. `BizQcTaskResult` - 197 edges
|
||||
7. `BizQcMaterial` - 197 edges
|
||||
8. `BizMaterial` - 194 edges
|
||||
9. `BizQcItemParam` - 192 edges
|
||||
10. `generate_uuid()` - 136 edges
|
||||
1. `success_response()` - 403 edges
|
||||
2. `error_response()` - 322 edges
|
||||
3. `SysUser` - 230 edges
|
||||
4. `BizQcMaterialUsage` - 205 edges
|
||||
5. `BizMaterialStockLog` - 201 edges
|
||||
6. `BizQcTaskResult` - 201 edges
|
||||
7. `BizQcMaterial` - 201 edges
|
||||
8. `BizMaterial` - 198 edges
|
||||
9. `BizQcItemParam` - 196 edges
|
||||
10. `generate_uuid()` - 146 edges
|
||||
|
||||
## Surprising Connections (you probably didn't know these)
|
||||
- `统一记录 API 请求/响应出入参的中间件` --uses--> `SysApiRequestLog` [INFERRED]
|
||||
@@ -90,48 +89,48 @@
|
||||
## Communities
|
||||
|
||||
### Community 0 - "Community 0"
|
||||
Cohesion: 0.01
|
||||
Nodes (427): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+419 more)
|
||||
Cohesion: 0.02
|
||||
Nodes (429): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+421 more)
|
||||
|
||||
### Community 1 - "Community 1"
|
||||
Cohesion: 0.02
|
||||
Nodes (416): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+408 more)
|
||||
Nodes (402): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+394 more)
|
||||
|
||||
### Community 2 - "Community 2"
|
||||
Cohesion: 0.06
|
||||
Nodes (272): AuditCreateBody, BatchDetailIdsBody, BatchRefundFinanceSubmitBody, FinanceConfirmBody, FullmoonTodoInsuranceBody, ProtocolCreateBody, ProtocolUpdateBody, 细胞存储 — 采集协议单 / 审核 / 财务确认 / 分期预警 API (+264 more)
|
||||
Cohesion: 0.01
|
||||
Nodes (258): apply_data_scope(), _get_child_dept_ids(), get_user_dept_id(), _resolve_user_role_scopes(), generate_uuid(), batch_stock_in(), batch_stock_out(), consumable_code_exists() (+250 more)
|
||||
|
||||
### Community 3 - "Community 3"
|
||||
Cohesion: 0.02
|
||||
Nodes (190): generate_uuid(), appointment_no_exists(), create_exhibition_appointment(), _format_visit_date(), _generate_appointment_no(), get_exhibition_appointment(), list_exhibition_appointments(), 展览预约 CRUD(biz_exhibition_appointment) (+182 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (221): InsuranceCompanyCreateBody, InsuranceCompanyInvoiceCreateBody, InsuranceCompanyInvoiceUpdateBody, InsuranceCompanyUpdateBody, InsuranceProjectPriceCreateBody, InsuranceProjectPriceUpdateBody, 保险公司及险种价格管理 API(保险公司 + 开票信息 + 险种价格), Base (+213 more)
|
||||
|
||||
### Community 4 - "Community 4"
|
||||
Cohesion: 0.03
|
||||
Nodes (147): list_collection_regions(), _persist_protocol_sub_resources(), list_ethnics_for_select(), InsuranceCompanyCreateBody, InsuranceCompanyInvoiceCreateBody, InsuranceCompanyInvoiceUpdateBody, InsuranceCompanyUpdateBody, InsuranceProjectPriceCreateBody (+139 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (164): CellSampleTypeCreateBody, CellSampleTypeUpdateBody, CollectionRegionCreateBody, CollectionRegionUpdateBody, CustomerCreateBody, CustomerUpdateBody, HospitalCreateBody, HospitalUpdateBody (+156 more)
|
||||
|
||||
### Community 5 - "Community 5"
|
||||
Cohesion: 0.03
|
||||
Nodes (99): list_roles_for_select(), _avatar_url_field(), _build_user_info_payload(), _jwt_user_payload(), logout(), 公共接口(Web 登录、刷新 Token、登出;用户模型对齐 docs/sql/zkxw.sql 基线), 登出:吊销 Redis 会话(若已配置 REDIS_HOST)。, 与 web-admin `userInfo` 字段约定一致。 (+91 more)
|
||||
Nodes (100): list_roles_for_select(), _avatar_url_field(), _build_user_info_payload(), get_web_auth_menu_codes(), _jwt_user_payload(), logout(), 公共接口(Web 登录、刷新 Token、登出;用户模型对齐 docs/sql/zkxw.sql 基线), 登出:吊销 Redis 会话(若已配置 REDIS_HOST)。 (+92 more)
|
||||
|
||||
### Community 6 - "Community 6"
|
||||
Cohesion: 0.05
|
||||
Nodes (96): _accept_conclusion_label(), _attach_reception_detail(), complete_production_work_order(), create_production_work_order_from_reception(), _enrich_wo_items(), _fmt_dt(), _generate_work_order_no(), get_production_work_order() (+88 more)
|
||||
Cohesion: 0.04
|
||||
Nodes (104): create_collection_protocol(), delete_collection_protocol(), _ensure_customer_for_mother(), get_collection_protocol_detail(), _get_current_user_id(), _get_tenant_no(), list_collection_protocol_audits(), list_collection_protocols() (+96 more)
|
||||
|
||||
### Community 7 - "Community 7"
|
||||
Cohesion: 0.05
|
||||
Nodes (26): BusinessException, InvalidStatusTransitionException, log_delivery_operation(), log_operation(), log_order_operation(), log_settlement_operation(), log_user_operation(), OrderLockedException (+18 more)
|
||||
Cohesion: 0.04
|
||||
Nodes (99): _format_attachment_file_size(), urls_to_attachment_list(), _accept_conclusion_label(), _attach_reception_detail(), complete_production_work_order(), create_production_work_order_from_reception(), _enrich_wo_items(), _fmt_dt() (+91 more)
|
||||
|
||||
### Community 8 - "Community 8"
|
||||
Cohesion: 0.06
|
||||
Nodes (54): get_designer_data(), ProcessDefCreateBody, ProcessDefUpdateBody, PublishVersionBody, 审批意见:前端传 commentText,兼容 comment。, StartInstanceBody, TaskActionBody, list_results_by_task() (+46 more)
|
||||
Nodes (60): _business_type_label(), _enrich_task_list(), get_business_all_tasks(), _get_business_form_fields(), get_designer_data(), get_instance_detail(), list_completed_tasks(), list_my_instances() (+52 more)
|
||||
|
||||
### Community 9 - "Community 9"
|
||||
Cohesion: 0.27
|
||||
Nodes (58): ConsumableCreateBody, ConsumablePackCreateBody, ConsumablePackUpdateBody, ConsumableUpdateBody, OutputTypeCreateBody, OutputTypeUpdateBody, PackItemInput, ProcessCategoryCreateBody (+50 more)
|
||||
Cohesion: 0.07
|
||||
Nodes (67): AccessLogCreateBody, AccessLogUpdateBody, CleanRoomCreateBody, CleanRoomUpdateBody, ExhibitionAppointmentCreateBody, ExhibitionAppointmentUpdateBody, OccupancyCreateBody, 运营支撑 API(洁净室、进出记录、仓储设施、储位、展厅预约) (+59 more)
|
||||
|
||||
### Community 10 - "Community 10"
|
||||
Cohesion: 0.09
|
||||
Nodes (58): batch_delete_research_donations(), change_donation_status(), convert_from_storage(), convert_to_storage(), create_research_donation(), delete_research_donation(), _get_current_user_id(), get_research_donation_detail() (+50 more)
|
||||
Cohesion: 0.05
|
||||
Nodes (26): BusinessException, InvalidStatusTransitionException, log_delivery_operation(), log_operation(), log_order_operation(), log_settlement_operation(), log_user_operation(), OrderLockedException (+18 more)
|
||||
|
||||
### Community 11 - "Community 11"
|
||||
Cohesion: 0.06
|
||||
@@ -142,24 +141,24 @@ Cohesion: 0.12
|
||||
Nodes (11): get_wechat_pay_client(), get_wechat_pay_v2(), 微信支付工具模块 支持微信支付 V3 API 文档参考: https://pay.weixin.qq.com/docs/v3/apis/index.ht, 统一下单接口 (V3) Args: out_trade_no: 商户订单号 total, 申请退款 Args: out_trade_no: 商户订单号 total_amount, 小程序调起支付的二次签名参数(与公众号 JSAPI 规则一致), 统一下单 (V2 API) Args: out_trade_no: 商户订单号 tot, 生成签名 V3 (SHA256 with RSA) (+3 more)
|
||||
|
||||
### Community 13 - "Community 13"
|
||||
Cohesion: 0.11
|
||||
Nodes (28): get_next_cell_product_code(), _build_facility_path_label(), build_split_product_codes(), create_cell_product(), create_cell_products_batch(), create_cell_products_by_quantity(), delete_cell_product(), _enrich_product_dicts() (+20 more)
|
||||
|
||||
### Community 14 - "Community 14"
|
||||
Cohesion: 0.21
|
||||
Nodes (19): _consumable_row_to_dict(), create_process(), _create_sub_consumable(), _create_sub_data_collection(), _create_sub_output(), _create_sub_reagent(), _data_collection_row_to_dict(), get_process() (+11 more)
|
||||
|
||||
### Community 15 - "Community 15"
|
||||
Cohesion: 0.18
|
||||
Nodes (18): company_code_exists(), create_company(), get_company(), list_companies(), list_company_options(), _row_to_dict(), soft_delete_company(), update_company() (+10 more)
|
||||
|
||||
### Community 16 - "Community 16"
|
||||
### Community 14 - "Community 14"
|
||||
Cohesion: 0.2
|
||||
Nodes (16): get_next_cell_product_code(), _build_facility_path_label(), build_split_product_codes(), create_cell_products_batch(), create_cell_products_by_quantity(), delete_cell_product(), _enrich_product_dicts(), get_cell_product() (+8 more)
|
||||
|
||||
### Community 15 - "Community 15"
|
||||
Cohesion: 0.17
|
||||
Nodes (18): create_storage_slot(), update_storage_slot(), batch_create_slots(), collect_descendant_ids(), create_facility(), create_slot(), get_children(), get_facility() (+10 more)
|
||||
Nodes (15): Config, QuotationBase, QuotationCreate, QuotationDetailResponse, QuotationItemBase, QuotationItemCreate, QuotationItemResponse, QuotationItemUpdate (+7 more)
|
||||
|
||||
### Community 16 - "Community 16"
|
||||
Cohesion: 0.25
|
||||
Nodes (13): code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), list_materials(), _norm_status(), options_list() (+5 more)
|
||||
|
||||
### Community 17 - "Community 17"
|
||||
Cohesion: 0.2
|
||||
Nodes (14): deduct_for_task(), _display_remark(), list_usages(), list_usages_by_task(), _parse_receiver_purpose_from_remark(), 查询质检任务关联的物料使用记录(task_complete)。, 撤销任务此前 task_complete 扣减,便于重新填报物料使用。, 兼容旧数据:领用人/用途曾拼接在 remark 中。 (+6 more)
|
||||
Cohesion: 0.21
|
||||
Nodes (13): create_collection_region(), create_hospital(), get_collection_region(), get_hospital(), _hospital_names_by_region_ids(), _hospital_to_dict(), list_collection_regions(), list_hospitals() (+5 more)
|
||||
|
||||
### Community 18 - "Community 18"
|
||||
Cohesion: 0.25
|
||||
@@ -170,20 +169,20 @@ Cohesion: 0.26
|
||||
Nodes (12): batch_issue_sample_codes(), batch_revoke_sample_codes(), create_sample_code(), get_sample_code(), list_sample_codes(), _parse_issued_time(), 样本编码池 CRUD(biz_sample_code), _resolve_issued_user_display_name() (+4 more)
|
||||
|
||||
### Community 20 - "Community 20"
|
||||
Cohesion: 0.22
|
||||
Nodes (12): create_access_log(), create_clean_room(), get_access_log(), get_clean_room(), list_access_logs(), list_clean_rooms(), room_code_exists(), _row_to_dict() (+4 more)
|
||||
|
||||
### Community 21 - "Community 21"
|
||||
Cohesion: 0.24
|
||||
Nodes (9): 微信消息通知服务 支持微信小程序模板消息推送 使用方式: from app.core.wechat_message import Wech, 发送模板消息 Args: openid: 用户openid templ, send_delivery_notice(), send_delivery_warning(), send_order_status(), send_payment_success(), send_refund_result(), send_urge_notification() (+1 more)
|
||||
|
||||
### Community 21 - "Community 21"
|
||||
Cohesion: 0.22
|
||||
Nodes (12): Config, InquiryBase, InquiryCreate, InquiryDetailResponse, InquiryItemBase, InquiryItemCreate, InquiryItemResponse, InquiryListResponse (+4 more)
|
||||
|
||||
### Community 22 - "Community 22"
|
||||
Cohesion: 0.23
|
||||
Nodes (12): Config, ProductBase, ProductCategoryBase, ProductCategoryCreate, ProductCategoryResponse, ProductCreate, ProductResponse, ProductUnitBase (+4 more)
|
||||
|
||||
### Community 23 - "Community 23"
|
||||
Cohesion: 0.3
|
||||
Nodes (10): create_consumable_pack(), get_consumable_pack(), get_pack_detail(), _item_row_to_dict(), list_all_packs(), list_consumable_packs(), pack_code_exists(), _row_to_dict() (+2 more)
|
||||
Cohesion: 0.31
|
||||
Nodes (12): _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), list_materials(), options_list(), _row_to_dict() (+4 more)
|
||||
|
||||
### Community 24 - "Community 24"
|
||||
Cohesion: 0.27
|
||||
@@ -194,8 +193,8 @@ Cohesion: 0.29
|
||||
Nodes (9): _build_tree(), _cascade_soft_delete(), create_menu(), get_menu(), list_menus(), list_menus_tree(), _row_to_dict(), soft_delete_menu() (+1 more)
|
||||
|
||||
### Community 26 - "Community 26"
|
||||
Cohesion: 0.31
|
||||
Nodes (8): consumable_code_exists(), create_consumable(), get_consumable(), list_consumables(), 耗材 CRUD(biz_consumable), _row_to_dict(), soft_delete_consumable(), update_consumable()
|
||||
Cohesion: 0.36
|
||||
Nodes (9): deduct_for_task(), _display_remark(), list_usages(), list_usages_by_task(), _parse_receiver_purpose_from_remark(), _resolve_receiver_purpose(), revert_task_material_usages(), _row_to_dict() (+1 more)
|
||||
|
||||
### Community 27 - "Community 27"
|
||||
Cohesion: 0.31
|
||||
@@ -219,124 +218,120 @@ Nodes (8): create_item_unit(), get_item_unit(), list_item_units(), 物品单位
|
||||
|
||||
### Community 32 - "Community 32"
|
||||
Cohesion: 0.31
|
||||
Nodes (8): create_customer(), get_customer(), id_card_taken(), list_customers(), 客户 CRUD(biz_customer), _row_to_dict(), soft_delete_customer(), update_customer()
|
||||
Nodes (8): create_cell_sample_type(), get_cell_sample_type(), list_cell_sample_types(), 细胞样本类型 CRUD(biz_cell_sample_type), _row_to_dict(), soft_delete_cell_sample_type(), type_code_exists(), update_cell_sample_type()
|
||||
|
||||
### Community 33 - "Community 33"
|
||||
Cohesion: 0.31
|
||||
Nodes (8): create_cell_sample_type(), get_cell_sample_type(), list_cell_sample_types(), 细胞样本类型 CRUD(biz_cell_sample_type), _row_to_dict(), soft_delete_cell_sample_type(), type_code_exists(), update_cell_sample_type()
|
||||
|
||||
### Community 34 - "Community 34"
|
||||
Cohesion: 0.31
|
||||
Nodes (8): create_output_type(), get_output_type(), list_output_types(), 工艺产出物类型 CRUD(biz_output_type), _row_to_dict(), soft_delete_output_type(), type_code_exists(), update_output_type()
|
||||
|
||||
### Community 35 - "Community 35"
|
||||
Cohesion: 0.36
|
||||
Nodes (7): create_post(), get_post(), list_posts(), post_code_exists(), _row_to_dict(), soft_delete_post(), update_post()
|
||||
|
||||
### Community 36 - "Community 36"
|
||||
### Community 34 - "Community 34"
|
||||
Cohesion: 0.36
|
||||
Nodes (7): create_tenant(), get_tenant(), list_tenants(), _row_to_dict(), soft_delete_tenant(), tenant_no_exists(), update_tenant()
|
||||
|
||||
### Community 37 - "Community 37"
|
||||
Cohesion: 0.36
|
||||
Nodes (7): create_reagent(), get_reagent(), list_reagents(), reagent_code_exists(), _row_to_dict(), soft_delete_reagent(), update_reagent()
|
||||
### Community 35 - "Community 35"
|
||||
Cohesion: 0.39
|
||||
Nodes (8): create_lab_item(), get_lab_item(), item_code_exists(), list_active_lab_items(), list_lab_items(), _row_to_dict(), soft_delete_lab_item(), update_lab_item()
|
||||
|
||||
### Community 38 - "Community 38"
|
||||
Cohesion: 0.36
|
||||
Nodes (7): create_site(), get_site(), list_sites(), _row_to_dict(), site_code_exists(), soft_delete_site(), update_site()
|
||||
|
||||
### Community 39 - "Community 39"
|
||||
### Community 36 - "Community 36"
|
||||
Cohesion: 0.29
|
||||
Nodes (2): BaseModel, SoftDeleteModel
|
||||
|
||||
### Community 40 - "Community 40"
|
||||
### Community 37 - "Community 37"
|
||||
Cohesion: 0.43
|
||||
Nodes (7): _display_remark(), list_stock_logs(), _parse_receiver_purpose_from_remark(), _resolve_receiver_purpose(), revert_step_stock_changes(), _row_to_dict(), _user_nick_name_map()
|
||||
|
||||
### Community 38 - "Community 38"
|
||||
Cohesion: 0.38
|
||||
Nodes (6): derive_legacy_status_from_three(), derive_three_status_from_legacy(), 阶段A兼容:从旧 status 推导三字段。 约束:旧 status 本身混合了支付/配送/订单生命周期,因此只能尽力推断; 若业务侧已有更精确, 阶段A兼容:从三字段反推旧 status(用于旧前端/旧筛选参数兼容)。, ThreeStatus, _to_decimal()
|
||||
|
||||
### Community 41 - "Community 41"
|
||||
### Community 39 - "Community 39"
|
||||
Cohesion: 0.4
|
||||
Nodes (4): list_ethnics_for_select(), list_ethnics(), 民族码表 CRUD(全局 sys_ethnic), _row_to_dict()
|
||||
|
||||
### Community 40 - "Community 40"
|
||||
Cohesion: 0.5
|
||||
Nodes (3): BaseSettings, Config, Settings
|
||||
|
||||
### Community 42 - "Community 42"
|
||||
### Community 41 - "Community 41"
|
||||
Cohesion: 0.5
|
||||
Nodes (2): _auto_fill_create_dept_id(), ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID
|
||||
|
||||
### Community 43 - "Community 43"
|
||||
### Community 42 - "Community 42"
|
||||
Cohesion: 0.67
|
||||
Nodes (2): get_menu_list(), 运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,供后端菜单模式联调)
|
||||
|
||||
### Community 44 - "Community 44"
|
||||
### Community 43 - "Community 43"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传
|
||||
|
||||
### Community 45 - "Community 45"
|
||||
### Community 44 - "Community 44"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)
|
||||
|
||||
### Community 48 - "Community 48"
|
||||
### Community 47 - "Community 47"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送订单状态通知 Args: openid: 用户openid ord
|
||||
|
||||
### Community 49 - "Community 49"
|
||||
### Community 48 - "Community 48"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送支付成功通知 Args: openid: 用户openid ord
|
||||
|
||||
### Community 50 - "Community 50"
|
||||
### Community 49 - "Community 49"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送配送通知 Args: openid: 配送员openid task
|
||||
|
||||
### Community 51 - "Community 51"
|
||||
### Community 50 - "Community 50"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送配送时效预警 Args: openid: 配送员openid ta
|
||||
|
||||
### Community 52 - "Community 52"
|
||||
### Community 51 - "Community 51"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送退款结果通知 Args: openid: 用户openid ord
|
||||
|
||||
### Community 53 - "Community 53"
|
||||
### Community 52 - "Community 52"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送催单通知给配送员 Args: deliver_openid: 配送员openid
|
||||
|
||||
## Knowledge Gaps
|
||||
- **90 isolated node(s):** `刷新会话 TTL(refreshToken 续期;已登录用户每次 API 校验通过后滑动续期)`, `写入 refreshToken(用于 one-time 使用/吊销)`, `根据 token 获取当前用户(包含 Redis 会话校验;会话滑动续期)`, `登录凭据 RSA 解密(与前端 JSEncrypt PKCS#1 v1.5 兼容)。`, `Base64 密文 -> JSON 对象(须含 username、password、ts 毫秒时间戳)。` (+85 more)
|
||||
These have ≤1 connection - possible missing edges or undocumented components.
|
||||
- **Thin community `Community 39`** (8 nodes): `BaseModel`, `.to_dict()`, `get_active()`, `base.py`, `SoftDeleteModel`, `.restore()`, `.soft_delete()`, `__tablename__()`
|
||||
- **Thin community `Community 36`** (8 nodes): `BaseModel`, `.to_dict()`, `get_active()`, `base.py`, `SoftDeleteModel`, `.restore()`, `.soft_delete()`, `__tablename__()`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 42`** (4 nodes): `_auto_fill_create_dept_id()`, `get_db()`, `database.py`, `ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID`
|
||||
- **Thin community `Community 41`** (4 nodes): `_auto_fill_create_dept_id()`, `get_db()`, `database.py`, `ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 43`** (3 nodes): `get_menu_list()`, `menu.py`, `运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,供后端菜单模式联调)`
|
||||
- **Thin community `Community 42`** (3 nodes): `get_menu_list()`, `menu.py`, `运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,供后端菜单模式联调)`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 44`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
|
||||
- **Thin community `Community 43`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 45`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
|
||||
- **Thin community `Community 44`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 48`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord`
|
||||
- **Thin community `Community 47`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 49`** (1 nodes): `发送支付成功通知 Args: openid: 用户openid ord`
|
||||
- **Thin community `Community 48`** (1 nodes): `发送支付成功通知 Args: openid: 用户openid ord`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 50`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task`
|
||||
- **Thin community `Community 49`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 51`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta`
|
||||
- **Thin community `Community 50`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 52`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord`
|
||||
- **Thin community `Community 51`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 53`** (1 nodes): `发送催单通知给配送员 Args: deliver_openid: 配送员openid`
|
||||
- **Thin community `Community 52`** (1 nodes): `发送催单通知给配送员 Args: deliver_openid: 配送员openid`
|
||||
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 `generate_uuid()` connect `Community 3` to `Community 0`, `Community 1`, `Community 2`, `Community 4`, `Community 5`, `Community 6`, `Community 8`, `Community 10`, `Community 11`, `Community 13`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 18`, `Community 19`, `Community 20`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 33`, `Community 34`, `Community 35`, `Community 36`, `Community 37`, `Community 38`?**
|
||||
_High betweenness centrality (0.104) - this node is a cross-community bridge._
|
||||
- **Why does `SysUser` connect `Community 0` to `Community 2`, `Community 4`, `Community 5`, `Community 8`, `Community 9`, `Community 10`, `Community 17`, `Community 18`, `Community 19`?**
|
||||
_High betweenness centrality (0.086) - this node is a cross-community bridge._
|
||||
- **Why does `success_response()` connect `Community 1` to `Community 0`, `Community 4`, `Community 5`, `Community 8`, `Community 10`, `Community 43`, `Community 13`, `Community 16`?**
|
||||
_High betweenness centrality (0.064) - this node is a cross-community bridge._
|
||||
- **Are the 390 inferred relationships involving `success_response()` (e.g. with `list_storage_release_reviews()` and `get_storage_release_review_detail()`) actually correct?**
|
||||
_`success_response()` has 390 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 363 inferred relationships involving `str` (e.g. with `extract_login_credentials()` and `._make_request()`) actually correct?**
|
||||
_`str` has 363 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 313 inferred relationships involving `error_response()` (e.g. with `_json_error_response()` and `list_storage_release_reviews()`) actually correct?**
|
||||
_`error_response()` has 313 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 216 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤) data_scope 值: 1 = 全部数据 2 = 本部门数据 3` and `从 SysUser 读取用户的 dept_id。`) actually correct?**
|
||||
_`SysUser` has 216 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Why does `generate_uuid()` connect `Community 2` to `Community 0`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 11`, `Community 13`, `Community 14`, `Community 16`, `Community 17`, `Community 18`, `Community 19`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 33`, `Community 34`, `Community 35`?**
|
||||
_High betweenness centrality (0.118) - this node is a cross-community bridge._
|
||||
- **Why does `SysUser` connect `Community 1` to `Community 3`, `Community 4`, `Community 5`, `Community 8`, `Community 9`, `Community 18`, `Community 19`?**
|
||||
_High betweenness centrality (0.098) - this node is a cross-community bridge._
|
||||
- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 5`, `Community 6`, `Community 39`, `Community 8`, `Community 42`, `Community 14`?**
|
||||
_High betweenness centrality (0.074) - this node is a cross-community bridge._
|
||||
- **Are the 402 inferred relationships involving `success_response()` (e.g. with `list_storage_release_reviews()` and `get_storage_release_review_detail()`) actually correct?**
|
||||
_`success_response()` has 402 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 381 inferred relationships involving `str` (e.g. with `extract_login_credentials()` and `._make_request()`) actually correct?**
|
||||
_`str` has 381 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 321 inferred relationships involving `error_response()` (e.g. with `_json_error_response()` and `list_storage_release_reviews()`) actually correct?**
|
||||
_`error_response()` has 321 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 228 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤) data_scope 值: 1 = 全部数据 2 = 本部门数据 3` and `从 SysUser 读取用户的 dept_id。`) actually correct?**
|
||||
_`SysUser` has 228 INFERRED edges - model-reasoned connections that need verification._
|
||||
@@ -57,12 +57,12 @@
|
||||
</div>
|
||||
<div id="legend"></div>
|
||||
</div>
|
||||
<div id="stats">2481 nodes · 9810 edges · 58 communities</div>
|
||||
<div id="stats">2542 nodes · 10216 edges · 57 communities</div>
|
||||
</div>
|
||||
<script>
|
||||
const RAW_NODES = [{"id": "init_py", "label": "__init__.py", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 46, "community_name": "Community 46", "source_file": "__init__.py", "file_type": "code", "degree": 0}, {"id": "main_py", "label": "main.py", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "main.py", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_lifespan", "label": "lifespan()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_mask_secret", "label": "_mask_secret()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "_mask_secret()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_root", "label": "root()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "root()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_health_check", "label": "health_check()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "health_check()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "tasks_init_py", "label": "__init__.py", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 5, "community_name": "Community 5", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "tasks_init_init_scheduled_tasks", "label": "init_scheduled_tasks()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "init_scheduled_tasks()", "community": 5, "community_name": "Community 5", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "tasks_init_shutdown_scheduler", "label": "shutdown_scheduler()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "shutdown_scheduler()", "community": 5, "community_name": "Community 5", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "core_auth_py", "label": "auth.py", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 11.4, "font": {"size": 0, "color": "#ffffff"}, "title": "auth.py", "community": 5, "community_name": "Community 5", "source_file": "core/auth.py", "file_type": "code", "degree": 18}, {"id": "core_auth_redis_session_enabled", "label": "_redis_session_enabled()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "_redis_session_enabled()", "community": 5, "community_name": "Community 5", "source_file": "core/auth.py", "file_type": "code", "degree": 2}, {"id": "core_auth_get_redis_client", "label": "_get_redis_client()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.7, "font": {"size": 0, "color": "#ffffff"}, "title": "_get_redis_client()", "community": 5, "community_name": "Community 5", "source_file": "core/auth.py", "file_type": "code", "degree": 9}, {"id": "core_auth_session_key", "label": "_session_key()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "_session_key()", "community": 5, "community_name": "Community 5", "source_file": "core/auth.py", "file_type": "code", "degree": 5}, {"id": "core_auth_refresh_key", "label": "_refresh_key()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "boLine truncated
|
||||
const RAW_EDGES = [{"from": "main_py", "to": "app_main_lifespan", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_mask_secret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_root", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_health_check", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_lifespan", "to": "core_login_crypto_ensure_initialized", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_lifespan", "to": "tasks_init_init_scheduled_tasks", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_lifespan", "to": "tasks_init_shutdown_scheduler", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "tasks_init_py", "to": "tasks_init_init_scheduled_tasks", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "tasks_init_py", "to": "tasks_init_shutdown_scheduler", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_redis_session_enabled", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_redis_client", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_session_key", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_refresh_key", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_store_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_revoke_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_extend_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_is_session_valid", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_store_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_is_refresh_token_valid", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_revoke_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_create_access_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_create_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_decode_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_current_user_by_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_current_user", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "Line truncated
|
||||
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 454}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 428}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 277}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 207}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 165}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 128}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 102}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 68}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 68}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 65}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 61}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 49}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 31}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 31}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 21}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 20}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 19}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 15}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 15}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 14}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 14}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 13}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 13}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 12}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 12}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 11}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 10}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 10}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 10}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 10}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 10}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 10}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 10}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 10}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 10}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 9}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 9}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 9}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 9}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 8}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 7}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 4}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 4}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 3}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 2}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 2}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 1}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 1}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 1}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 1}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 1}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 1}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 1}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 1}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 1}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 1}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 1}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 1}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 0}];
|
||||
const RAW_NODES = [{"id": "init_py", "label": "__init__.py", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 45, "community_name": "Community 45", "source_file": "__init__.py", "file_type": "code", "degree": 0}, {"id": "main_py", "label": "main.py", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "main.py", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_lifespan", "label": "lifespan()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_mask_secret", "label": "_mask_secret()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "_mask_secret()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_root", "label": "root()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "root()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_health_check", "label": "health_check()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "health_check()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "tasks_init_py", "label": "__init__.py", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 5, "community_name": "Community 5", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "tasks_init_init_scheduled_tasks", "label": "init_scheduled_tasks()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "init_scheduled_tasks()", "community": 5, "community_name": "Community 5", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "tasks_init_shutdown_scheduler", "label": "shutdown_scheduler()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "shutdown_scheduler()", "community": 5, "community_name": "Community 5", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "core_auth_py", "label": "auth.py", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 11.3, "font": {"size": 0, "color": "#ffffff"}, "title": "auth.py", "community": 5, "community_name": "Community 5", "source_file": "core/auth.py", "file_type": "code", "degree": 18}, {"id": "core_auth_redis_session_enabled", "label": "_redis_session_enabled()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "_redis_session_enabled()", "community": 5, "community_name": "Community 5", "source_file": "core/auth.py", "file_type": "code", "degree": 2}, {"id": "core_auth_get_redis_client", "label": "_get_redis_client()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.7, "font": {"size": 0, "color": "#ffffff"}, "title": "_get_redis_client()", "community": 5, "community_name": "Community 5", "source_file": "core/auth.py", "file_type": "code", "degree": 9}, {"id": "core_auth_session_key", "label": "_session_key()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "_session_key()", "community": 5, "community_name": "Community 5", "source_file": "core/auth.py", "file_type": "code", "degree": 5}, {"id": "core_auth_refresh_key", "label": "_refresh_key()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "boLine truncated
|
||||
const RAW_EDGES = [{"from": "main_py", "to": "app_main_lifespan", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_mask_secret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_root", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_health_check", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_lifespan", "to": "core_login_crypto_ensure_initialized", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_lifespan", "to": "tasks_init_init_scheduled_tasks", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_lifespan", "to": "tasks_init_shutdown_scheduler", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "tasks_init_py", "to": "tasks_init_init_scheduled_tasks", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "tasks_init_py", "to": "tasks_init_shutdown_scheduler", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_redis_session_enabled", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_redis_client", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_session_key", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_refresh_key", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_store_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_revoke_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_extend_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_is_session_valid", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_store_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_is_refresh_token_valid", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_revoke_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_create_access_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_create_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_decode_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_current_user_by_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_current_user", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "Line truncated
|
||||
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 441}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 433}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 293}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 227}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 168}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 129}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 109}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 107}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 75}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 71}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 67}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 49}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 31}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 20}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 18}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 16}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 15}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 15}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 15}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 14}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 13}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 13}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 13}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 13}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 12}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 11}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 10}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 10}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 10}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 10}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 10}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 10}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 10}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 10}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 9}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 9}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 8}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 8}, {"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": 4}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 4}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 3}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 2}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 2}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 1}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 1}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 1}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 1}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 1}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 1}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 1}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 1}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 1}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 1}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 1}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 1}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 0}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 0}];
|
||||
|
||||
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
|
||||
function esc(s) {
|
||||
|
||||
+10668
-5247
File diff suppressed because it is too large.
Load diff
@@ -25,7 +25,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/core/wechat_message.py": 1778578258.0458734,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/material.py": 1779283385.245847,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py": 1779022399.0175831,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py": 1779491653.3192608,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py": 1779509954.4854348,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/__init__.py": 1779418058.876012,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/research_donation.py": 1779177348.5945773,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_material.py": 1779284411.5179992,
|
||||
@@ -76,13 +76,14 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_third_party_company.py": 1779265648.2051165,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/material_stock_log.py": 1779281903.0942652,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/tenant.py": 1779265611.0532296,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py": 1779265707.1662717,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py": 1779510193.3188746,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sop_document.py": 1779265721.9928973,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py": 1779506354.67238,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py": 1779510450.6769412,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_third_party_item.py": 1779265661.482352,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py": 1779265718.524432,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py": 1779510328.552785,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/collection_protocol.py": 1779329214.3583212,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py": 1779332036.2049248,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py": 1779510275.0678422,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/clean_room.py": 1778775238.2993922,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/__init__.py": 1778605691.3816392,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/express_company.py": 1779265659.3453207,
|
||||
@@ -110,6 +111,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/collection_protocol_no.py": 1779279043.1571646,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/storage_facility.py": 1779270989.9713993,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_sample_type.py": 1778733001.8375483,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py": 1779510237.5108597,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/dept.py": 1779265637.7914758,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/base.py": 1778578258.062207,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/protocol_donation_convert.py": 1779161468.6582925,
|
||||
@@ -133,7 +135,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/workflow.py": 1779266232.4568832,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/sample_reception.py": 1779304425.1104686,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py": 1779281097.279193,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py": 1779435531.0507855,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py": 1779510401.9179235,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/leave.py": 1779266168.8693042,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/services/workflow_callback.py": 1778727966.7277644,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/services/workflow_engine.py": 1778634664.6293883,
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
-- /api/web/admin/api-request-logs 列表性能索引补强
|
||||
-- 典型查询:
|
||||
-- WHERE is_del=0 [AND http_method=?] [AND status_code=?]
|
||||
-- [AND create_at between ? and ?]
|
||||
-- ORDER BY create_at DESC
|
||||
|
||||
-- 默认列表 + 时间倒序分页
|
||||
ALTER TABLE sys_api_request_log
|
||||
ADD INDEX idx_arl_isdel_createat (is_del, create_at);
|
||||
|
||||
-- 按方法过滤
|
||||
ALTER TABLE sys_api_request_log
|
||||
ADD INDEX idx_arl_isdel_method_createat (is_del, http_method, create_at);
|
||||
|
||||
-- 按状态码过滤
|
||||
ALTER TABLE sys_api_request_log
|
||||
ADD INDEX idx_arl_isdel_status_createat (is_del, status_code, create_at);
|
||||
@@ -1,12 +0,0 @@
|
||||
-- 给 /api/web/admin/products 列表(GET,前端加密传输时为 POST + X-HTTP-Method-Override: GET)做索引补强
|
||||
-- 典型 SQL:WHERE is_del = 0 [AND category_id = ?] [AND (name LIKE ... OR description LIKE ...)] ORDER BY create_at DESC
|
||||
-- LIKE '%keyword%' 无法有效走 name/description 索引;无关键词时下面索引可帮助 COUNT + 分页排序。
|
||||
-- 执行前请先 SHOW INDEX FROM bas_product; 若索引已存在可跳过对应语句。
|
||||
|
||||
-- 1) 全量列表 / 仅启用筛选:is_del + 排序字段
|
||||
ALTER TABLE bas_product
|
||||
ADD INDEX idx_product_isdel_createat (is_del, create_at);
|
||||
|
||||
-- 2) 按分类筛选 + 排序(与 1 并存;分类列表走此索引更省扫描)
|
||||
ALTER TABLE bas_product
|
||||
ADD INDEX idx_product_isdel_category_createat (is_del, category_id, create_at);
|
||||
@@ -1,26 +0,0 @@
|
||||
-- /api/web/delivery-tasks 列表性能索引补强
|
||||
-- 目标查询特征:
|
||||
-- 1) WHERE is_del=0 ORDER BY create_at DESC(默认列表)
|
||||
-- 2) WHERE is_del=0 AND region_id=? AND status=? ORDER BY create_at DESC
|
||||
-- 3) WHERE is_del=0 AND deliver_id=? ORDER BY create_at DESC
|
||||
-- 4) 列表中按 task_id 聚合明细数量(biz_delivery_task_item)
|
||||
|
||||
-- 1) 默认列表与时间倒序分页
|
||||
ALTER TABLE biz_delivery_task
|
||||
ADD INDEX idx_dt_isdel_createat (is_del, create_at);
|
||||
|
||||
-- 2) 区域 + 状态过滤场景
|
||||
ALTER TABLE biz_delivery_task
|
||||
ADD INDEX idx_dt_isdel_region_status_createat (is_del, region_id, status, create_at);
|
||||
|
||||
-- 3) 配送员维度过滤场景
|
||||
ALTER TABLE biz_delivery_task
|
||||
ADD INDEX idx_dt_isdel_deliver_createat (is_del, deliver_id, create_at);
|
||||
|
||||
-- 4) 供应商维度过滤场景(供应商端任务列表)
|
||||
ALTER TABLE biz_delivery_task
|
||||
ADD INDEX idx_dt_isdel_supplier_createat (is_del, supplier_id, create_at);
|
||||
|
||||
-- 5) 列表 itemCount 聚合:WHERE task_id IN (...) AND is_del=0 GROUP BY task_id
|
||||
ALTER TABLE biz_delivery_task_item
|
||||
ADD INDEX idx_dti_task_isdel (task_id, is_del);
|
||||
@@ -1,21 +0,0 @@
|
||||
-- 给 /api/web/admin/orders 列表接口做性能索引补强(幂等尽量实现)
|
||||
-- 注意:不同 MySQL 版本对 IF NOT EXISTS 支持不同;若执行失败,请先 SHOW INDEX 再手动判断是否已存在。
|
||||
|
||||
-- 1) 覆盖最常见列表:WHERE is_del=0 ORDER BY create_at DESC
|
||||
-- 目标:减少 Using filesort / 全表扫描风险
|
||||
ALTER TABLE biz_order
|
||||
ADD INDEX idx_order_isdel_createat (is_del, create_at);
|
||||
|
||||
-- 2) 常用筛选:区域 + 订单主状态 + 时间排序
|
||||
ALTER TABLE biz_order
|
||||
ADD INDEX idx_order_isdel_region_orderstatus_createat (is_del, region_id, order_status, create_at);
|
||||
|
||||
-- 3) 常用筛选:区域 + 创建时间范围(startDate/endDate)
|
||||
ALTER TABLE biz_order
|
||||
ADD INDEX idx_order_isdel_region_createat (is_del, region_id, create_at);
|
||||
|
||||
-- 4) 单号查询建议:
|
||||
-- 当前实现是 order_no LIKE '%xxx%',该写法通常无法走索引。
|
||||
-- 若业务可改为前缀匹配(LIKE 'xxx%')或精确匹配(=),将显著提升性能。
|
||||
-- 订单号已有唯一索引 uk_order_no(可用于 '=' 或前缀匹配)。
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
-- /api/web/admin/price-versions 列表性能索引补强
|
||||
-- 典型查询:
|
||||
-- WHERE is_del=0 [AND region_id=?] [AND supplier_id=?] [AND status=?]
|
||||
-- ORDER BY create_at DESC
|
||||
|
||||
-- 默认列表 + 时间倒序分页
|
||||
ALTER TABLE biz_price_list
|
||||
ADD INDEX idx_pl_isdel_createat (is_del, create_at);
|
||||
|
||||
-- 区域维度过滤
|
||||
ALTER TABLE biz_price_list
|
||||
ADD INDEX idx_pl_isdel_region_createat (is_del, region_id, create_at);
|
||||
|
||||
-- 供应商维度过滤
|
||||
ALTER TABLE biz_price_list
|
||||
ADD INDEX idx_pl_isdel_supplier_createat (is_del, supplier_id, create_at);
|
||||
|
||||
-- 状态维度过滤
|
||||
ALTER TABLE biz_price_list
|
||||
ADD INDEX idx_pl_isdel_status_createat (is_del, status, create_at);
|
||||
@@ -1,7 +0,0 @@
|
||||
-- 询价报价界面“区域”下拉/Tab:启用区域列表索引补强
|
||||
-- 对应接口:GET /api/web/admin/regions/active
|
||||
-- 查询:WHERE is_del=0 AND is_active=1 ORDER BY sort_order
|
||||
|
||||
ALTER TABLE sys_region
|
||||
ADD INDEX idx_region_isdel_active_sort (is_del, is_active, sort_order);
|
||||
|
||||
@@ -0,0 +1,573 @@
|
||||
#!/usr/bin/env python3
|
||||
"""字段一致性检查器 — 检测 CRUD → API Schema → 前端 formData 字段缺失问题。
|
||||
|
||||
用法:
|
||||
python backend/scripts/check_field_consistency.py
|
||||
python backend/scripts/check_field_consistency.py --entity consumable
|
||||
python backend/scripts/check_field_consistency.py --json
|
||||
|
||||
退出码:
|
||||
0 — 全部通过
|
||||
1 — 存在警告(字段缺失)
|
||||
2 — 存在错误(文件/类找不到等)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from typing import Any, Dict, List, Optional, Set, Tuple
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 项目根目录(从脚本位置推断)
|
||||
# ---------------------------------------------------------------------------
|
||||
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
_PROJECT_ROOT = os.path.abspath(os.path.join(_SCRIPT_DIR, "..", ".."))
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 只读字段 — 这些字段出现在 _row_to_dict 但不应出现在 CreateBody/UpdateBody/formData
|
||||
# ---------------------------------------------------------------------------
|
||||
READ_ONLY_FIELDS: Set[str] = {
|
||||
"id",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"stockQty",
|
||||
"tenantNo",
|
||||
"attachmentFiles", # 计算字段,由后端从 URLs 生成
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 实体注册表
|
||||
# ---------------------------------------------------------------------------
|
||||
ENTITIES: List[Dict[str, str]] = [
|
||||
{
|
||||
"name": "consumable",
|
||||
"crud_file": "backend/app/crud/consumable.py",
|
||||
"schema_file": "backend/app/api/production.py",
|
||||
"create_body": "ConsumableCreateBody",
|
||||
"update_body": "ConsumableUpdateBody",
|
||||
"frontend_file": "web-admin/src/views/production/consumable/index.vue",
|
||||
},
|
||||
{
|
||||
"name": "reagent",
|
||||
"crud_file": "backend/app/crud/reagent.py",
|
||||
"schema_file": "backend/app/api/production.py",
|
||||
"create_body": "ReagentCreateBody",
|
||||
"update_body": "ReagentUpdateBody",
|
||||
"frontend_file": "web-admin/src/views/production/reagent/index.vue",
|
||||
},
|
||||
{
|
||||
"name": "material (market)",
|
||||
"crud_file": "backend/app/crud/material.py",
|
||||
"schema_file": "backend/app/api/material.py",
|
||||
"create_body": "MaterialBody",
|
||||
"update_body": "MaterialUpdateBody",
|
||||
"frontend_file": "web-admin/src/views/market/material/index.vue",
|
||||
},
|
||||
{
|
||||
"name": "qc_material",
|
||||
"crud_file": "backend/app/crud/qc_material.py",
|
||||
"schema_file": "backend/app/api/qc.py",
|
||||
"create_body": "QcMaterialBody",
|
||||
"update_body": "QcMaterialUpdateBody",
|
||||
"frontend_file": "web-admin/src/views/quality/material/index.vue",
|
||||
},
|
||||
{
|
||||
"name": "sop_document",
|
||||
"crud_file": "backend/app/crud/sop_document.py",
|
||||
"schema_file": "backend/app/api/production.py",
|
||||
"create_body": "SopDocumentCreateBody",
|
||||
"update_body": "SopDocumentUpdateBody",
|
||||
"frontend_file": "web-admin/src/views/production/sop/index.vue",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# 终端颜色辅助
|
||||
# ===================================================================
|
||||
class _C:
|
||||
"""ANSI 颜色常量"""
|
||||
|
||||
RESET = "\033[0m"
|
||||
GREEN = "\033[32m"
|
||||
YELLOW = "\033[33m"
|
||||
RED = "\033[31m"
|
||||
CYAN = "\033[36m"
|
||||
BOLD = "\033[1m"
|
||||
DIM = "\033[2m"
|
||||
|
||||
|
||||
def _supports_color() -> bool:
|
||||
"""检测终端是否支持颜色"""
|
||||
if os.environ.get("NO_COLOR"):
|
||||
return False
|
||||
if not hasattr(sys.stdout, "isatty"):
|
||||
return False
|
||||
return sys.stdout.isatty()
|
||||
|
||||
|
||||
_COLOR = _supports_color()
|
||||
|
||||
|
||||
def cprint(text: str, color: str = "") -> None:
|
||||
if _COLOR and color:
|
||||
print("{}{}{}".format(color, text, _C.RESET))
|
||||
else:
|
||||
print(text)
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# 工具函数
|
||||
# ===================================================================
|
||||
def _read_file(rel_path: str) -> Optional[str]:
|
||||
"""读取项目根目录下的相对路径文件"""
|
||||
full = os.path.join(_PROJECT_ROOT, rel_path)
|
||||
if not os.path.isfile(full):
|
||||
return None
|
||||
with open(full, "r", encoding="utf-8", errors="replace") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def _snake_to_camel(name: str) -> str:
|
||||
"""snake_case → camelCase: warning_qty → warningQty"""
|
||||
parts = name.split("_")
|
||||
return parts[0] + "".join(p.capitalize() for p in parts[1:])
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# 提取逻辑 — _row_to_dict
|
||||
# ===================================================================
|
||||
_RE_DICT_KEY = re.compile(r'"([a-zA-Z][a-zA-Z0-9]*)"\s*:')
|
||||
|
||||
|
||||
def extract_row_to_dict_fields(source: str) -> List[str]:
|
||||
"""从 CRUD 文件提取 _row_to_dict 函数的字典键(camelCase)。
|
||||
|
||||
支持一个文件中有多个 _row_to_dict 的情况 — 只取第一个。
|
||||
"""
|
||||
# 定位函数起始
|
||||
func_match = re.search(
|
||||
r"def\s+_row_to_dict\s*\([^)]*\)\s*->\s*[^:]+:", source
|
||||
)
|
||||
if not func_match:
|
||||
return []
|
||||
|
||||
# 从函数开始往后找到第一个 return { ... } 块
|
||||
start = func_match.end()
|
||||
# 找到 return {
|
||||
ret_match = re.search(r"return\s*\{", source[start:])
|
||||
if not ret_match:
|
||||
return []
|
||||
|
||||
brace_start = start + ret_match.end() - 1 # 指向 {
|
||||
|
||||
# 匹配大括号
|
||||
depth = 0
|
||||
end = brace_start
|
||||
for i in range(brace_start, len(source)):
|
||||
ch = source[i]
|
||||
if ch == "{":
|
||||
depth += 1
|
||||
elif ch == "}":
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
end = i
|
||||
break
|
||||
|
||||
block = source[brace_start : end + 1]
|
||||
keys = _RE_DICT_KEY.findall(block)
|
||||
# 去重但保持顺序
|
||||
seen = set()
|
||||
result = []
|
||||
for k in keys:
|
||||
if k not in seen:
|
||||
seen.add(k)
|
||||
result.append(k)
|
||||
return result
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# 提取逻辑 — Pydantic Schema 类
|
||||
# ===================================================================
|
||||
_RE_FIELD_ALIAS = re.compile(r'alias\s*=\s*"([^"]+)"')
|
||||
_RE_FIELD_LINE = re.compile(
|
||||
r"^\s+([a-z_][a-z0-9_]*)\s*:\s*"
|
||||
)
|
||||
|
||||
|
||||
def extract_schema_fields(source: str, class_name: str) -> Optional[List[str]]:
|
||||
"""从 Pydantic 类提取字段名(返回 camelCase 列表)。
|
||||
|
||||
优先使用 alias,否则 snake_case 转 camelCase。
|
||||
返回 None 表示类未找到。
|
||||
"""
|
||||
# 找到类定义
|
||||
class_match = re.search(
|
||||
r"class\s+{}\s*\([^)]*\)\s*:".format(re.escape(class_name)),
|
||||
source,
|
||||
)
|
||||
if not class_match:
|
||||
return None
|
||||
|
||||
class_start = class_match.end()
|
||||
|
||||
# 收集类体 — 到下一个顶层 class 或 def(不缩进)或文件末尾
|
||||
body_lines = []
|
||||
for line in source[class_start:].split("\n"):
|
||||
stripped = line.lstrip()
|
||||
if stripped and not stripped.startswith("#") and not line[0].isspace():
|
||||
# 到达下一个顶层定义
|
||||
break
|
||||
if stripped.startswith("class ") or (stripped.startswith("def ") and not line.startswith(" ")):
|
||||
break
|
||||
body_lines.append(line)
|
||||
|
||||
body = "\n".join(body_lines)
|
||||
|
||||
fields = []
|
||||
# 按行解析
|
||||
for line in body.split("\n"):
|
||||
field_match = _RE_FIELD_LINE.match(line)
|
||||
if not field_match:
|
||||
continue
|
||||
field_name = field_match.group(1)
|
||||
if field_name == "model_config":
|
||||
continue
|
||||
|
||||
# 检查是否有 alias
|
||||
alias_match = _RE_FIELD_ALIAS.search(line)
|
||||
if alias_match:
|
||||
fields.append(alias_match.group(1))
|
||||
else:
|
||||
fields.append(_snake_to_camel(field_name))
|
||||
|
||||
return fields
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# 提取逻辑 — 前端 formData
|
||||
# ===================================================================
|
||||
_RE_FORMDATA_KEY = re.compile(r"^\s+([a-zA-Z][a-zA-Z0-9]*)\s*:")
|
||||
|
||||
|
||||
def extract_frontend_formdata(source: str) -> List[str]:
|
||||
"""从 Vue 文件提取 formData 的键名(camelCase)。"""
|
||||
# 匹配多种写法: reactive({ ... }), reactive<SomeType>({ ... })
|
||||
match = re.search(
|
||||
r"(?:const|let|var)\s+formData\s*=\s*reactive(?:<[^>]*>)?\s*\(\s*\{",
|
||||
source,
|
||||
)
|
||||
if not match:
|
||||
return []
|
||||
|
||||
start = match.end() - 1 # 指向 {
|
||||
depth = 0
|
||||
end = start
|
||||
for i in range(start, len(source)):
|
||||
ch = source[i]
|
||||
if ch == "{":
|
||||
depth += 1
|
||||
elif ch == "}":
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
end = i
|
||||
break
|
||||
|
||||
block = source[start : end + 1]
|
||||
fields = []
|
||||
for line in block.split("\n"):
|
||||
m = _RE_FORMDATA_KEY.match(line)
|
||||
if m:
|
||||
fields.append(m.group(1))
|
||||
return fields
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# 单个实体检查
|
||||
# ===================================================================
|
||||
def check_entity(entity: Dict[str, str]) -> Dict[str, Any]:
|
||||
"""检查单个实体的字段一致性,返回报告字典。"""
|
||||
name = entity["name"]
|
||||
report: Dict[str, Any] = {
|
||||
"entity": name,
|
||||
"status": "ok",
|
||||
"crud_fields": [],
|
||||
"create_body_fields": None,
|
||||
"update_body_fields": None,
|
||||
"frontend_fields": [],
|
||||
"warnings": [],
|
||||
"errors": [],
|
||||
}
|
||||
|
||||
# 1. 读取 CRUD 文件
|
||||
crud_src = _read_file(entity["crud_file"])
|
||||
if crud_src is None:
|
||||
report["status"] = "error"
|
||||
report["errors"].append("CRUD file not found: {}".format(entity["crud_file"]))
|
||||
return report
|
||||
|
||||
crud_fields = extract_row_to_dict_fields(crud_src)
|
||||
report["crud_fields"] = crud_fields
|
||||
if not crud_fields:
|
||||
report["status"] = "error"
|
||||
report["errors"].append(
|
||||
"No _row_to_dict fields found in {}".format(entity["crud_file"])
|
||||
)
|
||||
return report
|
||||
|
||||
writable_fields = [f for f in crud_fields if f not in READ_ONLY_FIELDS]
|
||||
|
||||
# 2. 读取 Schema 文件
|
||||
schema_src = _read_file(entity["schema_file"])
|
||||
if schema_src is None:
|
||||
report["status"] = "error"
|
||||
report["errors"].append(
|
||||
"Schema file not found: {}".format(entity["schema_file"])
|
||||
)
|
||||
return report
|
||||
|
||||
# 3. 提取 CreateBody
|
||||
create_fields = extract_schema_fields(schema_src, entity["create_body"])
|
||||
report["create_body_fields"] = create_fields
|
||||
if create_fields is None:
|
||||
report["status"] = "warning"
|
||||
report["warnings"].append(
|
||||
"Create body class '{}' not found in {}".format(
|
||||
entity["create_body"], entity["schema_file"]
|
||||
)
|
||||
)
|
||||
else:
|
||||
missing = [f for f in writable_fields if f not in create_fields]
|
||||
if missing:
|
||||
report["status"] = "warning"
|
||||
report["warnings"].append(
|
||||
"CreateBody missing fields: {}".format(", ".join(sorted(missing)))
|
||||
)
|
||||
|
||||
# 4. 提取 UpdateBody
|
||||
update_fields = extract_schema_fields(schema_src, entity["update_body"])
|
||||
report["update_body_fields"] = update_fields
|
||||
if update_fields is None:
|
||||
report["status"] = "warning"
|
||||
report["warnings"].append(
|
||||
"Update body class '{}' not found in {}".format(
|
||||
entity["update_body"], entity["schema_file"]
|
||||
)
|
||||
)
|
||||
else:
|
||||
missing = [f for f in writable_fields if f not in update_fields]
|
||||
if missing:
|
||||
report["status"] = "warning"
|
||||
report["warnings"].append(
|
||||
"UpdateBody missing fields: {}".format(", ".join(sorted(missing)))
|
||||
)
|
||||
|
||||
# 5. 读取前端文件
|
||||
fe_src = _read_file(entity["frontend_file"])
|
||||
if fe_src is None:
|
||||
report["status"] = "warning"
|
||||
report["warnings"].append(
|
||||
"Frontend file not found: {}".format(entity["frontend_file"])
|
||||
)
|
||||
return report
|
||||
|
||||
fe_fields = extract_frontend_formdata(fe_src)
|
||||
report["frontend_fields"] = fe_fields
|
||||
if not fe_fields:
|
||||
report["status"] = "warning"
|
||||
report["warnings"].append(
|
||||
"No formData found in {}".format(entity["frontend_file"])
|
||||
)
|
||||
return report
|
||||
|
||||
missing_fe = [f for f in writable_fields if f not in fe_fields]
|
||||
if missing_fe:
|
||||
report["status"] = "warning"
|
||||
report["warnings"].append(
|
||||
"Frontend formData missing fields: {}".format(
|
||||
", ".join(sorted(missing_fe))
|
||||
)
|
||||
)
|
||||
|
||||
# 6. 反向检查: Schema 有但 _row_to_dict 没有的字段
|
||||
if create_fields is not None:
|
||||
extra_create = [f for f in create_fields if f not in crud_fields]
|
||||
if extra_create:
|
||||
report.setdefault("info", []).append(
|
||||
"CreateBody has extra fields (not in _row_to_dict): {}".format(
|
||||
", ".join(sorted(extra_create))
|
||||
)
|
||||
)
|
||||
|
||||
# 7. 反向检查: formData 有但 _row_to_dict 没有的字段
|
||||
extra_fe = [f for f in fe_fields if f not in crud_fields]
|
||||
if extra_fe:
|
||||
report.setdefault("info", []).append(
|
||||
"Frontend formData has extra fields (not in _row_to_dict): {}".format(
|
||||
", ".join(sorted(extra_fe))
|
||||
)
|
||||
)
|
||||
|
||||
return report
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# 报告输出
|
||||
# ===================================================================
|
||||
def print_report(report: Dict[str, Any]) -> None:
|
||||
"""打印单个实体的检查报告(终端彩色输出)"""
|
||||
name = report["entity"]
|
||||
status = report["status"]
|
||||
|
||||
if status == "ok":
|
||||
cprint(" [OK] {}".format(name), _C.GREEN)
|
||||
elif status == "warning":
|
||||
cprint(" [!!] {} — warnings".format(name), _C.YELLOW)
|
||||
else:
|
||||
cprint(" [XX] {} — errors".format(name), _C.RED)
|
||||
|
||||
# CRUD fields
|
||||
crud_fields = report.get("crud_fields", [])
|
||||
if crud_fields:
|
||||
writable = [f for f in crud_fields if f not in READ_ONLY_FIELDS]
|
||||
read_only = [f for f in crud_fields if f in READ_ONLY_FIELDS]
|
||||
cprint(
|
||||
" _row_to_dict ({} total, {} writable): {}".format(
|
||||
len(crud_fields),
|
||||
len(writable),
|
||||
", ".join(writable),
|
||||
),
|
||||
_C.DIM,
|
||||
)
|
||||
if read_only:
|
||||
cprint(
|
||||
" read-only: {}".format(", ".join(sorted(read_only))),
|
||||
_C.DIM,
|
||||
)
|
||||
|
||||
# Schema fields
|
||||
for body_label, body_key in [
|
||||
("CreateBody", "create_body_fields"),
|
||||
("UpdateBody", "update_body_fields"),
|
||||
]:
|
||||
fields = report.get(body_key)
|
||||
if fields is not None:
|
||||
cprint(
|
||||
" {}: {}".format(body_label, ", ".join(fields)),
|
||||
_C.DIM,
|
||||
)
|
||||
|
||||
# Frontend fields
|
||||
fe_fields = report.get("frontend_fields", [])
|
||||
if fe_fields:
|
||||
cprint(
|
||||
" formData: {}".format(", ".join(fe_fields)),
|
||||
_C.DIM,
|
||||
)
|
||||
|
||||
# Warnings
|
||||
for w in report.get("warnings", []):
|
||||
cprint(" WARN: {}".format(w), _C.YELLOW)
|
||||
|
||||
# Errors
|
||||
for e in report.get("errors", []):
|
||||
cprint(" ERR: {}".format(e), _C.RED)
|
||||
|
||||
# Info
|
||||
for info in report.get("info", []):
|
||||
cprint(" INFO: {}".format(info), _C.CYAN)
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def print_json_report(reports: List[Dict[str, Any]]) -> None:
|
||||
"""输出 JSON 格式报告"""
|
||||
print(json.dumps(reports, indent=2, ensure_ascii=False))
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# 主入口
|
||||
# ===================================================================
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="字段一致性检查器 — CRUD ↔ Schema ↔ 前端 formData"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--entity",
|
||||
type=str,
|
||||
default=None,
|
||||
help="只检查指定实体名称(如 consumable)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--json",
|
||||
action="store_true",
|
||||
dest="json_output",
|
||||
help="输出 JSON 格式",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
# 筛选实体
|
||||
entities = ENTITIES
|
||||
if args.entity:
|
||||
entities = [e for e in ENTITIES if e["name"] == args.entity]
|
||||
if not entities:
|
||||
cprint(
|
||||
"Entity '{}' not found. Available: {}".format(
|
||||
args.entity, ", ".join(e["name"] for e in ENTITIES)
|
||||
),
|
||||
_C.RED,
|
||||
)
|
||||
return 2
|
||||
|
||||
if not args.json_output:
|
||||
cprint(
|
||||
"Field Consistency Checker — checking {} entities".format(
|
||||
len(entities)
|
||||
),
|
||||
_C.BOLD,
|
||||
)
|
||||
cprint("Project root: {}".format(_PROJECT_ROOT), _C.DIM)
|
||||
print()
|
||||
|
||||
reports = []
|
||||
has_warnings = False
|
||||
has_errors = False
|
||||
|
||||
for entity in entities:
|
||||
report = check_entity(entity)
|
||||
reports.append(report)
|
||||
if report["status"] == "warning":
|
||||
has_warnings = True
|
||||
elif report["status"] == "error":
|
||||
has_errors = True
|
||||
|
||||
if args.json_output:
|
||||
print_json_report(reports)
|
||||
else:
|
||||
for report in reports:
|
||||
print_report(report)
|
||||
|
||||
# 汇总
|
||||
ok_count = sum(1 for r in reports if r["status"] == "ok")
|
||||
warn_count = sum(1 for r in reports if r["status"] == "warning")
|
||||
err_count = sum(1 for r in reports if r["status"] == "error")
|
||||
|
||||
cprint(
|
||||
"Summary: {} OK, {} warnings, {} errors (total {})".format(
|
||||
ok_count, warn_count, err_count, len(reports)
|
||||
),
|
||||
_C.BOLD,
|
||||
)
|
||||
|
||||
if has_errors:
|
||||
return 2
|
||||
if has_warnings:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -1,68 +0,0 @@
|
||||
-- 运营端权限改造:super_admin + 多区域 + 菜单 code 授权
|
||||
|
||||
-- 1) 角色迁移:admin -> super_admin
|
||||
UPDATE sys_user
|
||||
SET role = 'super_admin',
|
||||
update_at = NOW()
|
||||
WHERE is_del = 0
|
||||
AND role = 'admin';
|
||||
|
||||
-- 2) 用户-区域权限表
|
||||
CREATE TABLE IF NOT EXISTS sys_user_region_scope (
|
||||
id VARCHAR(32) NOT NULL COMMENT '主键ID',
|
||||
user_id VARCHAR(32) NOT NULL COMMENT '用户ID',
|
||||
region_id VARCHAR(32) NOT NULL COMMENT '区域ID',
|
||||
is_del TINYINT NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
create_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
create_by VARCHAR(32) DEFAULT NULL COMMENT '创建人ID',
|
||||
create_name VARCHAR(100) DEFAULT NULL COMMENT '创建人姓名',
|
||||
update_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
update_by VARCHAR(32) DEFAULT NULL COMMENT '修改人ID',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_user_region_scope (user_id, region_id, is_del),
|
||||
KEY idx_user_region_scope_user (user_id, is_del),
|
||||
KEY idx_user_region_scope_region (region_id, is_del)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户区域权限';
|
||||
|
||||
-- 3) 用户-区域权限历史表(无索引、无 is_del)
|
||||
CREATE TABLE IF NOT EXISTS sys_user_region_scope_his (
|
||||
id VARCHAR(32) NOT NULL COMMENT '主键ID',
|
||||
user_id VARCHAR(32) NOT NULL COMMENT '用户ID',
|
||||
region_id VARCHAR(32) NOT NULL COMMENT '区域ID',
|
||||
create_at DATETIME DEFAULT NULL COMMENT '创建时间',
|
||||
create_by VARCHAR(32) DEFAULT NULL COMMENT '创建人ID',
|
||||
create_name VARCHAR(100) DEFAULT NULL COMMENT '创建人姓名',
|
||||
update_at DATETIME DEFAULT NULL COMMENT '修改时间',
|
||||
update_by VARCHAR(32) DEFAULT NULL COMMENT '修改人ID',
|
||||
his_create_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '历史记录创建时间'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户区域权限历史';
|
||||
|
||||
-- 4) 用户-菜单 code 权限表
|
||||
CREATE TABLE IF NOT EXISTS sys_user_menu_scope (
|
||||
id VARCHAR(32) NOT NULL COMMENT '主键ID',
|
||||
user_id VARCHAR(32) NOT NULL COMMENT '用户ID',
|
||||
menu_code VARCHAR(100) NOT NULL COMMENT '菜单编码',
|
||||
is_del TINYINT NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
create_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
create_by VARCHAR(32) DEFAULT NULL COMMENT '创建人ID',
|
||||
create_name VARCHAR(100) DEFAULT NULL COMMENT '创建人姓名',
|
||||
update_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
update_by VARCHAR(32) DEFAULT NULL COMMENT '修改人ID',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_user_menu_scope (user_id, menu_code, is_del),
|
||||
KEY idx_user_menu_scope_user (user_id, is_del),
|
||||
KEY idx_user_menu_scope_code (menu_code, is_del)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户菜单权限';
|
||||
|
||||
-- 5) 用户-菜单 code 权限历史表(无索引、无 is_del)
|
||||
CREATE TABLE IF NOT EXISTS sys_user_menu_scope_his (
|
||||
id VARCHAR(32) NOT NULL COMMENT '主键ID',
|
||||
user_id VARCHAR(32) NOT NULL COMMENT '用户ID',
|
||||
menu_code VARCHAR(100) NOT NULL COMMENT '菜单编码',
|
||||
create_at DATETIME DEFAULT NULL COMMENT '创建时间',
|
||||
create_by VARCHAR(32) DEFAULT NULL COMMENT '创建人ID',
|
||||
create_name VARCHAR(100) DEFAULT NULL COMMENT '创建人姓名',
|
||||
update_at DATETIME DEFAULT NULL COMMENT '修改时间',
|
||||
update_by VARCHAR(32) DEFAULT NULL COMMENT '修改人ID',
|
||||
his_create_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '历史记录创建时间'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户菜单权限历史';
|
||||
@@ -0,0 +1,100 @@
|
||||
# 字段一致性开发指南
|
||||
|
||||
## 问题背景
|
||||
|
||||
在前后端全链路开发中,一个字段需要同时出现在 **5 个位置** 才能完整打通:
|
||||
|
||||
```
|
||||
前端 formData → API Schema (Pydantic) → API Handler 传参 → CRUD 函数签名 → ORM 赋值
|
||||
```
|
||||
|
||||
任何一层遗漏都会导致字段**静默丢失**(Pydantic 默认忽略未定义字段,不报错),产生难以发现的 bug。
|
||||
|
||||
## 历史问题
|
||||
|
||||
| 时间 | 问题 | 根因 |
|
||||
|------|------|------|
|
||||
| 2026-05 | 耗材/试剂新增时 `warning_qty` 未保存 | Schema 缺字段 → Handler 没传 → CRUD 没接 |
|
||||
| 2026-05 | 耗材/试剂新增时 `status` 未保存 | 同上 |
|
||||
| 2026-05 | 变动记录筛选"出库"无效 | 前端 value 与后端期望值不匹配 |
|
||||
|
||||
## 开发纪律(MUST)
|
||||
|
||||
### 1. `_row_to_dict` 是单一真相源
|
||||
|
||||
CRUD 文件中的 `_row_to_dict` 函数定义了实体返回给前端的**所有可读字段**。它是字段一致性的基准。
|
||||
|
||||
### 2. 先写 `_row_to_dict`,再写 create/update
|
||||
|
||||
新增实体时:
|
||||
1. 先定义 `_row_to_dict`,列出所有字段的读取逻辑
|
||||
2. 根据 `_row_to_dict` 的字段列表,逐字段编写 CreateBody/UpdateBody
|
||||
3. 根据 Schema 字段,逐字段编写 create/update 函数签名和 ORM 赋值
|
||||
4. 根据后端字段列表,编写前端 formData
|
||||
|
||||
### 3. 排除只读字段
|
||||
|
||||
以下字段出现在 `_row_to_dict` 中但**不需要**出现在 CreateBody/UpdateBody 或 formData 中:
|
||||
|
||||
- `id` — 自动生成
|
||||
- `createTime` / `updateTime` — 自动维护
|
||||
- `stockQty` — 通过出入库操作维护,不可直接设置
|
||||
- `tenantNo` — 从认证上下文获取
|
||||
|
||||
### 4. 每个字段必须检查的 5 个位置
|
||||
|
||||
以 `warningQty` 为例:
|
||||
|
||||
| 位置 | 代码 | 必须 |
|
||||
|------|------|------|
|
||||
| `_row_to_dict` | `"warningQty": _dec(c.warning_qty)` | ✅ 读取 |
|
||||
| CreateBody | `warning_qty: Optional[float] = Field(0, alias="warningQty")` | ✅ 接收 |
|
||||
| Handler | `warning_qty=body.warning_qty` | ✅ 传递 |
|
||||
| create 函数签名 | `warning_qty: Optional[float] = None` | ✅ 接收 |
|
||||
| create ORM 赋值 | `warning_qty=warning_qty if warning_qty is not None else 0` | ✅ 写入 |
|
||||
|
||||
### 5. 实现后验证
|
||||
|
||||
每个实体完成后运行:
|
||||
|
||||
```bash
|
||||
python backend/scripts/check_field_consistency.py
|
||||
```
|
||||
|
||||
检查项:
|
||||
- `_row_to_dict` 中的可写字段是否都在 CreateBody/UpdateBody 中
|
||||
- `_row_to_dict` 中的可写字段是否都在前端 formData 中
|
||||
- 前后端字段值映射是否一致(如筛选条件 value 对应关系)
|
||||
|
||||
## 校验脚本
|
||||
|
||||
`backend/scripts/check_field_consistency.py` 自动扫描以下三层,输出 diff 报告:
|
||||
|
||||
1. **CRUD 层**:提取 `_row_to_dict` 的所有 camelCase key
|
||||
2. **API 层**:提取 CreateBody/UpdateBody 的所有字段(含 alias)
|
||||
3. **前端层**:提取 `formData` 的所有 key
|
||||
|
||||
### 使用方式
|
||||
|
||||
```bash
|
||||
# 检查所有注册实体
|
||||
python backend/scripts/check_field_consistency.py
|
||||
|
||||
# 检查单个实体
|
||||
python backend/scripts/check_field_consistency.py --entity consumable
|
||||
|
||||
# JSON 格式输出
|
||||
python backend/scripts/check_field_consistency.py --json
|
||||
```
|
||||
|
||||
### 退出码
|
||||
|
||||
- `0`:所有检查通过
|
||||
- `1`:发现字段不一致
|
||||
|
||||
## 常见陷阱
|
||||
|
||||
1. **alias 遗漏**:Schema 字段有 `alias="warningQty"` 但忘记写,Pydantic 只接受 snake_case 键名
|
||||
2. **Handler 传参遗漏**:Schema 有字段但 Handler 没传给 CRUD,字段在 Schema 层就被丢弃
|
||||
3. **CRUD 签名遗漏**:Handler 传了但 CRUD 函数签名没接收,Python 会报 unexpected keyword argument(运行时错误)
|
||||
4. **前端 value 与后端不匹配**:如筛选条件下拉框的 value 是 `"use"` 但后端期望 `"out"`
|
||||
@@ -1,19 +0,0 @@
|
||||
-- 细胞产品库字段重设计迁移
|
||||
-- 日期: 2026-05-21
|
||||
-- 设计文档: docs/superpowers/specs/2026-05-21-cell-product-library-design.md
|
||||
|
||||
-- 1. 新增 4 个业务字段(放在 storage_slot_id 之后,product_status 之前)
|
||||
ALTER TABLE biz_cell_product
|
||||
ADD COLUMN `passage` VARCHAR(8) DEFAULT NULL COMMENT '代次(P1~P8)' AFTER `storage_slot_id`,
|
||||
ADD COLUMN `freeze_date` DATETIME DEFAULT NULL COMMENT '冻存日期' AFTER `passage`,
|
||||
ADD COLUMN `expected_cell_count` DECIMAL(18,4) DEFAULT NULL COMMENT '预计细胞数量(单位:亿)' AFTER `freeze_date`,
|
||||
ADD COLUMN `viability` DECIMAL(5,2) DEFAULT NULL COMMENT '活性(百分比,0~100)' AFTER `expected_cell_count`;
|
||||
|
||||
-- 2. 更新 product_status 默认值和注释
|
||||
ALTER TABLE biz_cell_product
|
||||
MODIFY COLUMN `product_status` VARCHAR(16) DEFAULT 'frozen' COMMENT '状态: frozen已冻存/sold已售卖/used已使用';
|
||||
|
||||
-- 3. 迁移旧状态数据(如有)
|
||||
UPDATE biz_cell_product SET product_status = 'frozen' WHERE product_status = 'zk';
|
||||
UPDATE biz_cell_product SET product_status = 'sold' WHERE product_status = 'yc';
|
||||
UPDATE biz_cell_product SET product_status = 'used' WHERE product_status = 'ysy';
|
||||
@@ -1,168 +0,0 @@
|
||||
-- 细胞产品库初始化测试数据(20 条,覆盖各种场景)
|
||||
-- 日期: 2026-05-21
|
||||
-- 前提: 已执行 2026-05-21-cell-product-alter.sql 迁移
|
||||
|
||||
-- 场景覆盖:
|
||||
-- 状态: frozen(12条) / sold(5条) / used(3条)
|
||||
-- 代次: P1~P8 均有覆盖
|
||||
-- 活性: 70.0 ~ 99.5,含 NULL
|
||||
-- 预计细胞数量: 0.5 ~ 50.0 亿,含 NULL
|
||||
-- 冻存日期: 有值 / NULL / 未来日期
|
||||
-- 有效期: 已过期 / 未过期 / NULL
|
||||
-- 产品图片: 有值 / NULL
|
||||
-- 备注: 有值 / NULL
|
||||
-- 数量/单位: 1~100 份
|
||||
|
||||
INSERT INTO biz_cell_product
|
||||
(id, product_code, product_name, product_type_id, spec_id, batch_no, storage_slot_id,
|
||||
passage, freeze_date, expected_cell_count, viability,
|
||||
product_status, source_type, production_task_id,
|
||||
quantity, unit, expiry_date, product_images,
|
||||
tenant_no, order_num, remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag)
|
||||
VALUES
|
||||
|
||||
-- ==================== 已冻存 frozen (12条) ====================
|
||||
|
||||
-- 1. 典型冻存产品:高活性、P2代次、有图片有备注
|
||||
('60eaac11fceb4fd6b62e58e8be2c51cc', 'CP20260501000001', '间充质干细胞-MSC-P2-001', NULL, NULL, 'B20260501-001', NULL,
|
||||
'P2', '2026-05-01 10:30:00', 5.0000, 95.50,
|
||||
'frozen', 'manual', NULL,
|
||||
10, '份', '2027-05-01 00:00:00', 'https://minio.example.com/cell-product/msc-p2-001.jpg',
|
||||
'zkxw', 1, '高活性批次,来源于健康供体', 'admin', '', '2026-05-01 10:30:00', 'admin', '2026-05-01 10:30:00', 0),
|
||||
|
||||
-- 2. P1初代产品:数量大、高活性
|
||||
('5ea198fede454198be443211d2687ab3', 'CP20260502000001', '脐带血造血干细胞-HSC-P1-002', NULL, NULL, 'B20260502-002', NULL,
|
||||
'P1', '2026-05-02 14:20:00', 10.0000, 98.00,
|
||||
'frozen', 'manual', NULL,
|
||||
20, '份', '2027-11-02 00:00:00', NULL,
|
||||
'zkxw', 2, NULL, 'admin', '', '2026-05-02 14:20:00', 'admin', '2026-05-02 14:20:00', 0),
|
||||
|
||||
-- 3. P3代次、低活性、无冻存日期
|
||||
('661bcbadd41c4f478b16f3b9dd577914', 'CP20260503000001', '脂肪干细胞-ADSC-P3-003', NULL, NULL, 'B20260503-003', NULL,
|
||||
'P3', NULL, 3.0000, 72.00,
|
||||
'frozen', 'manual', NULL,
|
||||
5, '份', '2026-08-03 00:00:00', NULL,
|
||||
'zkxw', 3, '活性偏低,需进一步检测', 'admin', '', '2026-05-03 09:00:00', 'admin', '2026-05-03 09:00:00', 0),
|
||||
|
||||
-- 4. P4、中等活性、无预计细胞数量
|
||||
('dd8d414f36a244bca611a51a96581a85', 'CP20260505000001', '神经干细胞-NSC-P4-004', NULL, NULL, 'B20260505-004', NULL,
|
||||
'P4', '2026-05-05 08:15:00', NULL, 88.00,
|
||||
'frozen', 'manual', NULL,
|
||||
8, '份', '2027-05-05 00:00:00', 'https://minio.example.com/cell-product/nsc-p4-004.jpg',
|
||||
'zkxw', 4, NULL, 'admin', '', '2026-05-05 08:15:00', 'admin', '2026-05-05 08:15:00', 0),
|
||||
|
||||
-- 5. P5、活性为NULL(未检测)
|
||||
('815d5312900140c99e453c685c6d81a6', 'CP20260506000001', '诱导多能干细胞-iPSC-P5-005', NULL, NULL, 'B20260506-005', NULL,
|
||||
'P5', '2026-05-06 16:45:00', 2.5000, NULL,
|
||||
'frozen', 'manual', NULL,
|
||||
3, '份', '2027-02-06 00:00:00', NULL,
|
||||
'zkxw', 5, '待活性检测', 'admin', '', '2026-05-06 16:45:00', 'admin', '2026-05-06 16:45:00', 0),
|
||||
|
||||
-- 6. P6、大数量、有效期已过期(异常数据)
|
||||
('da9b6201f2a74921b475c234e0d72841', 'CP20260507000001', '软骨细胞-CC-P6-006', NULL, NULL, 'B20260507-006', NULL,
|
||||
'P6', '2026-05-07 11:00:00', 1.2000, 85.00,
|
||||
'frozen', 'manual', NULL,
|
||||
15, '份', '2025-05-07 00:00:00', NULL,
|
||||
'zkxw', 6, '有效期已过,需处理', 'admin', '', '2026-05-07 11:00:00', 'admin', '2026-05-07 11:00:00', 0),
|
||||
|
||||
-- 7. P7、极小数量、极高活性
|
||||
('e26ac18706b84c3da114f24eb50ec7e9', 'CP20260508000001', '心肌细胞-CM-P7-007', NULL, NULL, 'B20260508-007', NULL,
|
||||
'P7', '2026-05-08 09:30:00', 0.5000, 99.50,
|
||||
'frozen', 'manual', NULL,
|
||||
1, '份', '2027-11-08 00:00:00', NULL,
|
||||
'zkxw', 7, NULL, 'admin', '', '2026-05-08 09:30:00', 'admin', '2026-05-08 09:30:00', 0),
|
||||
|
||||
-- 8. P8、最大代次、多张图片
|
||||
('177e808ce4b8454cb074e5965ed94bb1', 'CP20260509000001', '肝细胞-HC-P8-008', NULL, NULL, 'B20260509-008', NULL,
|
||||
'P8', '2026-05-09 13:00:00', 8.0000, 80.00,
|
||||
'frozen', 'manual', NULL,
|
||||
12, '份', '2027-05-09 00:00:00', 'https://minio.example.com/cell-product/hc-p8-008a.jpg,https://minio.example.com/cell-product/hc-p8-008b.jpg',
|
||||
'zkxw', 8, '代次较高,建议尽快使用', 'admin', '', '2026-05-09 13:00:00', 'admin', '2026-05-09 13:00:00', 0),
|
||||
|
||||
-- 9. P1、大预计细胞数量50亿
|
||||
('0fe62984ef6c4d3eafa8bcff70c6e151', 'CP20260510000001', 'NK细胞-NK-P1-009', NULL, NULL, 'B20260510-009', NULL,
|
||||
'P1', '2026-05-10 07:00:00', 50.0000, 96.00,
|
||||
'frozen', 'manual', NULL,
|
||||
30, '份', '2027-11-10 00:00:00', 'https://minio.example.com/cell-product/nk-p1-009.jpg',
|
||||
'zkxw', 9, '大批次生产', 'admin', '', '2026-05-10 07:00:00', 'admin', '2026-05-10 07:00:00', 0),
|
||||
|
||||
-- 10. P3、无有效期
|
||||
('cb8e8ea1581348f18c119e1611fba39f', 'CP20260511000001', 'T细胞-TC-P3-010', NULL, NULL, 'B20260511-010', NULL,
|
||||
'P3', '2026-05-11 15:30:00', 15.0000, 91.00,
|
||||
'frozen', 'manual', NULL,
|
||||
25, '份', NULL, NULL,
|
||||
'zkxw', 10, NULL, 'admin', '', '2026-05-11 15:30:00', 'admin', '2026-05-11 15:30:00', 0),
|
||||
|
||||
-- 11. P2、活性偏低70%
|
||||
('28c6b50ccd3d4cf8ae9bbbbffef96418', 'CP20260512000001', '树突状细胞-DC-P2-011', NULL, NULL, 'B20260512-011', NULL,
|
||||
'P2', '2026-05-12 10:00:00', 4.0000, 70.00,
|
||||
'frozen', 'manual', NULL,
|
||||
6, '份', '2026-11-12 00:00:00', NULL,
|
||||
'zkxw', 11, '活性偏低,需复检', 'admin', '', '2026-05-12 10:00:00', 'admin', '2026-05-12 10:00:00', 0),
|
||||
|
||||
-- 12. P4、未来冻存日期(计划冻存)
|
||||
('940c82c006954865adb09e31fae36038', 'CP20260513000001', '表皮细胞-EC-P4-012', NULL, NULL, 'B20260513-012', NULL,
|
||||
'P4', '2026-06-15 00:00:00', 6.0000, 92.50,
|
||||
'frozen', 'manual', NULL,
|
||||
4, '份', '2027-06-15 00:00:00', NULL,
|
||||
'zkxw', 12, '计划冻存,待入库', 'admin', '', '2026-05-13 08:00:00', 'admin', '2026-05-13 08:00:00', 0),
|
||||
|
||||
-- ==================== 已售卖 sold (5条) ====================
|
||||
|
||||
-- 13. P2、已售卖、高活性
|
||||
('338ae843fb4a4914a1eb672fd7a5ee38', 'CP20260420000001', '间充质干细胞-MSC-P2-S01', NULL, NULL, 'B20260420-S01', NULL,
|
||||
'P2', '2026-04-20 09:00:00', 5.0000, 97.00,
|
||||
'sold', 'manual', NULL,
|
||||
10, '份', '2027-04-20 00:00:00', 'https://minio.example.com/cell-product/msc-p2-s01.jpg',
|
||||
'zkxw', 13, '已出售给合作医院', 'admin', '', '2026-04-20 09:00:00', 'admin', '2026-05-15 14:00:00', 0),
|
||||
|
||||
-- 14. P1、已售卖、最大批次
|
||||
('237d80589852465180706d1f7a3d3586', 'CP20260418000001', '脐带血造血干细胞-HSC-P1-S02', NULL, NULL, 'B20260418-S02', NULL,
|
||||
'P1', '2026-04-18 11:30:00', 20.0000, 99.00,
|
||||
'sold', 'manual', NULL,
|
||||
50, '份', '2027-10-18 00:00:00', NULL,
|
||||
'zkxw', 14, NULL, 'admin', '', '2026-04-18 11:30:00', 'admin', '2026-05-16 09:30:00', 0),
|
||||
|
||||
-- 15. P3、已售卖、中活性
|
||||
('a6380097234e4c15b04349f27348a9dd', 'CP20260415000001', '脂肪干细胞-ADSC-P3-S03', NULL, NULL, 'B20260415-S03', NULL,
|
||||
'P3', '2026-04-15 08:00:00', 8.0000, 88.50,
|
||||
'sold', 'manual', NULL,
|
||||
15, '份', '2027-04-15 00:00:00', 'https://minio.example.com/cell-product/adsc-p3-s03a.jpg,https://minio.example.com/cell-product/adsc-p3-s03b.jpg',
|
||||
'zkxw', 15, '科研合作项目使用', 'admin', '', '2026-04-15 08:00:00', 'admin', '2026-05-17 10:00:00', 0),
|
||||
|
||||
-- 16. P5、已售卖、低活性
|
||||
('853e0e67632c4291bf9d111a43a17b71', 'CP20260410000001', '神经干细胞-NSC-P5-S04', NULL, NULL, 'B20260410-S04', NULL,
|
||||
'P5', '2026-04-10 14:00:00', 2.0000, 75.00,
|
||||
'sold', 'manual', NULL,
|
||||
5, '份', '2026-10-10 00:00:00', NULL,
|
||||
'zkxw', 16, '低价出售,活性一般', 'admin', '', '2026-04-10 14:00:00', 'admin', '2026-05-18 11:00:00', 0),
|
||||
|
||||
-- 17. P1、已售卖、未填活性
|
||||
('ec5309d6870f486695cf5b5f63fd91d1', 'CP20260405000001', 'NK细胞-NK-P1-S05', NULL, NULL, 'B20260405-S05', NULL,
|
||||
'P1', '2026-04-05 10:00:00', 30.0000, NULL,
|
||||
'sold', 'manual', NULL,
|
||||
20, '份', '2027-10-05 00:00:00', NULL,
|
||||
'zkxw', 17, NULL, 'admin', '', '2026-04-05 10:00:00', 'admin', '2026-05-19 16:00:00', 0),
|
||||
|
||||
-- ==================== 已使用 used (3条) ====================
|
||||
|
||||
-- 18. P3、已使用(用于生产分化)
|
||||
('5e1f8cf0bab14e3f964d5a7aafb09d0d', 'CP20260301000001', '间充质干细胞-MSC-P3-U01', NULL, NULL, 'B20260301-U01', NULL,
|
||||
'P3', '2026-03-01 08:30:00', 10.0000, 93.00,
|
||||
'used', 'manual', NULL,
|
||||
8, '份', '2027-03-01 00:00:00', 'https://minio.example.com/cell-product/msc-p3-u01.jpg',
|
||||
'zkxw', 18, '用于生产分化为软骨细胞', 'admin', '', '2026-03-01 08:30:00', 'admin', '2026-05-10 09:00:00', 0),
|
||||
|
||||
-- 19. P4、已使用、来源生产任务
|
||||
('292c2ec830084ba08daf151845043dba', 'CP20260215000001', '诱导多能干细胞-iPSC-P4-U02', NULL, NULL, 'B20260215-U02', NULL,
|
||||
'P4', '2026-02-15 12:00:00', 12.0000, 90.00,
|
||||
'used', 'production', 'task-uuid-placeholder-001',
|
||||
6, '份', '2027-02-15 00:00:00', NULL,
|
||||
'zkxw', 19, '生产任务产出的细胞被用于后续分化实验', 'admin', '', '2026-02-15 12:00:00', 'admin', '2026-04-20 15:00:00', 0),
|
||||
|
||||
-- 20. P6、已使用、高代次低活性(极限场景)
|
||||
('e1cb9f8cbe6a40998686a8bb8fb76c9a', 'CP20260201000001', '肝细胞-HC-P6-U03', NULL, NULL, 'B20260201-U03', NULL,
|
||||
'P6', '2026-02-01 09:00:00', 1.5000, 78.50,
|
||||
'used', 'manual', NULL,
|
||||
2, '份', '2026-08-01 00:00:00', 'https://minio.example.com/cell-product/hc-p6-u03.jpg,https://minio.example.com/cell-product/hc-p6-u03-report.pdf',
|
||||
'zkxw', 20, '高代次细胞,已用于药物毒性测试', 'admin', '', '2026-02-01 09:00:00', 'admin', '2026-03-15 10:00:00', 0);
|
||||
@@ -1,37 +0,0 @@
|
||||
-- ============================================================
|
||||
-- 库位占用记录功能迁移
|
||||
-- 日期: 2026-05-22
|
||||
-- ============================================================
|
||||
|
||||
-- 1. 新增:库位占用记录表
|
||||
CREATE TABLE biz_storage_slot_occupancy (
|
||||
id VARCHAR(64) NOT NULL COMMENT '主键ID',
|
||||
slot_id VARCHAR(64) NOT NULL COMMENT '储物格ID (FK → biz_storage_facility_slot)',
|
||||
item_type VARCHAR(32) NOT NULL COMMENT '物品类型: cell_product=细胞产品, other=其他',
|
||||
item_id VARCHAR(64) NOT NULL COMMENT '物品ID (指向对应业务表主键)',
|
||||
item_code VARCHAR(64) NULL COMMENT '物品编码 (冗余展示)',
|
||||
item_name VARCHAR(200) NULL COMMENT '物品名称 (冗余展示)',
|
||||
item_source VARCHAR(32) NULL COMMENT '来源: production=生产入库, manual=手动入库, transfer=转移',
|
||||
stored_at DATETIME NULL COMMENT '入库时间',
|
||||
removed_at DATETIME NULL COMMENT '出库时间 (NULL=当前在库)',
|
||||
occupancy_status VARCHAR(16) NOT NULL DEFAULT 'stored' COMMENT 'stored=在库, removed=已出库',
|
||||
tenant_no VARCHAR(64) NULL COMMENT '租户编号',
|
||||
order_num INT DEFAULT 0 COMMENT '排序',
|
||||
remark VARCHAR(500) NULL COMMENT '备注',
|
||||
create_by VARCHAR(64) NULL COMMENT '创建者',
|
||||
create_dept_id VARCHAR(64) NULL COMMENT '创建部门',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_by VARCHAR(64) NULL COMMENT '更新者',
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
del_flag CHAR(1) DEFAULT '0' COMMENT '删除标志(0存在 1删除)',
|
||||
PRIMARY KEY (id),
|
||||
INDEX idx_sso_slot (slot_id, occupancy_status, del_flag),
|
||||
INDEX idx_sso_item (item_type, item_id, del_flag),
|
||||
INDEX idx_sso_tenant (tenant_no, del_flag)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='库位占用记录表';
|
||||
|
||||
-- 2. 增强:biz_storage_facility_slot 增加缓存字段
|
||||
ALTER TABLE biz_storage_facility_slot
|
||||
ADD COLUMN occupied_count INT DEFAULT 0 COMMENT '当前占用数量',
|
||||
ADD COLUMN last_item_type VARCHAR(32) NULL COMMENT '最近存储物品类型',
|
||||
ADD COLUMN last_stored_at DATETIME NULL COMMENT '最近入库时间';
|
||||
@@ -1,51 +0,0 @@
|
||||
-- ============================================================
|
||||
-- 入库放行审核 biz_storage_release_review
|
||||
-- Date: 2026-05-23
|
||||
-- ============================================================
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for biz_storage_release_review
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `biz_storage_release_review`;
|
||||
CREATE TABLE `biz_storage_release_review` (
|
||||
`id` VARCHAR(64) NOT NULL COMMENT '主键ID',
|
||||
`sample_code` VARCHAR(64) NOT NULL COMMENT '样本编码(关联键)',
|
||||
`reception_source` VARCHAR(32) NOT NULL COMMENT '来源:cell_storage=采集/research_donation=捐赠',
|
||||
`protocol_id` VARCHAR(64) DEFAULT NULL COMMENT '协议单ID',
|
||||
`reception_id` VARCHAR(64) DEFAULT NULL COMMENT '样本接收记录ID',
|
||||
`protocol_no` VARCHAR(64) DEFAULT NULL COMMENT '协议编号',
|
||||
`sample_name` VARCHAR(128) DEFAULT NULL COMMENT '样本名称',
|
||||
`review_conclusion` VARCHAR(16) DEFAULT NULL COMMENT '审核结论:tg=通过/btg=不通过/NULL=待审核',
|
||||
`review_remark` VARCHAR(512) DEFAULT NULL COMMENT '审核备注',
|
||||
`review_attachments` VARCHAR(4000) DEFAULT NULL COMMENT '审核附件(逗号分隔URL)',
|
||||
`review_by` VARCHAR(64) DEFAULT NULL COMMENT '审核人ID',
|
||||
`review_by_name` VARCHAR(64) DEFAULT NULL COMMENT '审核人姓名',
|
||||
`review_time` DATETIME DEFAULT NULL COMMENT '审核时间',
|
||||
`storage_status` VARCHAR(16) NOT NULL DEFAULT 'drk' COMMENT '入库状态:drk=待入库/yrk=已入库',
|
||||
`storage_by` VARCHAR(64) DEFAULT NULL COMMENT '入库操作人ID',
|
||||
`storage_by_name` VARCHAR(64) DEFAULT NULL COMMENT '入库操作人姓名',
|
||||
`storage_time` DATETIME DEFAULT NULL COMMENT '入库时间',
|
||||
`tenant_no` VARCHAR(64) NOT NULL DEFAULT '' 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_srr_sample` (`tenant_no`, `sample_code`, `del_flag`),
|
||||
KEY `idx_srr_protocol` (`tenant_no`, `protocol_id`, `del_flag`),
|
||||
KEY `idx_srr_status` (`tenant_no`, `review_conclusion`, `storage_status`, `del_flag`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='入库放行审核';
|
||||
|
||||
-- ----------------------------
|
||||
-- Menu entry: 入库放行审核 (under 质量检测)
|
||||
-- ----------------------------
|
||||
-- 父菜单: 质量检测 id=70000000000000000000000000000001
|
||||
-- 新菜单 ID: 70000000000000000000000000000011 (递增)
|
||||
INSERT INTO `sys_menu` (`id`, `menu_name`, `parent_id`, `menu_type`, `path`, `component`, `perms`, `is_frame`, `visible`, `status`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`)
|
||||
VALUES ('70000000000000000000000000000011', '入库放行审核', '70000000000000000000000000000001', 'C', 'storage-release-review', '/quality-inspection/storage-release-review/index', 'biz:storageReleaseReview:list', 1, '1', '1', 'zkxw', 10, NULL, NULL, '', NOW(), NULL, NOW(), 0);
|
||||
@@ -1,91 +0,0 @@
|
||||
-- 快递公司初始化(仅国内)
|
||||
-- 用法:
|
||||
-- 1) 默认租户为 zkxw,如需其他租户请修改 @tenant_no
|
||||
-- 2) 可重复执行:按 tenant_no + express_code + del_flag=0 去重插入
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
SET @tenant_no = 'zkxw';
|
||||
SET @operator_id = 'd3000000000000000000000000000001';
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp_express_company_seed;
|
||||
CREATE TEMPORARY TABLE tmp_express_company_seed (
|
||||
express_code varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
express_name varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
order_num int(11) DEFAULT NULL,
|
||||
remark varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL
|
||||
) ENGINE=Memory DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
INSERT INTO tmp_express_company_seed (express_code, express_name, order_num, remark) VALUES
|
||||
('sf', '顺丰速运', 1, '国内主流快递'),
|
||||
('jd', '京东快递', 2, '国内主流快递'),
|
||||
('zt', '中通快递', 3, '国内主流快递'),
|
||||
('yt', '圆通速递', 4, '国内主流快递'),
|
||||
('sto', '申通快递', 5, '国内主流快递'),
|
||||
('yunda', '韵达速递', 6, '国内主流快递'),
|
||||
('deppon', '德邦快递', 7, '国内主流快递'),
|
||||
('ems', 'EMS中国邮政速递物流', 8, '国家邮政体系'),
|
||||
('youzheng', '中国邮政', 9, '邮政包裹/普邮'),
|
||||
('jtexpress', '极兔速递', 10, '国内主流快递'),
|
||||
('zjs', '宅急送', 11, '国内常见快递'),
|
||||
('anneng', '安能物流', 12, '零担/大件常见'),
|
||||
('suning', '苏宁物流', 13, '电商体系物流'),
|
||||
('best', '百世快递', 14, '原百世快递体系'),
|
||||
('tiantian', '天天快递', 15, '历史常见渠道'),
|
||||
('guotong', '国通快递', 16, '历史常见渠道'),
|
||||
('quanfen', '全峰快递', 17, '历史常见渠道'),
|
||||
('rufengda', '如风达', 18, '历史常见渠道'),
|
||||
('kuaijie', '快捷快递', 19, '历史常见渠道'),
|
||||
('huitong', '汇通快运', 20, '区域快运常见'),
|
||||
('yousu', '优速快递', 21, '国内常见快递'),
|
||||
('suer', '速尔快递', 22, '国内常见快递'),
|
||||
('ky', '跨越速运', 23, '企业件/时效件常见'),
|
||||
('ymdd', '壹米滴答', 24, '零担快运常见'),
|
||||
('longbang', '龙邦快递', 25, '国内常见快递');
|
||||
|
||||
INSERT INTO biz_express_company (
|
||||
id,
|
||||
express_code,
|
||||
express_name,
|
||||
tenant_no,
|
||||
order_num,
|
||||
remark,
|
||||
create_by,
|
||||
create_dept_id,
|
||||
create_time,
|
||||
update_by,
|
||||
update_time,
|
||||
del_flag
|
||||
)
|
||||
SELECT
|
||||
CONCAT(
|
||||
REPLACE(UUID(), '-', ''),
|
||||
LPAD(CONV(CRC32(t.express_code), 10, 16), 8, '0')
|
||||
),
|
||||
t.express_code,
|
||||
t.express_name,
|
||||
@tenant_no,
|
||||
t.order_num,
|
||||
t.remark,
|
||||
@operator_id,
|
||||
'',
|
||||
NOW(),
|
||||
@operator_id,
|
||||
NOW(),
|
||||
0
|
||||
FROM tmp_express_company_seed t
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM biz_express_company e
|
||||
WHERE e.tenant_no COLLATE utf8mb4_unicode_ci = @tenant_no COLLATE utf8mb4_unicode_ci
|
||||
AND e.express_code COLLATE utf8mb4_unicode_ci = t.express_code COLLATE utf8mb4_unicode_ci
|
||||
AND e.del_flag = 0
|
||||
);
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp_express_company_seed;
|
||||
|
||||
COMMIT;
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
@@ -1,3 +0,0 @@
|
||||
-- 市场物料库:增加预警库存字段(与质检物料库 biz_qc_material.warning_qty 对齐)
|
||||
ALTER TABLE `biz_material`
|
||||
ADD COLUMN `warning_qty` decimal(18, 4) NOT NULL DEFAULT 0 COMMENT '预警库存量' AFTER `stock_qty`;
|
||||
@@ -1,80 +0,0 @@
|
||||
-- ============================================================
|
||||
-- 生产物料库存管理 - 数据库迁移脚本
|
||||
-- 变更: production-material-inventory
|
||||
-- ============================================================
|
||||
|
||||
-- 1. biz_consumable 新增库存字段
|
||||
ALTER TABLE `biz_consumable`
|
||||
ADD COLUMN `stock_qty` DECIMAL(18,4) NOT NULL DEFAULT 0.0000 COMMENT '当前库存量' AFTER `description`,
|
||||
ADD COLUMN `warning_qty` DECIMAL(18,4) NOT NULL DEFAULT 0.0000 COMMENT '预警库存量' AFTER `stock_qty`,
|
||||
ADD COLUMN `status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '1-启用 0-停用' AFTER `warning_qty`;
|
||||
|
||||
-- 2. biz_reagent 新增库存字段
|
||||
ALTER TABLE `biz_reagent`
|
||||
ADD COLUMN `stock_qty` DECIMAL(18,4) NOT NULL DEFAULT 0.0000 COMMENT '当前库存量' AFTER `description`,
|
||||
ADD COLUMN `warning_qty` DECIMAL(18,4) NOT NULL DEFAULT 0.0000 COMMENT '预警库存量' AFTER `stock_qty`,
|
||||
ADD COLUMN `status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '1-启用 0-停用' AFTER `warning_qty`;
|
||||
|
||||
-- 3. 耗材变动记录表
|
||||
CREATE TABLE `biz_consumable_stock_log` (
|
||||
`id` VARCHAR(64) NOT NULL COMMENT '主键ID',
|
||||
`material_id` VARCHAR(64) NOT NULL COMMENT '耗材ID',
|
||||
`material_code` VARCHAR(64) DEFAULT NULL COMMENT '耗材编码快照',
|
||||
`material_name` VARCHAR(200) DEFAULT NULL COMMENT '耗材名称快照',
|
||||
`change_type` VARCHAR(16) NOT NULL COMMENT '变动类型:in入库 / use使用出库',
|
||||
`change_qty` DECIMAL(18,4) NOT NULL COMMENT '变动数量(入库正数,出库负数)',
|
||||
`stock_before` DECIMAL(18,4) NOT NULL COMMENT '变动前库存',
|
||||
`stock_after` DECIMAL(18,4) NOT NULL COMMENT '变动后库存',
|
||||
`source_type` VARCHAR(16) NOT NULL COMMENT '来源:manual_in / manual_out / step_save',
|
||||
`step_id` VARCHAR(64) DEFAULT NULL COMMENT '生产任务步骤ID(step_save时有值)',
|
||||
`task_id` VARCHAR(64) DEFAULT NULL COMMENT '生产任务ID(step_save时有值)',
|
||||
`task_no` VARCHAR(32) DEFAULT NULL COMMENT '生产任务编号快照',
|
||||
`receiver` VARCHAR(64) DEFAULT NULL COMMENT '领用人(手动出库时)',
|
||||
`purpose` VARCHAR(512) DEFAULT NULL COMMENT '用途/事由(手动出库时)',
|
||||
`tenant_no` VARCHAR(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
|
||||
`remark` VARCHAR(512) DEFAULT NULL COMMENT '备注',
|
||||
`create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人id',
|
||||
`create_dept_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建人部门ID',
|
||||
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人id',
|
||||
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` SMALLINT NOT NULL DEFAULT 0 COMMENT '删除标记',
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `idx_csl_material` (`material_id`, `del_flag`),
|
||||
INDEX `idx_csl_step` (`step_id`, `del_flag`),
|
||||
INDEX `idx_csl_task` (`task_id`, `del_flag`),
|
||||
INDEX `idx_csl_tenant_time` (`tenant_no`, `change_type`, `create_time`),
|
||||
INDEX `idx_csl_source` (`source_type`, `del_flag`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='耗材变动记录';
|
||||
|
||||
-- 4. 试剂变动记录表
|
||||
CREATE TABLE `biz_reagent_stock_log` (
|
||||
`id` VARCHAR(64) NOT NULL COMMENT '主键ID',
|
||||
`material_id` VARCHAR(64) NOT NULL COMMENT '试剂ID',
|
||||
`material_code` VARCHAR(64) DEFAULT NULL COMMENT '试剂编码快照',
|
||||
`material_name` VARCHAR(200) DEFAULT NULL COMMENT '试剂名称快照',
|
||||
`change_type` VARCHAR(16) NOT NULL COMMENT '变动类型:in入库 / use使用出库',
|
||||
`change_qty` DECIMAL(18,4) NOT NULL COMMENT '变动数量(入库正数,出库负数)',
|
||||
`stock_before` DECIMAL(18,4) NOT NULL COMMENT '变动前库存',
|
||||
`stock_after` DECIMAL(18,4) NOT NULL COMMENT '变动后库存',
|
||||
`source_type` VARCHAR(16) NOT NULL COMMENT '来源:manual_in / manual_out / step_save',
|
||||
`step_id` VARCHAR(64) DEFAULT NULL COMMENT '生产任务步骤ID(step_save时有值)',
|
||||
`task_id` VARCHAR(64) DEFAULT NULL COMMENT '生产任务ID(step_save时有值)',
|
||||
`task_no` VARCHAR(32) DEFAULT NULL COMMENT '生产任务编号快照',
|
||||
`receiver` VARCHAR(64) DEFAULT NULL COMMENT '领用人(手动出库时)',
|
||||
`purpose` VARCHAR(512) DEFAULT NULL COMMENT '用途/事由(手动出库时)',
|
||||
`tenant_no` VARCHAR(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
|
||||
`remark` VARCHAR(512) DEFAULT NULL COMMENT '备注',
|
||||
`create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人id',
|
||||
`create_dept_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建人部门ID',
|
||||
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人id',
|
||||
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`del_flag` SMALLINT NOT NULL DEFAULT 0 COMMENT '删除标记',
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `idx_rsl_material` (`material_id`, `del_flag`),
|
||||
INDEX `idx_rsl_step` (`step_id`, `del_flag`),
|
||||
INDEX `idx_rsl_task` (`task_id`, `del_flag`),
|
||||
INDEX `idx_rsl_tenant_time` (`tenant_no`, `change_type`, `create_time`),
|
||||
INDEX `idx_rsl_source` (`source_type`, `del_flag`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='试剂变动记录';
|
||||
@@ -1,5 +0,0 @@
|
||||
-- 生产任务表增加任务类型字段
|
||||
-- 区分入库生产单 (cell_storage) / 出库生产单 (outbound)
|
||||
ALTER TABLE biz_production_task
|
||||
ADD COLUMN task_type VARCHAR(20) NOT NULL DEFAULT 'cell_storage' COMMENT '任务类型 cell_storage入库生产单 outbound出库生产单'
|
||||
AFTER work_order_id;
|
||||
@@ -1,109 +0,0 @@
|
||||
-- 质检物料库测试数据(biz_qc_material / biz_qc_material_usage)
|
||||
--
|
||||
-- 用法:
|
||||
-- 1) 默认租户 zkxw,默认操作人 d3000000000000000000000000000001(与 zkxw.sql 演示账号一致)
|
||||
-- 2) 可重复执行:按物料编码前缀 QC-MAT-DEMO- 清理后重新插入
|
||||
-- 3) 执行前请确认已建表(见 docs/superpowers/plans/2026-05-20-qc-material-library.md 中 DDL)
|
||||
--
|
||||
-- 示例:
|
||||
-- mysql -u root -p zkxw < docs/sql/qc_material_demo_seed.sql
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
SET @tenant_no = 'zkxw';
|
||||
SET @operator_id = 'd3000000000000000000000000000001';
|
||||
SET @now = NOW();
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
-- 清理旧测试数据(先删变动记录,再删物料)
|
||||
DELETE u
|
||||
FROM `biz_qc_material_usage` u
|
||||
INNER JOIN `biz_qc_material` m ON m.`id` = u.`material_id`
|
||||
WHERE m.`tenant_no` = @tenant_no
|
||||
AND m.`material_code` LIKE 'QC-MAT-DEMO-%';
|
||||
|
||||
DELETE FROM `biz_qc_material`
|
||||
WHERE `tenant_no` = @tenant_no
|
||||
AND `material_code` LIKE 'QC-MAT-DEMO-%';
|
||||
|
||||
-- ----------------------------
|
||||
-- 质检物料主数据(10 条)
|
||||
-- 覆盖:正常库存 / 库存预警 / 零库存 / 停用
|
||||
-- ----------------------------
|
||||
INSERT INTO `biz_qc_material` (
|
||||
`id`,
|
||||
`material_code`,
|
||||
`material_name`,
|
||||
`spec_model`,
|
||||
`unit`,
|
||||
`stock_qty`,
|
||||
`warning_qty`,
|
||||
`status`,
|
||||
`tenant_no`,
|
||||
`order_num`,
|
||||
`remark`,
|
||||
`create_by`,
|
||||
`create_dept_id`,
|
||||
`create_time`,
|
||||
`update_by`,
|
||||
`update_time`,
|
||||
`del_flag`
|
||||
) VALUES
|
||||
('q1000000000000000000000000000001', 'QC-MAT-DEMO-001', 'PCR 扩增引物 Mix', '20× 预混', '支', 120.0000, 50.0000, '1', @tenant_no, 1, '常温避光', @operator_id, '', @now, @operator_id, @now, 0),
|
||||
('q1000000000000000000000000000002', 'QC-MAT-DEMO-002', '核酸提取试剂盒', '96 孔板适用', '盒', 35.0000, 40.0000, '1', @tenant_no, 2, '库存低于预警线', @operator_id, '', @now, @operator_id, @now, 0),
|
||||
('q1000000000000000000000000000003', 'QC-MAT-DEMO-003', '琼脂糖', 'Bio-Rad 常规型', 'g', 8.0000, 10.0000, '1', @tenant_no, 3, '粉末,干燥保存', @operator_id, '', @now, @operator_id, @now, 0),
|
||||
('q1000000000000000000000000000004', 'QC-MAT-DEMO-004', 'TAE 电泳缓冲液', '50× 浓缩', '瓶', 200.0000, 30.0000, '1', @tenant_no, 4, NULL, @operator_id, '', @now, @operator_id, @now, 0),
|
||||
('q1000000000000000000000000000005', 'QC-MAT-DEMO-005', '无菌吸头', '200μL 滤芯', '盒', 5000.0000, 500.0000, '1', @tenant_no, 5, '每盒 96 支', @operator_id, '', @now, @operator_id, @now, 0),
|
||||
('q1000000000000000000000000000006', 'QC-MAT-DEMO-006', 'EP 离心管', '1.5mL 锥底', '包', 3000.0000, 200.0000, '1', @tenant_no, 6, '每包 500 支', @operator_id, '', @now, @operator_id, @now, 0),
|
||||
('q1000000000000000000000000000007', 'QC-MAT-DEMO-007', '医用丁腈手套', 'M 码 无粉', '盒', 150.0000, 50.0000, '1', @tenant_no, 7, '每盒 100 只', @operator_id, '', @now, @operator_id, @now, 0),
|
||||
('q1000000000000000000000000000008', 'QC-MAT-DEMO-008', '75% 乙醇消毒液', '500ml 喷雾', '瓶', 0.0000, 20.0000, '1', @tenant_no, 8, '零库存,可测入库', @operator_id, '', @now, @operator_id, @now, 0),
|
||||
('q1000000000000000000000000000009', 'QC-MAT-DEMO-009', '质检标准品', '冻干粉 1mg', '支', 25.0000, 10.0000, '1', @tenant_no, 9, '-20℃ 保存', @operator_id, '', @now, @operator_id, @now, 0),
|
||||
('q1000000000000000000000000000010', 'QC-MAT-DEMO-010', '细胞培养基(旧批次)', '500ml', '瓶', 15.0000, 5.0000, '0', @tenant_no, 10, '停用批次,仅保留档案', @operator_id, '', @now, @operator_id, @now, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- 物料变动记录(3 条,便于「物料变动记录」页联调)
|
||||
-- change_type: in=入库 / use=使用;source_type: manual_in / task_complete
|
||||
-- ----------------------------
|
||||
INSERT INTO `biz_qc_material_usage` (
|
||||
`id`,
|
||||
`material_id`,
|
||||
`material_code`,
|
||||
`material_name`,
|
||||
`change_type`,
|
||||
`change_qty`,
|
||||
`stock_after`,
|
||||
`qc_task_id`,
|
||||
`qc_task_no`,
|
||||
`source_type`,
|
||||
`tenant_no`,
|
||||
`remark`,
|
||||
`create_by`,
|
||||
`create_dept_id`,
|
||||
`create_time`,
|
||||
`update_by`,
|
||||
`update_time`,
|
||||
`del_flag`
|
||||
) VALUES
|
||||
('qu100000000000000000000000000001', 'q1000000000000000000000000000001', 'QC-MAT-DEMO-001', 'PCR 扩增引物 Mix', 'in', 50.0000, 70.0000, NULL, NULL, 'manual_in', @tenant_no, '期初入库', @operator_id, '', DATE_SUB(@now, INTERVAL 7 DAY), @operator_id, DATE_SUB(@now, INTERVAL 7 DAY), 0),
|
||||
('qu100000000000000000000000000002', 'q1000000000000000000000000000001', 'QC-MAT-DEMO-001', 'PCR 扩增引物 Mix', 'in', 50.0000, 120.0000, NULL, NULL, 'manual_in', @tenant_no, '补货入库', @operator_id, '', DATE_SUB(@now, INTERVAL 2 DAY), @operator_id, DATE_SUB(@now, INTERVAL 2 DAY), 0),
|
||||
('qu100000000000000000000000000003', 'q1000000000000000000000000000002', 'QC-MAT-DEMO-002', '核酸提取试剂盒', 'use', -5.0000, 35.0000, NULL, 'QC-DEMO-TASK-001', 'task_complete', @tenant_no, '演示任务消耗', @operator_id, '', DATE_SUB(@now, INTERVAL 1 DAY), @operator_id, DATE_SUB(@now, INTERVAL 1 DAY), 0);
|
||||
|
||||
COMMIT;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
-- 插入结果速览
|
||||
SELECT
|
||||
material_code AS `物料编码`,
|
||||
material_name AS `物料名称`,
|
||||
stock_qty AS `当前库存`,
|
||||
warning_qty AS `预警库存`,
|
||||
CASE WHEN status = '1' THEN '正常' ELSE '停用' END AS `状态`,
|
||||
CASE WHEN stock_qty <= warning_qty THEN '库存预警' ELSE '正常' END AS `库存状态`
|
||||
FROM `biz_qc_material`
|
||||
WHERE `tenant_no` = @tenant_no
|
||||
AND `material_code` LIKE 'QC-MAT-DEMO-%'
|
||||
AND `del_flag` = 0
|
||||
ORDER BY `order_num`;
|
||||
@@ -1,33 +0,0 @@
|
||||
-- 质检物料变动记录:出库领用人/用途独立字段,来源类型补充 manual_out
|
||||
-- 用法:mysql -u root -p zkxw < docs/sql/qc_material_usage_out_fields_alter.sql
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
ALTER TABLE `biz_qc_material_usage`
|
||||
ADD COLUMN `receiver` varchar(64) DEFAULT NULL COMMENT '领用人(手动出库)' AFTER `qc_task_no`,
|
||||
ADD COLUMN `purpose` varchar(512) DEFAULT NULL COMMENT '用途/事由(手动出库)' AFTER `receiver`;
|
||||
|
||||
ALTER TABLE `biz_qc_material_usage`
|
||||
MODIFY COLUMN `source_type` varchar(16) NOT NULL COMMENT '来源:task_complete任务完成 / manual_in手动入库 / manual_out手动出库';
|
||||
|
||||
-- 历史数据:从备注中回填领用人、用途(格式:领用人:xxx;用途:yyy)
|
||||
UPDATE `biz_qc_material_usage`
|
||||
SET
|
||||
`receiver` = TRIM(
|
||||
SUBSTRING_INDEX(
|
||||
SUBSTRING_INDEX(`remark`, '领用人:', -1),
|
||||
';',
|
||||
1
|
||||
)
|
||||
),
|
||||
`purpose` = TRIM(
|
||||
SUBSTRING_INDEX(
|
||||
SUBSTRING_INDEX(`remark`, '用途:', -1),
|
||||
';',
|
||||
1
|
||||
)
|
||||
)
|
||||
WHERE `source_type` = 'manual_out'
|
||||
AND `del_flag` = 0
|
||||
AND (`receiver` IS NULL OR `receiver` = '')
|
||||
AND `remark` LIKE '%领用人:%';
|
||||
@@ -1,25 +0,0 @@
|
||||
-- 回填手动出库记录的领用人、用途(从 remark 解析,可重复执行)
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
UPDATE `biz_qc_material_usage`
|
||||
SET
|
||||
`receiver` = TRIM(
|
||||
SUBSTRING_INDEX(
|
||||
SUBSTRING_INDEX(`remark`, '领用人:', -1),
|
||||
';',
|
||||
1
|
||||
)
|
||||
),
|
||||
`purpose` = TRIM(
|
||||
SUBSTRING_INDEX(
|
||||
SUBSTRING_INDEX(`remark`, '用途:', -1),
|
||||
';',
|
||||
1
|
||||
)
|
||||
)
|
||||
WHERE `source_type` = 'manual_out'
|
||||
AND `del_flag` = 0
|
||||
AND `remark` LIKE '%领用人:%'
|
||||
AND (
|
||||
`receiver` IS NULL OR `receiver` = '' OR `purpose` IS NULL OR `purpose` = ''
|
||||
);
|
||||
@@ -1,18 +0,0 @@
|
||||
-- 细胞存储管理:菜单更名
|
||||
-- 物料库 → 市场物料库(id=50000000000000000000000000000009)
|
||||
-- 物料变动记录 → 市场物料变动记录(id=50000000000000000000000000000010)
|
||||
-- 用法:mysql -u root -p zkxw < docs/sql/sys_menu_cell_storage_material_rename.sql
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
UPDATE `sys_menu`
|
||||
SET `menu_name` = '市场物料库',
|
||||
`update_time` = NOW()
|
||||
WHERE `id` = '50000000000000000000000000000009'
|
||||
AND `del_flag` = 0;
|
||||
|
||||
UPDATE `sys_menu`
|
||||
SET `menu_name` = '市场物料变动记录',
|
||||
`update_time` = NOW()
|
||||
WHERE `id` = '50000000000000000000000000000010'
|
||||
AND `del_flag` = 0;
|
||||
@@ -1,10 +0,0 @@
|
||||
-- 质量检测:菜单「物料变动记录」更名为「质检物料变动记录」
|
||||
-- 用法:mysql -u root -p zkxw < docs/sql/sys_menu_qc_material_usage_rename.sql
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
UPDATE `sys_menu`
|
||||
SET `menu_name` = '质检物料变动记录',
|
||||
`update_time` = NOW()
|
||||
WHERE `id` = '70000000000000000000000000000010'
|
||||
AND `del_flag` = 0;
|
||||
+3664
-1161
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -4130,6 +4130,90 @@
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L303"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchreagentstockin",
|
||||
"label": "fetchReagentStockIn()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L311"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchreagentstockout",
|
||||
"label": "fetchReagentStockOut()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L315"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchreagentbatchstockin",
|
||||
"label": "fetchReagentBatchStockIn()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L322"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchreagentbatchstockout",
|
||||
"label": "fetchReagentBatchStockOut()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L329"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchreagentstocklogs",
|
||||
"label": "fetchReagentStockLogs()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L338"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchallreagentstocklogs",
|
||||
"label": "fetchAllReagentStockLogs()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L350"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchconsumablestockin",
|
||||
"label": "fetchConsumableStockIn()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L370"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchconsumablestockout",
|
||||
"label": "fetchConsumableStockOut()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L374"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchconsumablebatchstockin",
|
||||
"label": "fetchConsumableBatchStockIn()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L381"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchconsumablebatchstockout",
|
||||
"label": "fetchConsumableBatchStockOut()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L388"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchconsumablestocklogs",
|
||||
"label": "fetchConsumableStockLogs()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L397"
|
||||
},
|
||||
{
|
||||
"id": "api_production_fetchallconsumablestocklogs",
|
||||
"label": "fetchAllConsumableStockLogs()",
|
||||
"file_type": "code",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L409"
|
||||
},
|
||||
{
|
||||
"id": "api_qc_third_party_item_ts",
|
||||
"label": "qc-third-party-item.ts",
|
||||
@@ -17987,6 +18071,114 @@
|
||||
"source_location": "L303",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchreagentstockin",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L311",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchreagentstockout",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L315",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchreagentbatchstockin",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L322",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchreagentbatchstockout",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L329",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchreagentstocklogs",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L338",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchallreagentstocklogs",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L350",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchconsumablestockin",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L370",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchconsumablestockout",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L374",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchconsumablebatchstockin",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L381",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchconsumablebatchstockout",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L388",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchconsumablestocklogs",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L397",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_ts",
|
||||
"target": "api_production_fetchallconsumablestocklogs",
|
||||
"relation": "contains",
|
||||
"confidence": "EXTRACTED",
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L409",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_qc_third_party_item_ts",
|
||||
"target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_http",
|
||||
@@ -29017,6 +29209,46 @@
|
||||
"source_location": "L250",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_fetchreagentstocklogs",
|
||||
"target": "process_route_index_get",
|
||||
"relation": "calls",
|
||||
"confidence": "INFERRED",
|
||||
"confidence_score": 0.8,
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L342",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_fetchallreagentstocklogs",
|
||||
"target": "process_route_index_get",
|
||||
"relation": "calls",
|
||||
"confidence": "INFERRED",
|
||||
"confidence_score": 0.8,
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L358",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_fetchconsumablestocklogs",
|
||||
"target": "process_route_index_get",
|
||||
"relation": "calls",
|
||||
"confidence": "INFERRED",
|
||||
"confidence_score": 0.8,
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L401",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_production_fetchallconsumablestocklogs",
|
||||
"target": "process_route_index_get",
|
||||
"relation": "calls",
|
||||
"confidence": "INFERRED",
|
||||
"confidence_score": 0.8,
|
||||
"source_file": "api/production.ts",
|
||||
"source_location": "L417",
|
||||
"weight": 1.0
|
||||
},
|
||||
{
|
||||
"source": "api_qc_third_party_item_fetchqcthirdpartyitemlist",
|
||||
"target": "process_route_index_get",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Graph Report - src (2026-05-23)
|
||||
|
||||
## Corpus Check
|
||||
- Large corpus: 588 files · ~312,880 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
|
||||
- Large corpus: 588 files · ~319,039 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
|
||||
|
||||
## Summary
|
||||
- 1461 nodes · 1826 edges · 42 communities detected
|
||||
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 406 edges (avg confidence: 0.8)
|
||||
- 1473 nodes · 1842 edges · 41 communities detected
|
||||
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 410 edges (avg confidence: 0.8)
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Community Hubs (Navigation)
|
||||
@@ -32,7 +32,7 @@
|
||||
- [[_COMMUNITY_Community 20|Community 20]]
|
||||
- [[_COMMUNITY_Community 21|Community 21]]
|
||||
- [[_COMMUNITY_Community 22|Community 22]]
|
||||
- [[_COMMUNITY_Community 24|Community 24]]
|
||||
- [[_COMMUNITY_Community 23|Community 23]]
|
||||
- [[_COMMUNITY_Community 25|Community 25]]
|
||||
- [[_COMMUNITY_Community 26|Community 26]]
|
||||
- [[_COMMUNITY_Community 27|Community 27]]
|
||||
@@ -45,15 +45,14 @@
|
||||
- [[_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 40|Community 40]]
|
||||
- [[_COMMUNITY_Community 41|Community 41]]
|
||||
- [[_COMMUNITY_Community 42|Community 42]]
|
||||
- [[_COMMUNITY_Community 43|Community 43]]
|
||||
- [[_COMMUNITY_Community 45|Community 45]]
|
||||
- [[_COMMUNITY_Community 44|Community 44]]
|
||||
|
||||
## God Nodes (most connected - your core abstractions)
|
||||
1. `get()` - 157 edges
|
||||
1. `get()` - 161 edges
|
||||
2. `WebSocketClient` - 26 edges
|
||||
3. `push()` - 19 edges
|
||||
4. `withFullscreenLoading()` - 17 edges
|
||||
@@ -67,116 +66,116 @@
|
||||
## Surprising Connections (you probably didn't know these)
|
||||
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
|
||||
views/system/site/index.vue → utils/fullscreen-loading.ts
|
||||
- `handleBatchDeleteHospital()` --calls--> `withFullscreenLoading()` [INFERRED]
|
||||
views/basic-info/collection-region/index.vue → utils/fullscreen-loading.ts
|
||||
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
|
||||
views/basic-info/customer/index.vue → utils/fullscreen-loading.ts
|
||||
- `handleUnauthorizedResponse()` --calls--> `fetchRefreshToken()` [INFERRED]
|
||||
utils/http/index.ts → api/auth.ts
|
||||
- `fetchLeaveList()` --calls--> `get()` [INFERRED]
|
||||
api/leave.ts → views/production/process-route/index.vue
|
||||
- `fetchLeaveDetail()` --calls--> `get()` [INFERRED]
|
||||
api/leave.ts → views/production/process-route/index.vue
|
||||
- `fetchSampleReceptionCheckItemList()` --calls--> `get()` [INFERRED]
|
||||
api/sample-reception-check-item.ts → views/production/process-route/index.vue
|
||||
- `fetchSampleReceptionCheckItemsActive()` --calls--> `get()` [INFERRED]
|
||||
api/sample-reception-check-item.ts → views/production/process-route/index.vue
|
||||
|
||||
## Communities
|
||||
|
||||
### Community 0 - "Community 0"
|
||||
Cohesion: 0.01
|
||||
Nodes (78): fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchCellSampleTypeList(), fetchChannelAgreementPrices() (+70 more)
|
||||
Nodes (80): fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchCellSampleTypeList(), fetchChannelAgreementPrices() (+72 more)
|
||||
|
||||
### Community 1 - "Community 1"
|
||||
Cohesion: 0.03
|
||||
Nodes (56): fetchBatchGenerateProtocolNos(), fetchBatchGenerateSampleCodes(), fetchBatchIssueProtocolNos(), fetchBatchIssueSampleCodes(), fetchCollectionProtocolNoList(), fetchCreateCollectionProtocolNo(), fetchCreateSampleCode(), fetchDeleteCollectionProtocolNo() (+48 more)
|
||||
Nodes (60): fetchBatchGenerateProtocolNos(), fetchBatchGenerateSampleCodes(), fetchBatchIssueProtocolNos(), fetchBatchIssueSampleCodes(), fetchCollectionProtocolNoList(), fetchCreateCollectionProtocolNo(), fetchCreateSampleCode(), fetchDeleteCollectionProtocolNo() (+52 more)
|
||||
|
||||
### Community 2 - "Community 2"
|
||||
Cohesion: 0.04
|
||||
Nodes (20): clickTab(), handleTouchEnd(), setTransition(), ComponentLoader, IframeRouteManager, RoutePermissionValidator, RouteTransformer, useCommon() (+12 more)
|
||||
Nodes (31): fetchGetUserInfo(), clickTab(), handleTouchEnd(), setTransition(), IframeRouteManager, RouteRegistry, useCommon(), setupAfterEachGuard() (+23 more)
|
||||
|
||||
### Community 3 - "Community 3"
|
||||
Cohesion: 0.04
|
||||
Nodes (25): fetchGetMenuList(), fetchGetMenuCodes(), fetchGetUserInfo(), fetchLogin(), fetchRefreshToken(), MenuProcessor, RouteRegistry, useAppMode() (+17 more)
|
||||
Cohesion: 0.03
|
||||
Nodes (22): fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllConsumableStockLogs(), fetchAllOutputTypes(), fetchAllProcessCategories(), fetchAllProcesses(), fetchAllReagents(), fetchAllReagentStockLogs() (+14 more)
|
||||
|
||||
### Community 4 - "Community 4"
|
||||
Cohesion: 0.05
|
||||
Nodes (33): fetchDeptTree(), fetchPostBoundUserIds(), FireworkSystem, reload(), formatUserLabel(), loadDeptData(), onPersonSelectChange(), subscribeTokenRefresh() (+25 more)
|
||||
Cohesion: 0.04
|
||||
Nodes (33): fetchCollectionRegionList(), fetchCreateCollectionRegion(), fetchCreateHospital(), fetchDeleteCollectionRegion(), fetchDeleteHospital(), fetchHospitalList(), fetchUpdateCollectionRegion(), fetchUpdateHospital() (+25 more)
|
||||
|
||||
### Community 5 - "Community 5"
|
||||
Cohesion: 0.04
|
||||
Nodes (18): fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllOutputTypes(), fetchAllProcessCategories(), fetchAllProcesses(), fetchAllReagents(), fetchAllSopDocuments(), fetchConsumableList() (+10 more)
|
||||
Cohesion: 0.05
|
||||
Nodes (33): fetchDeptTree(), fetchPostBoundUserIds(), FireworkSystem, reload(), formatUserLabel(), loadDeptData(), onPersonSelectChange(), subscribeTokenRefresh() (+25 more)
|
||||
|
||||
### Community 6 - "Community 6"
|
||||
Cohesion: 0.05
|
||||
Nodes (40): fetchAccessLogList(), fetchCleanRoomList(), fetchCreateAccessLog(), fetchCreateCleanRoom(), fetchCreateSite(), fetchDeleteAccessLog(), fetchDeleteCleanRoom(), fetchDeleteSite() (+32 more)
|
||||
|
||||
### Community 7 - "Community 7"
|
||||
Cohesion: 0.07
|
||||
Nodes (35): disableDevTools(), handleLock(), handleUnlock(), isMobile(), toLogin(), base64ToBytes(), bytesToBase64(), decryptJson() (+27 more)
|
||||
Cohesion: 0.05
|
||||
Nodes (18): fetchAttachmentDownloadUrl(), fetchOrderAdjusts(), fetchOrderDetail(), fetchOrderItems(), fetchOrderList(), fetchPriceVersionDetail(), fetchSystemConfig(), handleReceptionAttachmentDownload() (+10 more)
|
||||
|
||||
### Community 8 - "Community 8"
|
||||
Cohesion: 0.09
|
||||
Nodes (5): handleReset(), handleSearch(), WebSocketClient, TableCache, emit()
|
||||
Nodes (31): toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes() (+23 more)
|
||||
|
||||
### Community 9 - "Community 9"
|
||||
Cohesion: 0.05
|
||||
Nodes (18): fetchAttachmentDownloadUrl(), fetchOrderAdjusts(), fetchOrderDetail(), fetchOrderItems(), fetchOrderList(), fetchPriceVersionDetail(), fetchSystemConfig(), handleReceptionAttachmentDownload() (+10 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (10): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), TableCache, themeAnimation() (+2 more)
|
||||
|
||||
### Community 10 - "Community 10"
|
||||
Cohesion: 0.09
|
||||
Nodes (8): getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager, validateStorageData()
|
||||
|
||||
### Community 11 - "Community 11"
|
||||
Cohesion: 0.07
|
||||
Nodes (15): fetchDeleteProductionTask(), fetchProductionTaskDetail(), fetchProductionTaskList(), fetchUpdateProductionTask(), fetchCompleteProductionWorkOrder(), fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList(), handleClose() (+7 more)
|
||||
Cohesion: 0.13
|
||||
Nodes (4): handleReset(), handleSearch(), WebSocketClient, emit()
|
||||
|
||||
### Community 12 - "Community 12"
|
||||
Cohesion: 0.08
|
||||
Nodes (17): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), collectIds(), postorder(), preorder(), applyTreeExpand() (+9 more)
|
||||
|
||||
### Community 13 - "Community 13"
|
||||
Cohesion: 0.09
|
||||
Nodes (9): fetchGetAllUpgradeLogs(), fetchGetChinaMapData(), fetchGetComments(), fetchGetCurrentVersion(), fetchGetLatestUpgradeLog(), fetchGetSystemConfig(), fetchGetUpgradeLogs(), systemUpgrade() (+1 more)
|
||||
|
||||
### Community 13 - "Community 13"
|
||||
Cohesion: 0.1
|
||||
Nodes (13): fetchEthnicList(), addSample(), applyDonationBundleToForm(), confirmBatchTransportApply(), createEmptyTransport(), ensureDonationProtocolNoInOptions(), ensureEthnicOptionInList(), handleOpenForAdd() (+5 more)
|
||||
|
||||
### Community 14 - "Community 14"
|
||||
Cohesion: 0.1
|
||||
Nodes (19): fetchCollectionRegionList(), fetchCreateCollectionRegion(), fetchCreateHospital(), fetchDeleteCollectionRegion(), fetchDeleteHospital(), fetchHospitalList(), fetchUpdateCollectionRegion(), fetchUpdateHospital() (+11 more)
|
||||
Nodes (8): fetchGetMenuList(), fetchGetMenuCodes(), fetchLogin(), fetchRefreshToken(), MenuProcessor, useAppMode(), useAuth(), buildWebEncryptedLoginBody()
|
||||
|
||||
### Community 15 - "Community 15"
|
||||
Cohesion: 0.1
|
||||
Nodes (12): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), collectIds(), handleAdd(), handleDelete(), handleReset() (+4 more)
|
||||
Nodes (13): fetchEthnicList(), addSample(), applyDonationBundleToForm(), confirmBatchTransportApply(), createEmptyTransport(), ensureDonationProtocolNoInOptions(), ensureEthnicOptionInList(), handleOpenForAdd() (+5 more)
|
||||
|
||||
### Community 16 - "Community 16"
|
||||
Cohesion: 0.12
|
||||
Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
|
||||
|
||||
### Community 17 - "Community 17"
|
||||
Cohesion: 0.13
|
||||
Nodes (16): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), postorder(), preorder(), applyTreeExpand(), handleAdd() (+8 more)
|
||||
|
||||
### Community 18 - "Community 18"
|
||||
Cohesion: 0.14
|
||||
Nodes (9): auditorDisplay(), dash(), expressName(), formatYm(), formatYmd(), sampleTypeName(), siteName(), unitName() (+1 more)
|
||||
|
||||
### Community 19 - "Community 19"
|
||||
### Community 18 - "Community 18"
|
||||
Cohesion: 0.14
|
||||
Nodes (17): fetchCreateUser(), fetchDeleteUser(), fetchResetPassword(), fetchUpdateUser(), fetchUserDetail(), formatUserDeptDisplay(), handleAdd(), handleDelete() (+9 more)
|
||||
|
||||
### Community 20 - "Community 20"
|
||||
### Community 19 - "Community 19"
|
||||
Cohesion: 0.12
|
||||
Nodes (12): fetchApproveTask(), fetchBusinessAllTasks(), fetchCompletedTasks(), fetchDesignerData(), fetchInstanceDetail(), fetchMyInstances(), fetchPendingTasks(), fetchProcessDefList() (+4 more)
|
||||
|
||||
### Community 21 - "Community 21"
|
||||
### Community 20 - "Community 20"
|
||||
Cohesion: 0.16
|
||||
Nodes (10): useTable(), useTableImpl(), getColumnChecks(), useTableColumns(), createErrorHandler(), createSmartDebounce(), defaultResponseAdapter(), extractPagination() (+2 more)
|
||||
|
||||
### Community 21 - "Community 21"
|
||||
Cohesion: 0.2
|
||||
Nodes (2): ComponentLoader, RouteTransformer
|
||||
|
||||
### Community 22 - "Community 22"
|
||||
Cohesion: 0.27
|
||||
Nodes (14): useChart(), useChartComponent(), useChartOps(), colourBlend(), getCssVar(), getDarkColor(), getLightColor(), handleElementThemeColor() (+6 more)
|
||||
|
||||
### Community 24 - "Community 24"
|
||||
### Community 23 - "Community 23"
|
||||
Cohesion: 0.17
|
||||
Nodes (3): fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList()
|
||||
Nodes (12): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), handleAdd(), handleBatchDelete(), handleDelete(), handleReset() (+4 more)
|
||||
|
||||
### Community 25 - "Community 25"
|
||||
Cohesion: 0.18
|
||||
Nodes (5): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), useCeremony(), useTheme()
|
||||
Cohesion: 0.17
|
||||
Nodes (3): fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList()
|
||||
|
||||
### Community 26 - "Community 26"
|
||||
Cohesion: 0.18
|
||||
@@ -199,92 +198,88 @@ Cohesion: 0.33
|
||||
Nodes (2): logApiCryptoBootInfo(), maskSecret()
|
||||
|
||||
### Community 32 - "Community 32"
|
||||
Cohesion: 0.29
|
||||
Nodes (2): fetchLeaveDetail(), fetchLeaveList()
|
||||
|
||||
### Community 33 - "Community 33"
|
||||
Cohesion: 0.47
|
||||
Nodes (3): isPaymentDueWithinWarnWindow(), parsePaymentDueYmd(), startOfLocalDay()
|
||||
|
||||
### Community 34 - "Community 34"
|
||||
### Community 33 - "Community 33"
|
||||
Cohesion: 0.33
|
||||
Nodes (2): fetchSampleReceptionCheckItemList(), fetchSampleReceptionCheckItemsActive()
|
||||
|
||||
### Community 35 - "Community 35"
|
||||
### Community 34 - "Community 34"
|
||||
Cohesion: 0.33
|
||||
Nodes (2): fetchQcThirdPartyItemList(), fetchQcThirdPartyItemsActive()
|
||||
|
||||
### Community 36 - "Community 36"
|
||||
### Community 35 - "Community 35"
|
||||
Cohesion: 0.33
|
||||
Nodes (2): fetchQcThirdPartyCompanyList(), fetchQcThirdPartyCompanyOptions()
|
||||
|
||||
### Community 37 - "Community 37"
|
||||
### Community 36 - "Community 36"
|
||||
Cohesion: 0.33
|
||||
Nodes (2): fetchQcLabTestItemList(), fetchQcLabTestItemsActive()
|
||||
|
||||
### Community 38 - "Community 38"
|
||||
### Community 37 - "Community 37"
|
||||
Cohesion: 0.33
|
||||
Nodes (2): fetchQcTaskDetail(), fetchQcTaskList()
|
||||
|
||||
### Community 40 - "Community 40"
|
||||
### Community 39 - "Community 39"
|
||||
Cohesion: 0.53
|
||||
Nodes (4): isEtaTodayOrEarlier(), parseEtaLocalDate(), sampleReceptionRowClassName(), startOfLocalDay()
|
||||
|
||||
### Community 41 - "Community 41"
|
||||
### Community 40 - "Community 40"
|
||||
Cohesion: 0.5
|
||||
Nodes (2): focusInput(), handleKeydown()
|
||||
|
||||
### Community 42 - "Community 42"
|
||||
### Community 41 - "Community 41"
|
||||
Cohesion: 0.67
|
||||
Nodes (2): if(), logSidebarMenu()
|
||||
|
||||
### Community 43 - "Community 43"
|
||||
### Community 42 - "Community 42"
|
||||
Cohesion: 1.0
|
||||
Nodes (2): getSettingDefaults(), resetToDefaults()
|
||||
|
||||
### Community 45 - "Community 45"
|
||||
### Community 44 - "Community 44"
|
||||
Cohesion: 1.0
|
||||
Nodes (2): defaultAvatarPathByRole(), resolveUserAvatarUrl()
|
||||
|
||||
## Knowledge Gaps
|
||||
- **Thin community `Community 21`** (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 27`** (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 30`** (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 31`** (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 32`** (7 nodes): `fetchCreateLeave()`, `fetchDeleteLeave()`, `fetchLeaveDetail()`, `fetchLeaveList()`, `fetchSubmitLeave()`, `fetchUpdateLeave()`, `leave.ts`
|
||||
- **Thin community `Community 33`** (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 34`** (6 nodes): `fetchCreateSampleReceptionCheckItem()`, `fetchDeleteSampleReceptionCheckItem()`, `fetchSampleReceptionCheckItemList()`, `fetchSampleReceptionCheckItemsActive()`, `fetchUpdateSampleReceptionCheckItem()`, `sample-reception-check-item.ts`
|
||||
- **Thin community `Community 34`** (6 nodes): `fetchCreateQcThirdPartyItem()`, `fetchDeleteQcThirdPartyItem()`, `fetchQcThirdPartyItemList()`, `fetchQcThirdPartyItemsActive()`, `fetchUpdateQcThirdPartyItem()`, `qc-third-party-item.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 35`** (6 nodes): `fetchCreateQcThirdPartyItem()`, `fetchDeleteQcThirdPartyItem()`, `fetchQcThirdPartyItemList()`, `fetchQcThirdPartyItemsActive()`, `fetchUpdateQcThirdPartyItem()`, `qc-third-party-item.ts`
|
||||
- **Thin community `Community 35`** (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 36`** (6 nodes): `fetchCreateQcThirdPartyCompany()`, `fetchDeleteQcThirdPartyCompany()`, `fetchQcThirdPartyCompanyList()`, `fetchQcThirdPartyCompanyOptions()`, `fetchUpdateQcThirdPartyCompany()`, `qc-third-party-company.ts`
|
||||
- **Thin community `Community 36`** (6 nodes): `fetchCreateQcLabTestItem()`, `fetchDeleteQcLabTestItem()`, `fetchQcLabTestItemList()`, `fetchQcLabTestItemsActive()`, `fetchUpdateQcLabTestItem()`, `qc-lab-test-item.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 37`** (6 nodes): `fetchCreateQcLabTestItem()`, `fetchDeleteQcLabTestItem()`, `fetchQcLabTestItemList()`, `fetchQcLabTestItemsActive()`, `fetchUpdateQcLabTestItem()`, `qc-lab-test-item.ts`
|
||||
- **Thin community `Community 37`** (6 nodes): `fetchCompleteQcTask()`, `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 38`** (6 nodes): `fetchCompleteQcTask()`, `fetchQcTaskDetail()`, `fetchQcTaskList()`, `fetchStartQcTask()`, `fetchUpdateQcTaskAttachments()`, `qc-task.ts`
|
||||
- **Thin community `Community 40`** (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 41`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
|
||||
- **Thin community `Community 41`** (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 42`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
|
||||
- **Thin community `Community 42`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 43`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 45`** (3 nodes): `defaultAvatarPathByRole()`, `resolveUserAvatarUrl()`, `user-avatar.ts`
|
||||
- **Thin community `Community 44`** (3 nodes): `defaultAvatarPathByRole()`, `resolveUserAvatarUrl()`, `user-avatar.ts`
|
||||
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 3`, `Community 4`, `Community 5`, `Community 6`, `Community 9`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 17`, `Community 18`, `Community 19`, `Community 20`, `Community 24`, `Community 26`, `Community 27`, `Community 32`, `Community 34`, `Community 35`, `Community 36`, `Community 37`, `Community 38`?**
|
||||
_High betweenness centrality (0.266) - this node is a cross-community bridge._
|
||||
- **Why does `push()` connect `Community 4` to `Community 0`, `Community 2`, `Community 8`, `Community 9`, `Community 12`, `Community 13`?**
|
||||
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 17`, `Community 18`, `Community 19`, `Community 23`, `Community 25`, `Community 26`, `Community 27`, `Community 33`, `Community 34`, `Community 35`, `Community 36`, `Community 37`?**
|
||||
_High betweenness centrality (0.279) - this node is a cross-community bridge._
|
||||
- **Why does `push()` connect `Community 5` to `Community 0`, `Community 7`, `Community 9`, `Community 11`, `Community 13`, `Community 15`?**
|
||||
_High betweenness centrality (0.085) - this node is a cross-community bridge._
|
||||
- **Why does `fetchGetLatestUpgradeLog()` connect `Community 12` to `Community 0`?**
|
||||
_High betweenness centrality (0.043) - this node is a cross-community bridge._
|
||||
- **Are the 156 inferred relationships involving `get()` (e.g. with `buildTreePathLabelFromFlat()` and `alignFqPaymentDetailsForDisplay()`) actually correct?**
|
||||
_`get()` has 156 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Why does `buildTreePathLabelFromFlat()` connect `Community 5` to `Community 0`, `Community 9`?**
|
||||
_High betweenness centrality (0.045) - this node is a cross-community bridge._
|
||||
- **Are the 160 inferred relationships involving `get()` (e.g. with `buildTreePathLabelFromFlat()` and `alignFqPaymentDetailsForDisplay()`) actually correct?**
|
||||
_`get()` has 160 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 18 inferred relationships involving `push()` (e.g. with `fetchAllPagedRecords()` and `calcInstallmentDueAmounts()`) actually correct?**
|
||||
_`push()` has 18 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 16 inferred relationships involving `withFullscreenLoading()` (e.g. with `.close()` and `handleSubmit()`) actually correct?**
|
||||
|
||||
@@ -57,12 +57,12 @@
|
||||
</div>
|
||||
<div id="legend"></div>
|
||||
</div>
|
||||
<div id="stats">1461 nodes · 1826 edges · 245 communities</div>
|
||||
<div id="stats">1473 nodes · 1842 edges · 244 communities</div>
|
||||
</div>
|
||||
<script>
|
||||
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 31, "community_name": "Community 31", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 31, "community_name": "Community 31", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 31, "community_name": "Community 31", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 31, "community_name": "Community 31", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 31, "community_name": "Community 31", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 31, "community_name": "Community 31", "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": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 16, "community_name": "Community 16", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.7, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 16, "community_name": "Community 16", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 16, "community_name": "Community 16", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 16, "community_name": "Community 16", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 16, "community_name": "Community 16", "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": 226}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 94}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 65}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 62}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 53}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 53}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 51}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 48}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 48}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 44}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 36}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 35}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 31}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 27}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 27}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 25}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 22}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 21}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 20}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 20}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 19}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 17}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 16}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 13}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 12}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 11}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 11}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 10}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 9}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 8}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 8}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 7}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 7}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 6}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 6}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 6}, {"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": 3}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 3}, {"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": 2}, {"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}, {"ciLine truncated
|
||||
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 31, "community_name": "Community 31", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 31, "community_name": "Community 31", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 31, "community_name": "Community 31", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 31, "community_name": "Community 31", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 31, "community_name": "Community 31", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 31, "community_name": "Community 31", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 78, "community_name": "Community 78", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 79, "community_name": "Community 79", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 16, "community_name": "Community 16", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.7, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 16, "community_name": "Community 16", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 16, "community_name": "Community 16", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 16, "community_name": "Community 16", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 16, "community_name": "Community 16", "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": 233}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 101}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 69}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 65}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 61}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 53}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 51}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 44}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 39}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 39}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 36}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 34}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 33}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 31}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 27}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 27}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 22}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 20}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 20}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 19}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 17}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 17}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 16}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 16}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 13}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 12}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 11}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 10}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 9}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 8}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 8}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 7}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 6}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 6}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 6}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 6}, {"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": 5}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 4}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 3}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 3}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 3}, {"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": 2}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 2}, {"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}, {"cLine truncated
|
||||
|
||||
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
|
||||
function esc(s) {
|
||||
|
||||
@@ -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": 1779506249.5668056,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1779502098.7595692,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1779511864.5113068,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1779511519.245795,
|
||||
"/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,
|
||||
@@ -192,7 +192,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/core/useAppMode.ts": 1778582067.999649,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/leave.ts": 1778666177.2933538,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception-check-item.ts": 1779007909.2933023,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts": 1779171206.8677726,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts": 1779510739.079313,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-third-party-item.ts": 1779017836.101254,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts": 1779492302.440177,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/workflow.ts": 1778729873.096252,
|
||||
@@ -273,7 +273,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process-route/index.vue": 1779435878.9581294,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/sop/index.vue": 1779309609.6630545,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-task/index.vue": 1779414898.4036016,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/reagent/index.vue": 1779307562.93293,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/reagent/index.vue": 1779511836.8888884,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue": 1779504046.6918495,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts": 1779506613.3205173,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/StepDetailPanel.vue": 1779507602.4356499,
|
||||
@@ -284,7 +284,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue": 1779432481.6736288,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskOutputProductDialog.vue": 1779505558.2585275,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable-pack/index.vue": 1779307488.018346,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable/index.vue": 1779307921.9798808,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable/index.vue": 1779511015.0429022,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process/index.vue": 1779436610.457994,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process-category/index.vue": 1779307716.2724373,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/index/index.vue": 1778582068.070888,
|
||||
|
||||
+1
@@ -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": []}
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_consumable_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_ts", "label": "production.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L1"}, {"id": "api_production_fetchconsumablelist", "label": "fetchConsumableList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L7"}, {"id": "api_production_fetchallconsumables", "label": "fetchAllConsumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L17"}, {"id": "api_production_fetchcreateconsumable", "label": "fetchCreateConsumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L21"}, {"id": "api_production_fetchupdateconsumable", "label": "fetchUpdateConsumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L25"}, {"id": "api_production_fetchdeleteconsumable", "label": "fetchDeleteConsumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L29"}, {"id": "api_production_fetchreagentlist", "label": "fetchReagentList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L37"}, {"id": "api_production_fetchallreagents", "label": "fetchAllReagents()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L47"}, {"id": "api_production_fetchcreatereagent", "label": "fetchCreateReagent()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L51"}, {"id": "api_production_fetchupdatereagent", "label": "fetchUpdateReagent()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L55"}, {"id": "api_production_fetchdeletereagent", "label": "fetchDeleteReagent()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L59"}, {"id": "api_production_fetchsoplist", "label": "fetchSopList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L67"}, {"id": "api_production_fetchallsopdocuments", "label": "fetchAllSopDocuments()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L77"}, {"id": "api_production_fetchcreatesop", "label": "fetchCreateSop()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L81"}, {"id": "api_production_fetchupdatesop", "label": "fetchUpdateSop()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L85"}, {"id": "api_production_fetchdeletesop", "label": "fetchDeleteSop()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L89"}, {"id": "api_production_fetchprocesscategorylist", "label": "fetchProcessCategoryList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L97"}, {"id": "api_production_fetchallprocesscategories", "label": "fetchAllProcessCategories()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L111"}, {"id": "api_production_fetchcreateprocesscategory", "label": "fetchCreateProcessCategory()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L115"}, {"id": "api_production_fetchupdateprocesscategory", "label": "fetchUpdateProcessCategory()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L119"}, {"id": "api_production_fetchdeleteprocesscategory", "label": "fetchDeleteProcessCategory()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L123"}, {"id": "api_production_fetchoutputtypelist", "label": "fetchOutputTypeList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L131"}, {"id": "api_production_fetchalloutputtypes", "label": "fetchAllOutputTypes()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts", "source_location": "L141"}, {"id": "api_production_fetchcreateoutputtype", "label": "fetchCreateOutputType()", "file_type": "code", "source_file"Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_reagent_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/reagent/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
|
||||
@@ -145,7 +145,7 @@
|
||||
<el-form-item label="变动类型">
|
||||
<el-select v-model="logSearchForm.changeType" placeholder="全部" clearable>
|
||||
<el-option label="入库" value="in" />
|
||||
<el-option label="出库" value="use" />
|
||||
<el-option label="出库" value="out" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间范围">
|
||||
@@ -212,6 +212,12 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工单号" min-width="140" align="center" header-align="center">
|
||||
<template #default="{ row }">{{ row.taskNo || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="步骤名称" min-width="140" align="center" header-align="center">
|
||||
<template #default="{ row }">{{ row.stepName || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="领用人" min-width="100" align="center" header-align="center">
|
||||
<template #default="{ row }">{{ row.receiver || '-' }}</template>
|
||||
</el-table-column>
|
||||
@@ -785,6 +791,12 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工单号" min-width="140" align="center" header-align="center">
|
||||
<template #default="{ row }">{{ row.taskNo || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="步骤名称" min-width="140" align="center" header-align="center">
|
||||
<template #default="{ row }">{{ row.stepName || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="领用人" min-width="100" align="center" header-align="center">
|
||||
<template #default="{ row }">{{ row.receiver || '-' }}</template>
|
||||
</el-table-column>
|
||||
@@ -1020,7 +1032,7 @@
|
||||
function getSourceLabel(sourceType: string) {
|
||||
if (sourceType === 'manual_in') return '手动入库'
|
||||
if (sourceType === 'manual_out') return '手动出库'
|
||||
if (sourceType === 'step_save') return '步骤扣减'
|
||||
if (sourceType === 'step_save') return '生产扣减'
|
||||
return sourceType || '-'
|
||||
}
|
||||
|
||||
|
||||
@@ -219,8 +219,8 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="变动类型">
|
||||
<el-select v-model="allLogFilter.changeType" placeholder="全部" clearable>
|
||||
<el-option label="入库" value="in" />
|
||||
<el-option label="出库" value="use" />
|
||||
<el-option label="入库" value="in" />
|
||||
<el-option label="出库" value="out" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间范围">
|
||||
@@ -319,6 +319,12 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工单号" min-width="140" align="center" header-align="center">
|
||||
<template #default="{ row }">{{ row.taskNo || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="步骤名称" min-width="140" align="center" header-align="center">
|
||||
<template #default="{ row }">{{ row.stepName || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="receiver"
|
||||
label="领用人"
|
||||
@@ -928,7 +934,7 @@
|
||||
<el-form-item label="变动类型">
|
||||
<el-select v-model="stockLogFilter.changeType" placeholder="全部" clearable @change="loadStockLogs">
|
||||
<el-option label="入库" value="in" />
|
||||
<el-option label="出库" value="use" />
|
||||
<el-option label="出库" value="out" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@@ -985,6 +991,12 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工单号" min-width="140" align="center" header-align="center">
|
||||
<template #default="{ row }">{{ row.taskNo || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="步骤名称" min-width="140" align="center" header-align="center">
|
||||
<template #default="{ row }">{{ row.stepName || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="receiver"
|
||||
label="领用人"
|
||||
@@ -1099,7 +1111,7 @@
|
||||
const map: Record<string, string> = {
|
||||
manual_in: '手动入库',
|
||||
manual_out: '手动出库',
|
||||
step_save: '步骤扣减'
|
||||
step_save: '生产扣减'
|
||||
}
|
||||
return map[sourceType] || sourceType || '-'
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user