This commit is contained in:
zlwu committed 2026-07-13 12:11:13 +08:00
1 parent df53d05193
commit f90726927e
50 files changed
+16281 -12780

No files matched your search

+28
View File
@@ -54,6 +54,7 @@ from app.schemas.production_task import (
ProductionTaskForwardBody,
ProductionTaskAssigneeUpdate,
ProductionTaskStepDispatchBody,
SpawnTemporaryWorkOrderBody,
TaskStepAdd,
TaskStepUpdate,
TaskStepMaterialItem,
@@ -2079,6 +2080,33 @@ async def forward_production_task_api(
return error_response(400, str(e))
@router.post("/production-tasks/{task_id}/spawn-temporary-work-order")
async def spawn_temporary_work_order_from_task_api(
task_id: str,
body: SpawnTemporaryWorkOrderBody,
operateScope: Optional[str] = Query(None, alias="operateScope"),
user: dict = Depends(
require_any_menu_code("production:my-task:list", "production:work-order:list")
),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
result = production_task_svc.spawn_temporary_work_order_from_task(
db,
task_id,
tenant_no=tenant_no,
user_id=user.get("user_id"),
create_dept_id=user.get("dept_id", ""),
remark=body.remark or "",
)
db.commit()
return success_response(result, message="临时工单已创建")
except ValueError as e:
db.rollback()
return error_response(400, str(e))
@router.put("/production-tasks/{task_id}/assignee")
async def reassign_production_task_api(
task_id: str,
+19
View File
@@ -1414,6 +1414,8 @@ class QcMaterialBatchUpdateBody(BaseModel):
manufacturer: Optional[str] = None
unit_price: Optional[float] = Field(None, alias="unitPrice")
amount: Optional[float] = None
in_qty: Optional[float] = Field(None, alias="inQty")
remaining_qty: Optional[float] = Field(None, alias="remainingQty")
remark: Optional[str] = None
qc_attachment_urls: Optional[str] = Field(None, alias="qcAttachmentUrls")
material_code: Optional[str] = Field(None, alias="materialCode")
@@ -1477,6 +1479,23 @@ async def qc_material_batch_options(
return error_response(400, str(e))
@router.get("/qc-material-batches/{batch_id}")
async def get_qc_material_batch(
batch_id: str,
db: Session = Depends(get_db),
user: dict = Depends(require_menu_code("biz:qcMaterial:list")),
):
try:
tenant_no = _get_tenant_no(db, user)
payload = batch_svc.get_batch_detail(db, batch_id, tenant_no=tenant_no)
_maybe_strip_qc_material_amount_fields(db, user, [payload])
return success_response(payload)
except ValueError as e:
return error_response(400, str(e))
except Exception as e:
return error_response(400, str(e))
@router.put("/qc-material-batches/{batch_id}")
async def update_qc_material_batch(
batch_id: str,
+74
View File
@@ -2484,6 +2484,80 @@ def replace_step_data_collections(
db.commit()
def spawn_temporary_work_order_from_task(
db: Session,
source_task_id: str,
*,
tenant_no: str,
user_id: Optional[str] = None,
create_dept_id: str = "",
remark: str = "",
) -> Dict[str, Any]:
"""从生产任务创建临时生产工单,并返回待复制到新任务的原材料载荷(不含产出)。"""
task = (
db.query(BizProductionTask)
.filter(
and_(
BizProductionTask.id == source_task_id,
BizProductionTask.tenant_no == tenant_no,
BizProductionTask.del_flag == 0,
)
)
.first()
)
if not task:
raise ValueError("任务不存在")
inputs = (
db.query(BizProductionTaskInput)
.filter(
and_(
BizProductionTaskInput.task_id == source_task_id,
BizProductionTaskInput.del_flag == 0,
)
)
.order_by(BizProductionTaskInput.order_num.asc(), BizProductionTaskInput.create_time.asc())
.all()
)
if not inputs:
raise ValueError("请先在原材料中填写并保存后再派发临时工单")
copy_items: List[Dict[str, Any]] = []
for inp in inputs:
inp_type = (inp.input_type or "").strip()
inp_id = (inp.input_id or "").strip()
inp_code = (inp.input_code or "").strip()
inp_name = (inp.input_name or "").strip()
if not inp_type or (not inp_id and not inp_code and not inp_name):
raise ValueError("原材料数据不完整,请保存后再派发")
copy_items.append({
"inputType": inp_type,
"inputId": inp_id or None,
"inputCode": inp_code or None,
"inputName": inp_name or None,
"remark": (inp.remark or "").strip() or None,
})
user_remark = (remark or "").strip()
full_remark = user_remark[:512] if user_remark else ""
from app.crud import production_work_order as production_work_order_svc
new_wo = production_work_order_svc.create_temp_production_work_order(
db,
tenant_no=tenant_no,
user_id=user_id,
create_dept_id=create_dept_id,
remark=full_remark,
)
return {
"workOrder": production_work_order_svc._temp_wo_to_dict(new_wo),
"sourceTaskId": task.id,
"sourceTaskNo": task.task_no or "",
"inputItems": copy_items,
}
def set_task_inputs(
db: Session, task_id: str, tenant_no: str,
user_id: Optional[str], items: List[Dict[str, Any]],
+183 -2
View File
@@ -750,6 +750,89 @@ def get_batch(db: Session, batch_id: str, tenant_no: str) -> Optional[BizQcMater
)
def _sum_batch_out_total(
db: Session, batch_id: str, tenant_no: str
) -> Tuple[Decimal, int]:
row = (
db.query(
func.coalesce(func.sum(func.abs(BizQcMaterialUsage.change_qty)), 0),
func.count(BizQcMaterialUsage.id),
)
.filter(
BizQcMaterialUsage.batch_id == batch_id,
BizQcMaterialUsage.tenant_no == tenant_no,
BizQcMaterialUsage.del_flag == 0,
BizQcMaterialUsage.change_type.in_(["use", "discard"]),
)
.one()
)
total = Decimal(str(row[0] or 0))
count = int(row[1] or 0)
return total, count
def get_batch_detail(
db: Session, batch_id: str, tenant_no: str
) -> Dict[str, Any]:
batch = get_batch(db, batch_id, tenant_no)
if not batch:
raise ValueError("入库批次不存在")
material = (
db.query(BizQcMaterial)
.filter(
BizQcMaterial.id == batch.material_id,
BizQcMaterial.tenant_no == tenant_no,
BizQcMaterial.del_flag == 0,
)
.first()
)
out_total, out_count = _sum_batch_out_total(db, batch_id, tenant_no)
payload = _batch_row_to_dict(batch, material)
payload["outTotal"] = _dec(out_total)
payload["outCount"] = out_count
return payload
def _append_batch_qty_adjust(
db: Session,
*,
batch: BizQcMaterialStockBatch,
material: BizQcMaterial,
change_qty: Decimal,
stock_before: Decimal,
stock_after: Decimal,
remark: str,
tenant_no: str,
user_id: Optional[str],
) -> None:
if change_qty == 0:
return
now = datetime.now()
snaps = _usage_batch_snapshots(batch)
db.add(
BizQcMaterialUsage(
id=generate_uuid(),
material_id=material.id,
material_code=material.material_code,
material_name=material.material_name,
change_type="adjust",
change_qty=change_qty,
stock_before=stock_before,
stock_after=stock_after,
source_type="batch_qty_edit",
tenant_no=tenant_no,
remark=remark,
create_by=user_id,
create_dept_id=material.create_dept_id or "",
create_time=now,
update_by=user_id,
update_time=now,
del_flag=0,
**snaps,
)
)
def update_batch(
db: Session,
batch_id: str,
@@ -764,6 +847,8 @@ def update_batch(
manufacturer: Optional[str] = None,
unit_price: Optional[Any] = None,
amount: Optional[Any] = None,
in_qty: Optional[Any] = None,
remaining_qty: Optional[Any] = None,
remark: Optional[str] = None,
qc_attachment_urls: Optional[str] = None,
material_code: Optional[str] = None,
@@ -775,7 +860,16 @@ def update_batch(
) -> BizQcMaterialStockBatch:
from app.crud import qc_material as mat_svc
batch = get_batch(db, batch_id, tenant_no)
batch = (
db.query(BizQcMaterialStockBatch)
.filter(
BizQcMaterialStockBatch.id == batch_id,
BizQcMaterialStockBatch.tenant_no == tenant_no,
BizQcMaterialStockBatch.del_flag == 0,
)
.with_for_update()
.first()
)
if not batch:
raise ValueError("入库批次不存在")
@@ -826,6 +920,92 @@ def update_batch(
if qc_attachment_urls is not None:
batch.qc_attachment_urls = (qc_attachment_urls or "").strip() or None
old_in_qty = batch.in_qty or Decimal("0")
old_remaining = batch.remaining_qty or Decimal("0")
qty_updated = in_qty is not None or remaining_qty is not None
qty_values_changed = False
if qty_updated:
new_in_qty = _require_decimal(in_qty, "入库数量") if in_qty is not None else old_in_qty
new_remaining = (
_require_decimal(remaining_qty, "剩余数量")
if remaining_qty is not None
else old_remaining
)
qty_values_changed = new_in_qty != old_in_qty or new_remaining != old_remaining
if qty_values_changed:
if new_in_qty <= 0:
raise ValueError("入库数量必须大于0")
if new_remaining < 0:
raise ValueError("剩余数量不能为负数")
if new_remaining > new_in_qty:
raise ValueError("剩余数量不能大于入库数量")
out_total, _ = _sum_batch_out_total(db, batch_id, tenant_no)
if new_in_qty < out_total:
raise ValueError(f"入库数量不能小于已出库量 {_dec(out_total)}")
delta_remaining = new_remaining - old_remaining
if in_qty is not None and amount is None:
unit_p = batch.unit_price or Decimal("0")
batch.amount = (unit_p * new_in_qty).quantize(Decimal("0.01"))
stock_before = material.stock_qty or Decimal("0")
material.stock_qty = stock_before + delta_remaining
material.update_by = user_id
material.update_time = datetime.now()
db.add(material)
batch.in_qty = new_in_qty
batch.remaining_qty = new_remaining
in_qty_delta = new_in_qty - old_in_qty
remaining_extra = new_remaining - (old_remaining + in_qty_delta)
running_stock = stock_before
user_remark = (remark or "").strip() if remark is not None else ""
if in_qty_delta != 0:
next_stock = running_stock + in_qty_delta
adjust_remark = (
f"编辑修正入库数量({_dec(old_in_qty)} → {_dec(new_in_qty)})"
)
if user_remark:
adjust_remark = f"{adjust_remark};{user_remark}"
_append_batch_qty_adjust(
db,
batch=batch,
material=material,
change_qty=in_qty_delta,
stock_before=running_stock,
stock_after=next_stock,
remark=adjust_remark,
tenant_no=tenant_no,
user_id=user_id,
)
running_stock = next_stock
if remaining_extra != 0:
expected_remaining = old_remaining + in_qty_delta
next_stock = running_stock + remaining_extra
adjust_remark = (
f"编辑修正剩余数量({_dec(expected_remaining)} → {_dec(new_remaining)})"
)
if user_remark and in_qty_delta == 0:
adjust_remark = f"{adjust_remark};{user_remark}"
_append_batch_qty_adjust(
db,
batch=batch,
material=material,
change_qty=remaining_extra,
stock_before=running_stock,
stock_after=next_stock,
remark=adjust_remark,
tenant_no=tenant_no,
user_id=user_id,
)
batch.material_code = material.material_code
batch.material_name = material.material_name
batch.spec_model = material.spec_model
@@ -853,7 +1033,8 @@ def update_batch(
in_usage.batch_no = batch.batch_no
in_usage.manufacturer = batch.manufacturer
in_usage.unit_price = batch.unit_price
in_usage.amount = batch.amount
if not qty_values_changed:
in_usage.amount = batch.amount
in_usage.remark = batch.remark
in_usage.update_by = user_id
in_usage.update_time = datetime.now()
+2
View File
@@ -280,6 +280,8 @@ def _list_usages_query(
q0 = q0.filter(BizQcMaterialUsage.change_type == "in")
elif ct == "discard":
q0 = q0.filter(BizQcMaterialUsage.change_type == "discard")
elif ct == "adjust":
q0 = q0.filter(BizQcMaterialUsage.change_type == "adjust")
# 任务消耗子流水(parent_usage_id 有值)仅在「任务使用」筛选下展示,避免与领用行重复
if ct != "use":
q0 = q0.filter(
@@ -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_legacy_material_write_gone", "label": "_legacy_material_write_gone()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L76"}, {"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": "L80"}, {"id": "api_production_get_current_user_id", "label": "_get_current_user_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L88"}, {"id": "api_production_consumablecreatebody", "label": "ConsumableCreateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L97"}, {"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": "L111"}, {"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": "L126"}, {"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": "L140"}, {"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": "L150"}, {"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": "L159"}, {"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": "L169"}, {"id": "api_production_stockinbody", "label": "StockInBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L177"}, {"id": "api_production_stockoutbody", "label": "StockOutBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L183"}, {"id": "api_production_batchstockinitem", "label": "BatchStockInItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L191"}, {"id": "api_production_batchstockinbody", "label": "BatchStockInBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L198"}, {"id": "api_production_batchstockoutitem", "label": "BatchStockOutItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L204"}, {"id": "api_production_batchstockoutbody", "label": "BatchStockOutBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L210"}, {"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": "L219"}, {"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": "L241"}, {"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": "L265"}, {"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": "L283"}, {"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": "L302"}, {"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": "L321"}, {"id": "api_production_reagentcreatebody", "label": "ReagentCreateBody"Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_schemas_production_task_py", "label": "production_task.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L1"}, {"id": "schemas_production_task_productiontaskcreate", "label": "ProductionTaskCreate", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L6"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "schemas_production_task_productiontaskforwardbody", "label": "ProductionTaskForwardBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L17"}, {"id": "schemas_production_task_productiontaskassigneeupdate", "label": "ProductionTaskAssigneeUpdate", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L23"}, {"id": "schemas_production_task_productiontasklistquery", "label": "ProductionTaskListQuery", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L29"}, {"id": "schemas_production_task_productiontasklistbyworkordersbody", "label": "ProductionTaskListByWorkOrdersBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L38"}, {"id": "schemas_production_task_productiontaskupdate", "label": "ProductionTaskUpdate", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L48"}, {"id": "schemas_production_task_productiontaskstatusupdate", "label": "ProductionTaskStatusUpdate", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L57"}, {"id": "schemas_production_task_taskstepadd", "label": "TaskStepAdd", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L64"}, {"id": "schemas_production_task_taskstepupdate", "label": "TaskStepUpdate", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L75"}, {"id": "schemas_production_task_taskstepmaterialitem", "label": "TaskStepMaterialItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L85"}, {"id": "schemas_production_task_taskstepoutputitem", "label": "TaskStepOutputItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L100"}, {"id": "schemas_production_task_taskstepdatacollectionitem", "label": "TaskStepDataCollectionItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L107"}, {"id": "schemas_production_task_taskinputitem", "label": "TaskInputItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L114"}, {"id": "schemas_production_task_taskoutputitem", "label": "TaskOutputItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L123"}, {"id": "schemas_production_task_taskstepreorderbody", "label": "TaskStepReorderBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L152"}, {"id": "schemas_production_task_productiontaskstepdispatchitem", "label": "ProductionTaskStepDispatchItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L158"}, {"id": "schemas_production_task_productiontaskstepdispatchbody", "label": "ProductionTaskStepDispatchBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L165"}, {"id": "schemas_production_task_spawntemporaryworkorderbody", "label": "SpawnTemporaryWorkOrderBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L170"}, {"id": "schemas_production_task_rationale_39", "label": "\u6309\u591a\u4e2a\u5de5\u5355 ID \u6279\u91cf\u67e5\u8be2\u751f\u4ea7\u4efb\u52a1\uff08POST body\uff0c\u907f\u514d GET URL \u8fc7\u957f\uff09", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py", "source_location": "L39"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_schemas_production_task_py", "target": "pydantic", "relation": "importLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_material_stock_batch_py", "label": "qc_material_stock_batch.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L1"}, {"id": "crud_qc_material_stock_batch_fmt_date", "label": "_fmt_date()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L16"}, {"id": "crud_qc_material_stock_batch_parse_date", "label": "_parse_date()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L20"}, {"id": "crud_qc_material_stock_batch_parse_expire_date", "label": "_parse_expire_date()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L34"}, {"id": "crud_qc_material_stock_batch_require_str", "label": "_require_str()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L38"}, {"id": "crud_qc_material_stock_batch_require_decimal", "label": "_require_decimal()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L45"}, {"id": "crud_qc_material_stock_batch_stock_in_no_exists", "label": "stock_in_no_exists()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L57"}, {"id": "crud_qc_material_stock_batch_batch_row_to_dict", "label": "_batch_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L73"}, {"id": "crud_qc_material_stock_batch_usage_batch_snapshots", "label": "_usage_batch_snapshots()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L106"}, {"id": "crud_qc_material_stock_batch_get_material_for_update", "label": "_get_material_for_update()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L127"}, {"id": "crud_qc_material_stock_batch_list_batches", "label": "list_batches()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L145"}, {"id": "crud_qc_material_stock_batch_batch_options", "label": "batch_options()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L209"}, {"id": "crud_qc_material_stock_batch_create_batch_and_usage", "label": "_create_batch_and_usage()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L282"}, {"id": "crud_qc_material_stock_batch_stock_in_one", "label": "stock_in_one()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L373"}, {"id": "crud_qc_material_stock_batch_batch_stock_in", "label": "batch_stock_in()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L414"}, {"id": "crud_qc_material_stock_batch_stock_out_batch", "label": "_stock_out_batch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L470"}, {"id": "crud_qc_material_stock_batch_batch_stock_out", "label": "batch_stock_out()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L551"}, {"id": "crud_qc_material_stock_batch_validate_discard_reason", "label": "_validate_discard_reason()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L604"}, {"id": "crud_qc_material_stock_batch_discard_batch", "label": "_discard_batch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L613"}, {"id": "crud_qc_material_stock_batch_batch_discard", "label": "batch_discard()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L690"}, {"id": "crud_qc_material_stock_batch_get_batch", "label": "get_batch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py", "source_location": "L741"}, {"id": "crud_qc_material_stock_batch_sum_batch_out_total", "label": "_sum_batch_out_total()", "file_type": "code", "source_file": "/UsLine truncated
@@ -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_require_requisition_for_catalog_material", "label": "_require_requisition_for_catalog_material()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L53"}, {"id": "crud_production_task_production_conclusion_label", "label": "_production_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L105"}, {"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": "L112"}, {"id": "crud_production_task_normalize_date_bound", "label": "_normalize_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L116"}, {"id": "crud_production_task_enrich_outbound_task_items", "label": "_enrich_outbound_task_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L123"}, {"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": "L257"}, {"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": "L271"}, {"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": "L300"}, {"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": "L325"}, {"id": "crud_production_task_step_configured_reagent_to_dict", "label": "_step_configured_reagent_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L342"}, {"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": "L358"}, {"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": "L375"}, {"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": "L387"}, {"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": "L399"}, {"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": "L421"}, {"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": "L446"}, {"id": "crud_production_task_resolve_sub_table_order_num", "label": "_resolve_sub_table_order_num()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L459"}, {"id": "crud_production_task_empty_step_sub_tables", "label": "_empty_step_sub_tables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L468"}, {"id": "crud_production_task_batch_load_step_sub_tables", "label": "_batch_load_step_sub_tables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L478"}, {"id": "crud_production_task_step_sub_tables_to_dict", "label": "_step_sub_tables_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L578"}, {"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_locatiLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_qc_py", "label": "qc.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L1"}, {"id": "api_qc_thirdpartycompanybody", "label": "ThirdPartyCompanyBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L63"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_qc_thirdpartycompanyupdatebody", "label": "ThirdPartyCompanyUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L81"}, {"id": "api_qc_list_qc_third_party_companies", "label": "list_qc_third_party_companies()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L100"}, {"id": "api_qc_list_qc_third_party_company_options", "label": "list_qc_third_party_company_options()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L122"}, {"id": "api_qc_create_qc_third_party_company", "label": "create_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L136"}, {"id": "api_qc_update_qc_third_party_company", "label": "update_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L171"}, {"id": "api_qc_delete_qc_third_party_company", "label": "delete_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L208"}, {"id": "api_qc_thirdpartyitembody", "label": "ThirdPartyItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L228"}, {"id": "api_qc_thirdpartyitemupdatebody", "label": "ThirdPartyItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L240"}, {"id": "api_qc_list_qc_third_party_items", "label": "list_qc_third_party_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L253"}, {"id": "api_qc_list_qc_third_party_items_active", "label": "list_qc_third_party_items_active()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L282"}, {"id": "api_qc_create_qc_third_party_item", "label": "create_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L297"}, {"id": "api_qc_update_qc_third_party_item", "label": "update_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L326"}, {"id": "api_qc_delete_qc_third_party_item", "label": "delete_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L357"}, {"id": "api_qc_labtestitembody", "label": "LabTestItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L377"}, {"id": "api_qc_labtestitemupdatebody", "label": "LabTestItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L388"}, {"id": "api_qc_itemparambody", "label": "ItemParamBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L402"}, {"id": "api_qc_taskresultbody", "label": "TaskResultBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L407"}, {"id": "api_qc_taskcompletewithresultbody", "label": "TaskCompleteWithResultBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L412"}, {"id": "api_qc_list_qc_lab_test_items", "label": "list_qc_lab_test_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L422"}, {"id": "api_qc_list_qc_lab_test_items_active", "label": "list_qc_lab_test_items_active()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L444"}, {"id": "api_qc_create_qc_lab_test_item", "label": "create_qc_lab_test_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L458"}, {"id": "api_qc_update_qc_lab_test_item", "label": "update_qc_lab_test_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L486"}, {"id": "apiLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_material_usage_py", "label": "qc_material_usage.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L1"}, {"id": "crud_qc_material_usage_parse_receiver_purpose_from_remark", "label": "_parse_receiver_purpose_from_remark()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L18"}, {"id": "crud_qc_material_usage_resolve_receiver_purpose", "label": "_resolve_receiver_purpose()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L30"}, {"id": "crud_qc_material_usage_display_remark", "label": "_display_remark()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L40"}, {"id": "crud_qc_material_usage_user_nick_name_map", "label": "_user_nick_name_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L56"}, {"id": "crud_qc_material_usage_receiver_display_map", "label": "_receiver_display_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L64"}, {"id": "crud_qc_material_usage_usage_unit_label", "label": "_usage_unit_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L76"}, {"id": "crud_qc_material_usage_stock_in_date_for_row", "label": "_stock_in_date_for_row()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L85"}, {"id": "crud_qc_material_usage_unit_price_for_row", "label": "_unit_price_for_row()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L91"}, {"id": "crud_qc_material_usage_amount_for_row", "label": "_amount_for_row()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L99"}, {"id": "crud_qc_material_usage_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L115"}, {"id": "crud_qc_material_usage_linked_qc_task_no_map", "label": "_linked_qc_task_no_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L176"}, {"id": "crud_qc_material_usage_batch_map", "label": "_batch_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L209"}, {"id": "crud_qc_material_usage_mine_usage_filter", "label": "_mine_usage_filter()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L221"}, {"id": "crud_qc_material_usage_list_usages_query", "label": "_list_usages_query()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L246"}, {"id": "crud_qc_material_usage_paginate_usages", "label": "_paginate_usages()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L320"}, {"id": "crud_qc_material_usage_list_usages", "label": "list_usages()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L365"}, {"id": "crud_qc_material_usage_list_my_usages", "label": "list_my_usages()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L393"}, {"id": "crud_qc_material_usage_list_usages_by_task", "label": "list_usages_by_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L424"}, {"id": "crud_qc_material_usage_list_linked_task_usages", "label": "list_linked_task_usages()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L481"}, {"id": "crud_qc_material_usage_revert_task_material_usages", "label": "revert_task_material_usages()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L531"}, {"id": "crud_qc_material_usage_list_requisition_options", "label": "list_requisition_options()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py", "source_location": "L599"}, {"id": "crud_qc_material_usage_rLine truncated
@@ -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_require_requisition_for_catalog_material", "label": "_require_requisition_for_catalog_material()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L53"}, {"id": "crud_production_task_production_conclusion_label", "label": "_production_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L105"}, {"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": "L112"}, {"id": "crud_production_task_normalize_date_bound", "label": "_normalize_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L116"}, {"id": "crud_production_task_enrich_outbound_task_items", "label": "_enrich_outbound_task_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L123"}, {"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": "L257"}, {"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": "L271"}, {"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": "L300"}, {"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": "L325"}, {"id": "crud_production_task_step_configured_reagent_to_dict", "label": "_step_configured_reagent_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L342"}, {"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": "L358"}, {"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": "L375"}, {"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": "L387"}, {"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": "L399"}, {"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": "L421"}, {"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": "L446"}, {"id": "crud_production_task_resolve_sub_table_order_num", "label": "_resolve_sub_table_order_num()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L459"}, {"id": "crud_production_task_empty_step_sub_tables", "label": "_empty_step_sub_tables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L468"}, {"id": "crud_production_task_batch_load_step_sub_tables", "label": "_batch_load_step_sub_tables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L478"}, {"id": "crud_production_task_step_sub_tables_to_dict", "label": "_step_sub_tables_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L578"}, {"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_locatiLine truncated
+5
View File
@@ -165,3 +165,8 @@ class ProductionTaskStepDispatchItem(BaseModel):
class ProductionTaskStepDispatchBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
steps: List[ProductionTaskStepDispatchItem] = Field(..., min_length=1)
class SpawnTemporaryWorkOrderBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
remark: Optional[str] = None
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+91 -116
View File
@@ -1,11 +1,11 @@
# Graph Report - app (2026-07-07)
## Corpus Check
- Large corpus: 217 files · ~263,710 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
- Large corpus: 217 files · ~264,353 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
## Summary
- 4494 nodes · 24239 edges · 50 communities detected
- Extraction: 32% EXTRACTED · 68% INFERRED · 0% AMBIGUOUS · INFERRED: 16527 edges (avg confidence: 0.59)
- 4501 nodes · 24339 edges · 45 communities detected
- Extraction: 32% EXTRACTED · 68% INFERRED · 0% AMBIGUOUS · INFERRED: 16613 edges (avg confidence: 0.59)
- Token cost: 0 input · 0 output
## Community Hubs (Navigation)
@@ -48,26 +48,21 @@
- [[_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 44|Community 44]]
- [[_COMMUNITY_Community 45|Community 45]]
- [[_COMMUNITY_Community 46|Community 46]]
- [[_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]]
## God Nodes (most connected - your core abstractions)
1. `success_response()` - 671 edges
2. `error_response()` - 555 edges
3. `SysUser` - 502 edges
1. `success_response()` - 673 edges
2. `error_response()` - 557 edges
3. `SysUser` - 503 edges
4. `BizQcTaskResult` - 316 edges
5. `BizProductionMaterial` - 311 edges
5. `BizProductionMaterial` - 312 edges
6. `BizProductionMaterialUsage` - 306 edges
7. `BizQcMaterialUsage` - 303 edges
7. `BizQcMaterialUsage` - 304 edges
8. `BizQcMaterial` - 294 edges
9. `BizProductionMaterialStockBatch` - 293 edges
10. `BizMaterialUsage` - 290 edges
@@ -88,63 +83,63 @@
### Community 0 - "Community 0"
Cohesion: 0.01
Nodes (866): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+858 more)
Nodes (859): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+851 more)
### Community 1 - "Community 1"
Cohesion: 0.01
Nodes (616): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+608 more)
Nodes (564): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+556 more)
### Community 2 - "Community 2"
Cohesion: 0.07
Nodes (504): 细胞存储 — 采集协议单 / 审核 / 财务确认 / 分期预警 API, 与列表接口一致:按租户 + 角色数据权限判断是否可访问该协议单。, If mother info exists but no customerId, create a customer record and link it., Base, 细胞产品 CRUD(biz_cell_product), 解析任务样本投入物,返回祖先链单段(样本终止节点)。, 管理端手动改状态:允许在合法枚举间任意变更,并同步库位占用。, 去掉末尾 -P{n}-XX 或 -XX,得到代次产品编码的基础前缀。 (+496 more)
Cohesion: 0.01
Nodes (382): _normalize_date_bound(), _body_to_payload(), _get_current_user_id(), get_production_reception_detail(), _get_tenant_no(), post_production_reception(), put_production_reception(), _resolve_reception_id() (+374 more)
### Community 3 - "Community 3"
Cohesion: 0.01
Nodes (388): _normalize_date_bound(), list_ethnics_for_select(), apply_data_scope(), _get_child_dept_ids(), get_user_dept_id(), _resolve_user_role_scopes(), format_date(), ApiRequestLogCRUD (+380 more)
Cohesion: 0.09
Nodes (340): 环境检测 — 检测项维护 + 登记管理 API, 保险公司及险种价格管理 API(保险公司 + 开票信息 + 险种价格), ProcessDefCreateBody, ProcessDefUpdateBody, PublishVersionBody, 审批意见:前端传 commentText,兼容 comment。, StartInstanceBody, TaskActionBody (+332 more)
### Community 4 - "Community 4"
Cohesion: 0.01
Nodes (310): generate_uuid(), map_payments_by_schedule_ids(), batch_stock_in(), batch_stock_out(), consumable_code_exists(), create_consumable(), _dec(), get_consumable() (+302 more)
Nodes (280): generate_uuid(), batch_stock_in(), batch_stock_out(), consumable_code_exists(), create_consumable(), _dec(), get_consumable(), _is_enabled_status() (+272 more)
### Community 5 - "Community 5"
Cohesion: 0.02
Nodes (252): eq_unicode(), like_unicode(), MySQL 字符串比较/模糊匹配时统一排序规则,避免 Illegal mix of collations。, 跨表字符串等值比较(JOIN / WHERE)时统一为 utf8mb4_unicode_ci。, 将列显式设为 utf8mb4_unicode_ci。, unicode_ci(), build_void_type_label_map(), format_protocol_status_label() (+244 more)
Nodes (256): _persist_protocol_sub_resources(), list_ethnics_for_select(), apply_data_scope(), _get_child_dept_ids(), get_user_dept_id(), _resolve_user_role_scopes(), ApiRequestLogCRUD, delete() (+248 more)
### Community 6 - "Community 6"
Cohesion: 0.02
Nodes (185): batch_discard(), batch_options(), _batch_row_to_dict(), batch_stock_in(), batch_stock_out(), _create_batch_and_usage(), delete_batch(), _discard_batch() (+177 more)
Cohesion: 0.08
Nodes (271): CellSampleTypeCreateBody, CellSampleTypeUpdateBody, CollectionRegionCreateBody, CollectionRegionUpdateBody, CustomerCreateBody, CustomerUpdateBody, HospitalCreateBody, HospitalUpdateBody (+263 more)
### Community 7 - "Community 7"
Cohesion: 0.02
Nodes (116): get_designer_data(), _error_json(), lifespan(), 数据库异常:返回 JSON 并保留 CORS 头,避免浏览器只报跨域错误, 未捕获异常:统一 JSON 500,确保跨域场景下仍有 Access-Control-Allow-Origin, sqlalchemy_exception_handler(), unhandled_exception_handler(), BaseHTTPMiddleware (+108 more)
Nodes (172): api_save_application(), map_payments_by_schedule_ids(), get_protocol_nos_used_in_protocols(), create_dict_type(), dict_type_code_exists(), get_dict_type(), list_dict_types(), 字典类型 CRUD(sys_dict_type) (+164 more)
### Community 8 - "Community 8"
Cohesion: 0.02
Nodes (149): _avatar_url_field(), _build_current_user_payload(), _build_user_info_payload(), get_current_user_profile(), get_web_auth_menu_codes(), _jwt_user_payload(), logout(), 公共接口(Web 登录、刷新 Token、登出;用户模型对齐 docs/sql/zkxw.sql 基线) (+141 more)
Cohesion: 0.03
Nodes (161): batch_discard(), batch_options(), _batch_row_to_dict(), batch_stock_in(), batch_stock_out(), _create_batch_and_usage(), delete_batch(), _discard_batch() (+153 more)
### Community 9 - "Community 9"
Cohesion: 0.04
Nodes (124): AccessLogCreateBody, AccessLogUpdateBody, CleanRoomCreateBody, CleanRoomUpdateBody, ExhibitionAppointmentCreateBody, ExhibitionAppointmentUpdateBody, list_storage_slot_stats(), OccupancyCreateBody (+116 more)
Cohesion: 0.02
Nodes (103): get_designer_data(), _error_json(), 数据库异常:返回 JSON 并保留 CORS 头,避免浏览器只报跨域错误, 未捕获异常:统一 JSON 500,确保跨域场景下仍有 Access-Control-Allow-Origin, sqlalchemy_exception_handler(), unhandled_exception_handler(), BaseHTTPMiddleware, ApiCryptoError (+95 more)
### Community 10 - "Community 10"
Cohesion: 0.34
Nodes (73): BatchStockInBody, BatchStockInItem, BatchStockOutBody, BatchStockOutItem, ConsumableCreateBody, ConsumablePackCreateBody, ConsumablePackUpdateBody, ConsumableUpdateBody (+65 more)
Cohesion: 0.03
Nodes (148): get_next_cell_product_code(), build_void_type_label_map(), format_protocol_status_label(), resolve_void_type_label(), _ancestor_link_from_cell_product_input(), _ancestor_sample_chain_link(), _apply_cell_product_status_change(), _build_ancestor_chain() (+140 more)
### Community 11 - "Community 11"
Cohesion: 0.05
Nodes (69): generate_id(), optional_date(), parse_date(), 将字符串 / date / datetime 转为 date 或 None, camel_to_snake(), get_model_attr(), HistoryCRUD, allocate_next_biz_no() (+61 more)
Cohesion: 0.04
Nodes (124): AccessLogCreateBody, AccessLogUpdateBody, CleanRoomCreateBody, CleanRoomUpdateBody, ExhibitionAppointmentCreateBody, ExhibitionAppointmentUpdateBody, OccupancyCreateBody, 运营支撑 API(洁净室、进出记录、仓储设施、储位、展厅预约) (+116 more)
### Community 12 - "Community 12"
Cohesion: 0.06
Nodes (62): get_next_cell_product_code(), _ancestor_link_from_cell_product_input(), _ancestor_sample_chain_link(), _apply_cell_product_status_change(), _build_ancestor_chain(), _build_descendant_chain(), _build_facility_path_label(), build_split_product_codes() (+54 more)
Cohesion: 0.04
Nodes (91): 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() (+83 more)
### Community 13 - "Community 13"
Cohesion: 0.06
Nodes (61): complete_application(), create_basic_experiment_sale_schedules(), create_infusion_plan(), create_schedule(), _create_schedule_products(), _format_yyyy_mm_dd(), _generate_application_no(), get_application() (+53 more)
Cohesion: 0.34
Nodes (74): BatchStockInBody, BatchStockInItem, BatchStockOutBody, BatchStockOutItem, ConsumableCreateBody, ConsumablePackCreateBody, ConsumablePackUpdateBody, ConsumableUpdateBody (+66 more)
### Community 14 - "Community 14"
Cohesion: 0.11
Nodes (39): _amount_for_row(), _batch_map(), deduct_for_task(), _deduct_task_usage_legacy_batch(), _display_remark(), _fmt_date_val(), _linked_qc_task_no_map(), list_linked_task_usages() (+31 more)
Cohesion: 0.06
Nodes (54): _avatar_url_field(), _build_user_info_payload(), _jwt_user_payload(), Web 端登录用 RSA 公钥(PKCS#1 v1.5,与 JSEncrypt 一致), Web 端登录:账号为 sys_user.user_no,密码为 sys_user.password(bcrypt)。, 返回库中原始头像路径,由前端按 VITE_MINIO_BASE_URL 拼展示 URL。, 与 web-admin `userInfo` 字段约定一致。, refresh_token() (+46 more)
### Community 15 - "Community 15"
Cohesion: 0.11
@@ -155,177 +150,157 @@ 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 17 - "Community 17"
Cohesion: 0.16
Nodes (22): _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), get_material_entity(), get_my_usages(), _is_enabled_status() (+14 more)
Cohesion: 0.2
Nodes (19): _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), get_material_entity(), get_my_usages(), _is_enabled_status() (+11 more)
### Community 18 - "Community 18"
Cohesion: 0.17
Nodes (21): batch_stock_in(), batch_stock_out(), code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), _is_enabled_status() (+13 more)
Cohesion: 0.21
Nodes (15): batch_generate_protocol_nos(), batch_issue_protocol_nos(), batch_revoke_protocol_nos(), create_protocol_no(), get_protocol_no(), list_protocol_nos(), _parse_issued_time(), protocol_no_exists() (+7 more)
### Community 19 - "Community 19"
Cohesion: 0.14
Nodes (17): _build_tree(), _cascade_soft_delete(), create_menu(), get_menu(), list_menus(), list_menus_tree(), _row_to_dict(), soft_delete_menu() (+9 more)
Cohesion: 0.22
Nodes (14): batch_generate_sample_codes(), batch_issue_sample_codes(), batch_revoke_sample_codes(), create_sample_code(), get_sample_code(), list_sample_codes(), _parse_issued_time(), 样本编码池 CRUD(biz_sample_code) (+6 more)
### Community 20 - "Community 20"
Cohesion: 0.18
Nodes (15): create_collection_region(), create_hospital(), get_collection_region(), get_hospital(), _hospital_names_by_region_ids(), _hospital_to_dict(), list_collection_regions(), list_hospitals() (+7 more)
Cohesion: 0.22
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 21 - "Community 21"
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 22 - "Community 22"
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 23 - "Community 23"
### Community 22 - "Community 22"
Cohesion: 0.24
Nodes (11): deduct_for_step(), _display_remark(), list_stock_logs(), _parse_receiver_purpose_from_remark(), 试剂变动记录 CRUD(biz_reagent_stock_log), 撤销步骤此前 step_save 扣减,便于重新填报。, 扣减试剂库存并生成变动记录。调用方控制事务,本函数不 commit。, _resolve_receiver_purpose() (+3 more)
### Community 24 - "Community 24"
Cohesion: 0.32
Nodes (11): create_env_detect_record(), _generate_record_no(), get_env_detect_record(), _join_csv(), list_env_detect_records(), _resolve_inspector_snapshots(), _resolve_item_snapshot(), _row_to_dict() (+3 more)
### Community 25 - "Community 25"
### Community 23 - "Community 23"
Cohesion: 0.24
Nodes (11): deduct_for_step(), _display_remark(), list_stock_logs(), _parse_receiver_purpose_from_remark(), 耗材变动记录 CRUD(biz_consumable_stock_log), 撤销步骤此前 step_save 扣减,便于重新填报。, 扣减耗材库存并生成变动记录。调用方控制事务,本函数不 commit。, _resolve_receiver_purpose() (+3 more)
### Community 26 - "Community 26"
### Community 24 - "Community 24"
Cohesion: 0.27
Nodes (11): _build_tree(), _cascade_soft_delete(), _collect_with_ancestors(), create_dept(), get_dept(), list_depts(), list_depts_tree(), 保留匹配节点及其全部上级,供关键词检索后仍能正确组树。 (+3 more)
### Community 27 - "Community 27"
### Community 25 - "Community 25"
Cohesion: 0.27
Nodes (8): create_customer(), get_customer(), id_card_taken(), list_customers(), 客户 CRUD(biz_customer), _row_to_dict(), soft_delete_customer(), update_customer()
### Community 28 - "Community 28"
### Community 26 - "Community 26"
Cohesion: 0.31
Nodes (8): create_express_company(), express_code_exists(), get_express_company(), list_express_companies(), 快递公司 CRUD(biz_express_company), _row_to_dict(), soft_delete_express_company(), update_express_company()
### Community 29 - "Community 29"
### Community 27 - "Community 27"
Cohesion: 0.38
Nodes (9): create_check_item(), get_check_item(), item_code_exists(), list_active_check_items(), list_check_items(), _order_query(), _row_to_dict(), soft_delete_check_item() (+1 more)
### Community 30 - "Community 30"
### Community 28 - "Community 28"
Cohesion: 0.38
Nodes (9): create_env_detect_item(), get_env_detect_item(), item_code_exists(), list_active_env_detect_items(), list_env_detect_items(), _order_query(), _row_to_dict(), soft_delete_env_detect_item() (+1 more)
### Community 31 - "Community 31"
### Community 29 - "Community 29"
Cohesion: 0.31
Nodes (8): create_item_unit(), get_item_unit(), list_item_units(), 物品单位 CRUD(biz_item_unit), _row_to_dict(), soft_delete_item_unit(), unit_code_exists(), update_item_unit()
### Community 32 - "Community 32"
### Community 30 - "Community 30"
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 33 - "Community 33"
### Community 31 - "Community 31"
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 34 - "Community 34"
Cohesion: 0.36
Nodes (7): create_post(), get_post(), list_posts(), post_code_exists(), _row_to_dict(), soft_delete_post(), update_post()
### Community 35 - "Community 35"
Cohesion: 0.36
Nodes (7): create_tenant(), get_tenant(), list_tenants(), _row_to_dict(), soft_delete_tenant(), tenant_no_exists(), update_tenant()
### Community 36 - "Community 36"
Cohesion: 0.36
Nodes (7): create_site(), get_site(), list_sites(), _row_to_dict(), site_code_exists(), soft_delete_site(), update_site()
### Community 37 - "Community 37"
### Community 32 - "Community 32"
Cohesion: 0.29
Nodes (2): BaseModel, SoftDeleteModel
### Community 38 - "Community 38"
### Community 33 - "Community 33"
Cohesion: 0.38
Nodes (6): derive_legacy_status_from_three(), derive_three_status_from_legacy(), 阶段A兼容:从旧 status 推导三字段。 约束:旧 status 本身混合了支付/配送/订单生命周期,因此只能尽力推断; 若业务侧已有更精确, 阶段A兼容:从三字段反推旧 status(用于旧前端/旧筛选参数兼容)。, ThreeStatus, _to_decimal()
### Community 39 - "Community 39"
### Community 34 - "Community 34"
Cohesion: 0.5
Nodes (3): BaseSettings, Config, Settings
### Community 40 - "Community 40"
### Community 35 - "Community 35"
Cohesion: 0.5
Nodes (2): _auto_fill_create_dept_id(), ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID
### Community 41 - "Community 41"
### Community 36 - "Community 36"
Cohesion: 0.67
Nodes (2): get_menu_list(), 运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,5 个一级菜单分组)
### Community 42 - "Community 42"
### Community 37 - "Community 37"
Cohesion: 1.0
Nodes (1): 请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传
### Community 43 - "Community 43"
### Community 38 - "Community 38"
Cohesion: 1.0
Nodes (1): API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)
### Community 46 - "Community 46"
### Community 41 - "Community 41"
Cohesion: 1.0
Nodes (1): 发送订单状态通知 Args: openid: 用户openid ord
### Community 47 - "Community 47"
### Community 42 - "Community 42"
Cohesion: 1.0
Nodes (1): 发送支付成功通知 Args: openid: 用户openid ord
### Community 48 - "Community 48"
### Community 43 - "Community 43"
Cohesion: 1.0
Nodes (1): 发送配送通知 Args: openid: 配送员openid task
### Community 49 - "Community 49"
### Community 44 - "Community 44"
Cohesion: 1.0
Nodes (1): 发送配送时效预警 Args: openid: 配送员openid ta
### Community 50 - "Community 50"
### Community 45 - "Community 45"
Cohesion: 1.0
Nodes (1): 发送退款结果通知 Args: openid: 用户openid ord
### Community 51 - "Community 51"
### Community 46 - "Community 46"
Cohesion: 1.0
Nodes (1): 发送催单通知给配送员 Args: deliver_openid: 配送员openid
## Knowledge Gaps
- **130 isolated node(s):** `刷新会话 TTL(refreshToken 续期;已登录用户每次 API 校验通过后滑动续期)`, `写入 refreshToken(用于 one-time 使用/吊销)`, `根据 token 获取当前用户(包含 Redis 会话校验;会话滑动续期)`, `登录凭据 RSA 解密(与前端 JSEncrypt PKCS#1 v1.5 兼容)。`, `加载 RSA 密钥对:优先环境变量,否则使用内置固定默认密钥。` (+125 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **Thin community `Community 37`** (8 nodes): `BaseModel`, `.to_dict()`, `get_active()`, `base.py`, `SoftDeleteModel`, `.restore()`, `.soft_delete()`, `__tablename__()`
- **Thin community `Community 32`** (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 40`** (4 nodes): `_auto_fill_create_dept_id()`, `get_db()`, `database.py`, `ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID`
- **Thin community `Community 35`** (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 41`** (3 nodes): `get_menu_list()`, `menu.py`, `运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,5 个一级菜单分组)`
- **Thin community `Community 36`** (3 nodes): `get_menu_list()`, `menu.py`, `运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,5 个一级菜单分组)`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 42`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
- **Thin community `Community 37`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 43`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
- **Thin community `Community 38`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 46`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord`
- **Thin community `Community 41`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 47`** (1 nodes): `发送支付成功通知 Args: openid: 用户openid ord`
- **Thin community `Community 42`** (1 nodes): `发送支付成功通知 Args: openid: 用户openid ord`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 48`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task`
- **Thin community `Community 43`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 49`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta`
- **Thin community `Community 44`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 50`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord`
- **Thin community `Community 45`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 51`** (1 nodes): `发送催单通知给配送员 Args: deliver_openid: 配送员openid`
- **Thin community `Community 46`** (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 `SysUser` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 8`, `Community 9`, `Community 10`, `Community 14`, `Community 17`, `Community 21`, `Community 23`, `Community 25`?**
_High betweenness centrality (0.104) - this node is a cross-community bridge._
- **Why does `generate_uuid()` connect `Community 4` to `Community 0`, `Community 1`, `Community 3`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 11`, `Community 12`, `Community 14`, `Community 15`, `Community 17`, `Community 18`, `Community 19`, `Community 20`, `Community 21`, `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`?**
_High betweenness centrality (0.089) - this node is a cross-community bridge._
- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 3`, `Community 7`, `Community 8`, `Community 9`, `Community 41`, `Community 12`?**
_High betweenness centrality (0.055) - this node is a cross-community bridge._
- **Are the 738 inferred relationships involving `str` (e.g. with `unhandled_exception_handler()` and `get_current_user_by_token()`) actually correct?**
_`str` has 738 INFERRED edges - model-reasoned connections that need verification._
- **Are the 670 inferred relationships involving `success_response()` (e.g. with `list_storage_release_reviews()` and `get_storage_release_review_detail()`) actually correct?**
_`success_response()` has 670 INFERRED edges - model-reasoned connections that need verification._
- **Are the 554 inferred relationships involving `error_response()` (e.g. with `_json_error_response()` and `list_storage_release_reviews()`) actually correct?**
_`error_response()` has 554 INFERRED edges - model-reasoned connections that need verification._
- **Are the 500 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤) data_scope 值: 1 = 全部数据 2 = 本部门数据 3` and `从 SysUser 读取用户的 dept_id。`) actually correct?**
_`SysUser` has 500 INFERRED edges - model-reasoned connections that need verification._
- **Why does `SysUser` connect `Community 1` to `Community 2`, `Community 3`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 18`, `Community 19`, `Community 22`, `Community 23`?**
_High betweenness centrality (0.121) - this node is a cross-community bridge._
- **Why does `generate_uuid()` connect `Community 4` to `Community 0`, `Community 2`, `Community 3`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 14`, `Community 15`, `Community 17`, `Community 18`, `Community 19`, `Community 20`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`?**
_High betweenness centrality (0.076) - this node is a cross-community bridge._
- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 2`, `Community 36`, `Community 5`, `Community 7`, `Community 9`, `Community 10`, `Community 12`, `Community 14`?**
_High betweenness centrality (0.068) - this node is a cross-community bridge._
- **Are the 741 inferred relationships involving `str` (e.g. with `unhandled_exception_handler()` and `get_current_user_by_token()`) actually correct?**
_`str` has 741 INFERRED edges - model-reasoned connections that need verification._
- **Are the 672 inferred relationships involving `success_response()` (e.g. with `list_storage_release_reviews()` and `get_storage_release_review_detail()`) actually correct?**
_`success_response()` has 672 INFERRED edges - model-reasoned connections that need verification._
- **Are the 556 inferred relationships involving `error_response()` (e.g. with `_json_error_response()` and `list_storage_release_reviews()`) actually correct?**
_`error_response()` has 556 INFERRED edges - model-reasoned connections that need verification._
- **Are the 501 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤) data_scope 值: 1 = 全部数据 2 = 本部门数据 3` and `从 SysUser 读取用户的 dept_id。`) actually correct?**
_`SysUser` has 501 INFERRED edges - model-reasoned connections that need verification._
+4 -4
View File
@@ -57,12 +57,12 @@
</div>
<div id="legend"></div>
</div>
<div id="stats">4494 nodes &middot; 24239 edges &middot; 56 communities</div>
<div id="stats">4501 nodes &middot; 24339 edges &middot; 51 communities</div>
</div>
<script>
const RAW_NODES = [{"id": "init_py", "label": "__init__.py", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 44, "community_name": "Community 44", "source_file": "__init__.py", "file_type": "code", "degree": 0}, {"id": "main_py", "label": "main.py", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "main.py", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 7}, {"id": "app_main_lifespan", "label": "lifespan()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_error_json", "label": "_error_json()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "_error_json()", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 3}, {"id": "app_main_sqlalchemy_exception_handler", "label": "sqlalchemy_exception_handler()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "sqlalchemy_exception_handler()", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_unhandled_exception_handler", "label": "unhandled_exception_handler()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "unhandled_exception_handler()", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 5}, {"id": "app_main_mask_secret", "label": "_mask_secret()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "_mask_secret()", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_root", "label": "root()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "root()", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_health_check", "label": "health_check()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "health_check()", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_rationale_81", "label": "\u6570\u636e\u5e93\u5f02\u5e38\uff1a\u8fd4\u56de JSON \u5e76\u4fdd\u7559 CORS \u5934\uff0c\u907f\u514d\u6d4f\u89c8\u5668\u53ea\u62a5\u8de8\u57df\u9519\u8bef", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "\u6570\u636e\u5e93\u5f02\u5e38\uff1a\u8fd4\u56de JSON \u5e76\u4fdd\u7559 CORS \u5934\uff0c\u907f\u514d\u6d4f\u89c8\u5668\u53ea\u62a5\u8de8\u57df\u9519\u8bef", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "rationale", "degree": 3}, {"id": "app_main_rationale_92", "label": "\u672a\u6355\u83b7\u5f02\u5e38\uff1a\u7edf\u4e00 JSON 500\uff0c\u786e\u4fdd\u8de8\u57df\u573a\u666f\u4e0b\u4ecd\u6709 Access-Control-Allow-Origin", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "\u672a\u6355\u83b7\u5f02\u5e38\uff1a\u7edf\u4e00 JSON 500\uff0c\u786e\u4fdd\u8de8\u57df\u573a\u666f\u4e0b\u4ecd\u6709 Access-Control-Allow-Origin", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "rationale", "degree": 3}, {"id": "tasks_init_py", "label": "__init__.py", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 7, "community_name": "Community 7", "source_file": "tasks/__init__.py", "file_type": "code", "degLine 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_error_json", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_sqlalchemy_exception_handler", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_unhandled_exception_handler", "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": "app_main_error_json", "to": "app_main_sqlalchemy_exception_handler", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_error_json", "to": "app_main_unhandled_exception_handler", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_sqlalchemy_exception_handler", "to": "app_main_rationale_81", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_sqlalchemy_exception_handler", "to": "exception", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_unhandled_exception_handler", "to": "app_main_rationale_92", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_unhandled_exception_handler", "to": "exception", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_unhandled_exception_handler", "to": "str", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_81", "to": "core_api_request_log_middleware_apirequestlogmiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_81", "to": "core_api_crypto_middleware_apicryptomiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_92", "to": "core_api_request_log_middleware_apirequestlogmiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_92", "to": "core_api_crypto_middleware_apicryptomiddleware", "label": "uses", "title": "uses [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", "labeLine truncated
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 901}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 657}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 510}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 438}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 336}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 268}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 198}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 186}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 170}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 129}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 82}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 81}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 65}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 65}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 40}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 38}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 31}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 23}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 23}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 21}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 17}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 14}, {"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": 12}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 12}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 11}, {"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": 9}, {"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": 4}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 4}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 3}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 2}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 2}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 1}, {"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": 0}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 0}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 0}];
const RAW_NODES = [{"id": "init_py", "label": "__init__.py", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 39, "community_name": "Community 39", "source_file": "__init__.py", "file_type": "code", "degree": 0}, {"id": "main_py", "label": "main.py", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "main.py", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 7}, {"id": "app_main_lifespan", "label": "lifespan()", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 14, "community_name": "Community 14", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_error_json", "label": "_error_json()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "_error_json()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 3}, {"id": "app_main_sqlalchemy_exception_handler", "label": "sqlalchemy_exception_handler()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "sqlalchemy_exception_handler()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_unhandled_exception_handler", "label": "unhandled_exception_handler()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "unhandled_exception_handler()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 5}, {"id": "app_main_mask_secret", "label": "_mask_secret()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "_mask_secret()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_root", "label": "root()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "root()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_health_check", "label": "health_check()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "health_check()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_rationale_81", "label": "\u6570\u636e\u5e93\u5f02\u5e38\uff1a\u8fd4\u56de JSON \u5e76\u4fdd\u7559 CORS \u5934\uff0c\u907f\u514d\u6d4f\u89c8\u5668\u53ea\u62a5\u8de8\u57df\u9519\u8bef", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "\u6570\u636e\u5e93\u5f02\u5e38\uff1a\u8fd4\u56de JSON \u5e76\u4fdd\u7559 CORS \u5934\uff0c\u907f\u514d\u6d4f\u89c8\u5668\u53ea\u62a5\u8de8\u57df\u9519\u8bef", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "rationale", "degree": 3}, {"id": "app_main_rationale_92", "label": "\u672a\u6355\u83b7\u5f02\u5e38\uff1a\u7edf\u4e00 JSON 500\uff0c\u786e\u4fdd\u8de8\u57df\u573a\u666f\u4e0b\u4ecd\u6709 Access-Control-Allow-Origin", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "\u672a\u6355\u83b7\u5f02\u5e38\uff1a\u7edf\u4e00 JSON 500\uff0c\u786e\u4fdd\u8de8\u57df\u573a\u666f\u4e0b\u4ecd\u6709 Access-Control-Allow-Origin", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "rationale", "degree": 3}, {"id": "tasks_init_py", "label": "__init__.py", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 14, "community_name": "Community 14", "source_file": "tasks/__init__.py", "file_type": "code", Line 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_error_json", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_sqlalchemy_exception_handler", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_unhandled_exception_handler", "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": "app_main_error_json", "to": "app_main_sqlalchemy_exception_handler", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_error_json", "to": "app_main_unhandled_exception_handler", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_sqlalchemy_exception_handler", "to": "app_main_rationale_81", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_sqlalchemy_exception_handler", "to": "exception", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_unhandled_exception_handler", "to": "app_main_rationale_92", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_unhandled_exception_handler", "to": "exception", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_unhandled_exception_handler", "to": "str", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_81", "to": "core_api_request_log_middleware_apirequestlogmiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_81", "to": "core_api_crypto_middleware_apicryptomiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_92", "to": "core_api_request_log_middleware_apirequestlogmiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_92", "to": "core_api_crypto_middleware_apicryptomiddleware", "label": "uses", "title": "uses [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", "labeLine truncated
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 894}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 602}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 415}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 345}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 315}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 286}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 273}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 190}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 172}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 171}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 158}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 129}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 106}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 83}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 63}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 38}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 31}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 20}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 17}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 16}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 15}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 13}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 12}, {"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": 8}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 7}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 4}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 4}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 3}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 2}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 2}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 1}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 1}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 1}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 1}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 1}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 1}, {"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": 0}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 0}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 0}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 0}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 0}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 0}, {"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) {
File diff suppressed because it is too large. Load diff
+6 -6
View File
@@ -52,7 +52,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/product_parameter_value.py": 1778578258.0980055,
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/product_review_media.py": 1778578258.0986822,
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/product_parameter.py": 1778578258.0977957,
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py": 1783306300.9945476,
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/production_task.py": 1783402762.4365127,
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/product_detail_media.py": 1778578258.0973988,
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/product_banner.py": 1778578258.097102,
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/region.py": 1778578258.099429,
@@ -99,14 +99,14 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/material_usage.py": 1782894693.7808309,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_usage.py": 1781513732.7796721,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sop_document.py": 1779265721.9928973,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py": 1783307214.537781,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py": 1783403507.6142845,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/inbound_sample_special.py": 1782890475.769446,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_third_party_item.py": 1779265661.482352,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_production_reception.py": 1782722028.9202535,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py": 1779512669.9847593,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/collection_protocol.py": 1783329833.497812,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/cleanroom_garment.py": 1782264452.4901433,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py": 1781423974.5969574,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_usage.py": 1783428516.0973594,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/biz_no_generator.py": 1779882385.4674172,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_confirm.py": 1779828818.7646794,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py": 1779515479.6599197,
@@ -121,7 +121,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_lab_test_item.py": 1779265673.3888667,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/pre_transit_sample.py": 1782891216.72219,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/role.py": 1779265616.3701816,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py": 1781690315.173275,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_batch.py": 1783428574.8936534,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/material_stock_check.py": 1781427194.5434632,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task_step_assignee.py": 1782469070.7380123,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_sms_notification.py": 1781590614.9654794,
@@ -177,7 +177,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/api/public.py": 1782122639.96012,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/material.py": 1782894693.6582327,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py": 1782404982.2474263,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py": 1783392548.7993915,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py": 1783428518.8598783,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/market.py": 1781522283.6823432,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/sample_production_reception.py": 1782718998.90251,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/collection_protocol.py": 1782982337.6828277,
@@ -204,7 +204,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/api/sample_sms_notification.py": 1780325524.907156,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/sample_reception.py": 1782719108.3741593,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py": 1781410837.9443986,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py": 1783305567.650697,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py": 1783402784.4873977,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/protocol_sample_collection.py": 1780457788.2093296,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/leave.py": 1779266168.8693042,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/clinical_payment.py": 1781750841.074568,
@@ -0,0 +1,59 @@
# 质检物料库 · 编辑弹窗数量修正 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 允许在质检物料库编辑弹窗修正入库数量与剩余数量,同步物资汇总库存与入库流水,账实不符时写入 adjust 流水,不改历史出库记录。
**Architecture:** 后端 `update_batch` 增加数量修正分支(`_sum_batch_out_total` + 校验 + 入库流水同步 + 可选 adjust 流水);新增 GET 批次详情返回 `outTotal`;前端编辑弹窗联动两数量字段;变动记录 Tab 支持 adjust 筛选与展示。
**Tech Stack:** FastAPI · SQLAlchemy · Vue 3 · Element Plus · DecimalInput
**Spec:** `docs/superpowers/specs/2026-07-07-qc-material-batch-qty-edit-design.md`
---
### Task 1: 后端 CRUD — out_total 与 update_batch 数量修正
**Files:**
- Modify: `backend/app/crud/qc_material_stock_batch.py`
- [ ] 新增 `_sum_batch_out_total(db, batch_id, tenant_no) -> Tuple[Decimal, int]`
- [ ] 新增 `get_batch_detail(db, batch_id, tenant_no) -> Dict`(含 outTotal、outCount)
- [ ] `update_batch` 增加 `in_qty` / `remaining_qty` 参数与事务内数量修正逻辑
- [ ] 批次查询改用 `with_for_update()` 锁定
### Task 2: 后端 API
**Files:**
- Modify: `backend/app/api/qc.py`
- [ ] `QcMaterialBatchUpdateBody` 增加 `inQty`、`remainingQty`
- [ ] 新增 `GET /qc-material-batches/{batch_id}`
### Task 3: 变动记录 adjust 筛选
**Files:**
- Modify: `backend/app/crud/qc_material_usage.py`
- [ ] `_list_usages_query` 增加 `change_type == adjust` 分支
### Task 4: 前端 API 与编辑弹窗
**Files:**
- Modify: `web-admin/src/api/qc-material.ts`
- Modify: `web-admin/src/views/quality-inspection/qc-material/index.vue`
- [ ] 类型与 `fetchQcMaterialBatchDetail`
- [ ] 编辑弹窗可编辑数量、只读已出库/理论剩余、联动与校验、提交 payload
### Task 5: 变动记录 Tab
**Files:**
- Modify: `web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue`
- [ ] 筛选项「库存调整」、Tag 与来源文案
### Task 6: 验证
- [ ] 后端 Python 语法检查
- [ ] 前端 lint 相关文件
@@ -0,0 +1,218 @@
# 质检物料库 · 编辑弹窗数量修正设计
> 日期: 2026-07-07
> 状态: 已实现
> 父模块: 质量检测 → 质检物料库(`/#/quality-group/quality-base/qc-material`)
> 关联文档: `2026-06-11-qc-material-batch-inbound-design.md`
## 1. 背景与目标
### 问题
编辑入库批次弹窗中,**入库数量**(`in_qty`)与**剩余数量**(`remaining_qty`)为只读,入库时若填错数量无法事后修正,导致批次余额与物资汇总库存(`stock_qty`)不准确。
### 目标(用户确认:场景 C — 两种都要支持)
| 场景 | 说明 | 典型操作 |
|------|------|----------|
| **A. 入库录入错误** | 初始入库量填错,出库/废弃/任务扣减记录本身正确 | 修正 `in_qty`,剩余按公式联动 |
| **B. 账实不符** | 入库量无误,实物盘点或发现剩余与账面不一致 | 直接修正 `remaining_qty`,写库存调整流水 |
### 非目标
- 修改历史出库 / 废弃 / 任务扣减流水(审计记录不可篡改)
- 回溯修改已完成盘点单中的快照行
- 同步改造生产物料库、细胞存储物料库(本 spec 仅覆盖质检物料库;后续可复用模式)
---
## 2. 数据不变量
### 2.1 批次级
```
已出库总量(out_total) = Σ |change_qty|
WHERE batch_id = 当前批次
AND del_flag = 0
AND change_type IN ('use', 'discard')
理论剩余(theoretical_remaining) = in_qty − out_total
```
恒等式(正常状态下):
- `0 ≤ remaining_qty ≤ in_qty`
- `remaining_qty = theoretical_remaining`(无独立调整时)
### 2.2 物资汇总
```
material.stock_qty = Σ batch.remaining_qty(同 material_id、del_flag=0)
```
### 2.3 流水职责
| 类型 | change_type | source_type | 是否随编辑修改 |
|------|-------------|-------------|----------------|
| 入库 | `in` | `manual_in` | **是** — 同步 `change_qty`、`amount` 快照 |
| 出库 | `use` | `manual_out` 等 | **否** |
| 废弃 | `discard` | `manual_discard` | **否** |
| 库存调整(新增) | `adjust` | `batch_qty_edit` | **新增** — 仅当剩余与理论值不一致时 |
---
## 3. 业务规则
### 3.1 编辑弹窗字段
| 字段 | 可编辑 | 说明 |
|------|--------|------|
| 入库数量 `inQty` | ✅ | `el-input-number`,min > 0,精度与入库一致(4 位小数) |
| 剩余数量 `remainingQty` | ✅ | 同上;可与理论值不同(场景 B) |
| 已出库总量 | 只读展示 | 打开弹窗时由后端返回或前端根据查看数据展示 |
| 理论剩余 | 只读展示 | `inQty − outTotal`;用户改 `inQty` 时前端实时重算 |
**UI 提示(有出库时):**
> 该批次已出库/废弃共 **{outTotal}** {unit}。修改入库数量后,若剩余数量未手工改动,将自动调整为 **{theoreticalRemaining}**。
**UI 提示(剩余与理论值不一致时):**
> 剩余数量与「入库数量 − 已出库」不一致,保存后将写入一条**库存调整**记录。
### 3.2 前端联动逻辑
1. 打开编辑弹窗:请求批次详情(含 `outTotal`),或列表行扩展字段 `outTotal`。
2. 用户修改 `inQty`:
- 若用户**未**手工改过 `remainingQty`(`remainingQtyTouched = false`)→ `remainingQty = inQty − outTotal`
- 若 `remainingQtyTouched = true` → 不自动覆盖剩余(支持场景 B)
3. 用户修改 `remainingQty` → 设 `remainingQtyTouched = true`
4. 改 `inQty` 且未锁定金额时 → 重算 `amount = unitPrice × inQty`(与入库弹窗一致)
5. 提交前校验:
- `inQty > 0`
- `remainingQty ≥ 0`
- `remainingQty ≤ inQty`
- `inQty ≥ outTotal`(入库量不能小于已出库总量)
### 3.3 后端 `update_batch` 扩展(已实现:保留原入库 + adjust 流水)
- **原入库流水**(`change_type=in`):**不修改** `change_qty`、`amount`,仅同步编号/批号等元数据快照。
- **入库数量变化**:写入 `adjust` 流水,`change_qty = 新入库量 − 旧入库量`,备注 `编辑修正入库数量(旧 → 新)`。
- **剩余数量在入库修正之外另有差异**:再写入一条 `adjust`,`change_qty = 新剩余 − (旧剩余 + 入库量差)`,备注 `编辑修正剩余数量`。
- **出库/废弃/任务流水**:仍不修改。
### 3.4 出库流水 — 明确不改
以下记录 **只读、不 UPDATE**:
- `change_type = use`(含 `manual_out`、`task_complete`、`outbound_handover`)
- `change_type = discard`
理由:反映真实领用/废弃/任务消耗,修正入库错误不应篡改历史操作。
### 3.5 边界情况
| 情况 | 处理 |
|------|------|
| 无出库记录(`out_total = 0`) | 改 `in_qty` 时默认 `remaining = in_qty`;两字段可联动 |
| 有出库,`in_qty` 从 100 改为 1000,剩余未手工改 | `remaining` 自动 970(已出 30) |
| 有出库,仅改 `remaining`(`in_qty` 不变) | 写 adjust 流水,差值进 `material.stock_qty` |
| `in_qty` 改小到小于 `out_total` | 拒绝,400:「入库数量不能小于已出库量 {out_total}」 |
| `remaining` 改负或大于 `in_qty` | 拒绝,400 |
| 批次已删除 / 物资已停用 | 沿用现网校验 |
---
## 4. API 变更
### 4.1 批次详情(可选,推荐)
```
GET /api/admin/web/admin/qc-material-batches/{batchId}
Response 在现有字段上增加:
outTotal: number // 已出库+废弃总量
outCount: number // 出库/废弃流水条数(用于 UI 提示)
```
若暂不增详情接口,可在 `list_batches` 每行附带 `outTotal`(编辑时从列表行读取);有性能顾虑时优先详情接口。
### 4.2 更新批次
```
PUT /api/admin/web/admin/qc-material-batches/{batchId}
Body 新增可选字段:
inQty: number
remainingQty: number
```
`QcMaterialBatchUpdateBody` 增加上述两字段。
### 4.3 变动记录列表
- `change_type=adjust` 纳入筛选(变动类型下拉新增「库存调整」,`value=adjust`)
- `_row_to_dict` / 前端展示:`adjust` → Tag `warning`,文案「库存调整」;`source_type=batch_qty_edit` → 「批次数量修正」
---
## 5. 前端改造
### 5.1 文件
| 文件 | 改动 |
|------|------|
| `web-admin/src/views/quality-inspection/qc-material/index.vue` | 编辑弹窗:`inQty`/`remainingQty` 可编辑;只读展示已出库/理论剩余;联动与校验;提交 payload |
| `web-admin/src/api/qc-material.ts` | 类型与 update 入参增加字段;可选 fetchBatchDetail |
| `web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue` | 变动类型筛选项 + 展示文案 |
### 5.2 编辑弹窗布局(在现有 `form-grid-3` 内)
```
入库数量 [input-number] 剩余数量 [input-number] 已出库总量 [只读]
理论剩余 [只读,inQty−outTotal] (有差异时 el-alert 提示将写调整流水)
```
- 数量控件样式与入库弹窗 `input-number` 一致
- `form-label-tip`:「已出库总量含手动出库、废弃及任务扣减(若启用)」
### 5.3 查看弹窗
- 批次基础信息仍展示修正后的 `inQty` / `remainingQty`
- 出库明细列表不变;若存在 adjust 流水,可在「变动记录」Tab 中查看
---
## 6. 后端改造
| 文件 | 改动 |
|------|------|
| `backend/app/crud/qc_material_stock_batch.py` | `update_batch` 数量修正逻辑;`_sum_batch_out_total()` helper |
| `backend/app/api/qc.py` | `QcMaterialBatchUpdateBody` 增字段;可选 GET batch detail |
| `backend/app/crud/qc_material_usage.py` | `list_usages` 支持 `change_type=adjust` 筛选;`_row_to_dict` 展示 |
无需新增数据库表;`change_type` / `source_type` 为 varchar,新枚举值直接写入。
---
## 7. 测试要点
1. **场景 A**:入库 100,无出库 → 改 in 为 1000 → remaining=1000,stock_qty +900,入库流水 change_qty=1000,无 adjust 流水
2. **场景 A+出库**:入库 100,出库 30 → 改 in 为 1000 → remaining=970,stock_qty +900,出库 3 条不变
3. **场景 B**:in 保持 100,出库 30,remaining 从 70 改为 65 → stock_qty −5,新增 adjust 流水 change_qty=−5
4. **校验**:in 改为 20(已出 30)→ 失败
5. **校验**:remaining 改为 101(in=100)→ 失败
6. **仅改厂家/批号**:数量不变,无 adjust、无 stock_qty 变化
7. **变动记录 Tab**:adjust 类型可筛选、Tag 展示正确
---
## 8. 与盘点的关系
- **库存盘点 Tab** 仍用于周期性盘点、登记未用完物料;本能力用于**单批次事后纠错**,二者互补。
- 已完成盘点单中的 `remaining_qty` 快照**不回溯**修改。
---
## 9. 后续扩展(本 spec 不做)
- 生产物料库 / 细胞存储物料库复用同一模式
- 数量修正权限细分(如仅库管可改剩余量)
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-07
@@ -0,0 +1,38 @@
# 设计:从任务执行派发临时生产工单
## 流程
1. 用户在任务执行弹窗进入「产出(细胞产品)」。
2. 点击「派发临时工单」→ 校验原材料完整且已保存(`input` scope 无脏数据)。
3. 弹出「新增临时工单」弹窗(仅备注,与生产工单临时 Tab 一致)。
4. 确认 → 调用 `spawn-temporary-work-order` API 创建 LSSC 工单。
5. 打开 `DispatchTaskDialog`,用户填写任务名称/工艺路线并生成任务。
6. 任务创建成功 → 前端调用 `set_task_inputs` 写入 API 返回的 `inputItems`(仅原材料,不含产出)。
## 约束
- 来源任务须至少一条已持久化原材料,且每条具备 `inputType` 与编码/名称/id(**含临时生产工单来源任务**)。
- **SHALL NOT** 复制当前任务产出(细胞产品)。
- 按钮在只读下不展示(**已完成 `ywc` 任务除外:只读查看时仍展示派发**)。
## API
`POST /web/admin/production-tasks/{task_id}/spawn-temporary-work-order`
Body: `{ remark?: string }`
Response:
```json
{
"workOrder": { "id", "workOrderNo", "workOrderStatus", ... },
"sourceTaskId": "...",
"sourceTaskNo": "...",
"inputItems": [{ "inputType", "inputId", "inputCode", "inputName", "remark" }]
}
```
## UI
- 按钮:`btn-ghost` + `Position` 图标,文案「派发临时工单」,位于产出底栏「保存」左侧。
- 不可用时 `disabled` + tooltip 说明需先保存原材料。
@@ -0,0 +1,26 @@
## Why
入库/出库生产任务执行时,常需将同一批已登记原材料(样本或细胞产品)延续到一条独立的临时生产链路(如在培分支)。现状需手动新建临时工单、再派发任务、再逐条添加原材料,步骤分散且易漏。
## What Changes
- **任务执行弹窗**:在「产出(细胞产品)」底栏增加「派发临时工单」按钮;仅当原材料已填写且已保存时可操作。
- **后端 API**:`POST /web/admin/production-tasks/{id}/spawn-temporary-work-order` — 校验来源任务、读取已保存原材料、创建 LSSC 临时工单并返回复制载荷。
- **前端联动**:弹出与「新增临时工单」相同的备注弹窗;确认后打开「派发生产任务」;任务创建成功后自动 `set_task_inputs` 复制原材料(**不复制产出**)。
## Capabilities
### New Capabilities
- `spawn-temp-work-order-from-task`: 从生产任务执行上下文派发临时生产工单并复制原材料
### Modified Capabilities
(无既有 spec 需求变更)
## Impact
- `backend/app/crud/production_task.py`、`backend/app/api/production.py`、`backend/app/schemas/production_task.py`
- `web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue`
- `web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue`
- `web-admin/src/api/production-task.ts`
@@ -0,0 +1,63 @@
# spawn-temp-work-order-from-task
## Purpose
从生产任务执行弹窗「产出(细胞产品)」发起临时生产工单,并复制已保存原材料至新任务。
## Requirements
### Requirement: 产出页派发临时工单入口
任务执行弹窗(非只读,或已完成只读查看)SHALL 在「产出(细胞产品)」详情底栏提供「派发临时工单」按钮。入库、出库、**临时**生产工单下的任务均 MAY 派发;生产工单或任务状态为已完成(`ywc`)时 SHALL 仍允许派发(只读查看入口亦须可用)。
#### Scenario: 展示按钮
- **WHEN** 用户打开生产任务执行弹窗(含临时生产工单任务)并进入「产出(细胞产品)」
- **THEN** 底栏显示「派发临时工单」按钮(描边样式,带图标)
#### Scenario: 临时工单任务可继续派发
- **WHEN** 当前任务所属工单 `workOrderType` 为 `temporary`,且已保存原材料
- **THEN** 仍可点击「派发临时工单」,系统创建新的 LSSC 临时工单并复制原材料
#### Scenario: 已完成工单或任务仍可派发
- **WHEN** 生产工单或生产任务状态为 `ywc`(已完成),且任务已保存原材料
- **THEN** 在产出页仍可点击「派发临时工单」(含只读「查看」进入的执行弹窗)
### Requirement: 原材料门禁
系统 SHALL 仅在来源任务原材料已填写完整且已保存(无未保存的 `input` 变更)时允许派发;否则按钮禁用或点击后提示。
#### Scenario: 未保存原材料
- **WHEN** 原材料存在未保存修改
- **THEN** 用户无法完成派发,并提示先保存原材料
#### Scenario: 原材料为空
- **WHEN** 来源任务无任何已保存原材料
- **THEN** API 返回 400,提示先填写并保存原材料
### Requirement: 创建临时工单与复制原材料
派发确认后,系统 SHALL 创建 `work_order_type=temporary` 的生产工单(LSSC 编号);用户通过既有「派发生产任务」创建新任务后,系统 SHALL 将来源任务已保存的原材料复制至新任务 `biz_production_task_input`;SHALL NOT 复制来源任务产出(细胞产品)。
#### Scenario: 成功派发
- **WHEN** 用户填写备注并确认,随后在派发弹窗中成功创建临时工单下的生产任务
- **THEN** 新任务原材料与来源任务已保存原材料一致(样本/细胞产品类型与关联 id 一致)
#### Scenario: 不复制产出
- **WHEN** 来源任务已保存多条产出(细胞产品)
- **THEN** 新任务原材料中不包含上述产出记录
### Requirement: 新增临时工单弹窗一致
派发时弹出的备注弹窗 SHALL 与生产工单「临时」Tab「新增临时工单」交互一致(标题、备注字段、确认/取消)。
#### Scenario: 弹窗交互
- **WHEN** 用户点击「派发临时工单」且通过原材料门禁
- **THEN** 展示「新增临时工单」弹窗,确认后创建临时工单
@@ -0,0 +1,16 @@
## 1. OpenSpec & Backend
- [x] 1.1 编写 proposal / design / spec
- [x] 1.2 `spawn_temporary_work_order_from_task` CRUD + schema
- [x] 1.3 注册 `POST /production-tasks/{id}/spawn-temporary-work-order`
## 2. Frontend
- [x] 2.1 `fetchSpawnTemporaryWorkOrderFromTask` API
- [x] 2.2 `TaskExecutionDialog` 产出底栏按钮 + 临时工单弹窗
- [x] 2.3 `DispatchTaskDialog` 发出 `taskCreated` 事件并复制原材料
## 3. Verification
- [x] 3.1 更新知识图谱
- [x] 3.2 Lint 检查改动文件
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+129 -128
View File
@@ -1,11 +1,11 @@
# Graph Report - src (2026-07-07)
## Corpus Check
- Large corpus: 852 files · ~563,510 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
- Large corpus: 852 files · ~564,234 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
## Summary
- 2862 nodes · 4009 edges · 59 communities detected
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 900 edges (avg confidence: 0.8)
- 2866 nodes · 4016 edges · 58 communities detected
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 902 edges (avg confidence: 0.8)
- Token cost: 0 input · 0 output
## Community Hubs (Navigation)
@@ -46,52 +46,51 @@
- [[_COMMUNITY_Community 34|Community 34]]
- [[_COMMUNITY_Community 35|Community 35]]
- [[_COMMUNITY_Community 36|Community 36]]
- [[_COMMUNITY_Community 37|Community 37]]
- [[_COMMUNITY_Community 38|Community 38]]
- [[_COMMUNITY_Community 39|Community 39]]
- [[_COMMUNITY_Community 40|Community 40]]
- [[_COMMUNITY_Community 41|Community 41]]
- [[_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]]
- [[_COMMUNITY_Community 54|Community 54]]
- [[_COMMUNITY_Community 55|Community 55]]
- [[_COMMUNITY_Community 57|Community 57]]
- [[_COMMUNITY_Community 56|Community 56]]
- [[_COMMUNITY_Community 58|Community 58]]
- [[_COMMUNITY_Community 59|Community 59]]
- [[_COMMUNITY_Community 61|Community 61]]
- [[_COMMUNITY_Community 64|Community 64]]
- [[_COMMUNITY_Community 66|Community 66]]
- [[_COMMUNITY_Community 74|Community 74]]
- [[_COMMUNITY_Community 60|Community 60]]
- [[_COMMUNITY_Community 63|Community 63]]
- [[_COMMUNITY_Community 65|Community 65]]
- [[_COMMUNITY_Community 73|Community 73]]
- [[_COMMUNITY_Community 75|Community 75]]
- [[_COMMUNITY_Community 76|Community 76]]
- [[_COMMUNITY_Community 77|Community 77]]
## God Nodes (most connected - your core abstractions)
1. `get()` - 280 edges
1. `get()` - 281 edges
2. `push()` - 78 edges
3. `WebSocketClient` - 26 edges
4. `emit()` - 25 edges
5. `set()` - 20 edges
6. `handleDynamicRoutes()` - 18 edges
7. `parseProtocolStandardImportText()` - 17 edges
8. `MenuProcessor` - 16 edges
9. `scopeQuery()` - 15 edges
8. `scopeQuery()` - 16 edges
9. `MenuProcessor` - 16 edges
10. `TableCache` - 14 edges
## Surprising Connections (you probably didn't know these)
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
views/basic-info/customer/index.vue → utils/fullscreen-loading.ts
- `dash()` --calls--> `formatDisplayOrDash()` [INFERRED]
components/business/infusion-schedule-outbound-chain-view/index.vue → utils/datetime-display.ts
- `buildInboundMetaFields()` --calls--> `push()` [INFERRED]
utils/production-work-order-card-meta.ts → views/operations/storage-facility/index.vue
- `dash()` --calls--> `formatDisplayOrDash()` [INFERRED]
components/business/clinical-schedule-payment-detail/index.vue → utils/datetime-display.ts
- `fmtMoney()` --calls--> `formatMoneyDisplay()` [INFERRED]
components/business/clinical-schedule-payment-detail/index.vue → utils/money-format.ts
- `defaultInstallmentRatios()` --calls--> `push()` [INFERRED]
utils/protocol-payment-installment.ts → views/operations/storage-facility/index.vue
- `calcUnpaidAmountsByRatios()` --calls--> `push()` [INFERRED]
utils/protocol-payment-installment.ts → views/operations/storage-facility/index.vue
## Communities
@@ -100,108 +99,108 @@ Cohesion: 0.01
Nodes (162): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchChannelAccount() (+154 more)
### Community 1 - "Community 1"
Cohesion: 0.01
Nodes (129): fetchUploadAttachment(), fetchMyProductionTasks(), fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), FireworkSystem, handleReportUpload(), handleReportUpload() (+121 more)
Cohesion: 0.02
Nodes (84): fetchUploadAttachment(), handleReportUpload(), handleReportUpload(), walk(), buildInboundBasicSection(), buildInboundCellStorageViewSections(), buildInboundResearchDonationViewSections(), buildReceptionSection() (+76 more)
### Community 2 - "Community 2"
Cohesion: 0.03
Nodes (86): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionList(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchPilotCheckupActualItems(), fetchPilotCheckupDetail(), fetchPilotCheckupList() (+78 more)
Nodes (86): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionList(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchPilotCheckupDetail(), fetchPilotCheckupList(), markPilotCheckupChecked() (+78 more)
### Community 3 - "Community 3"
Cohesion: 0.03
Nodes (33): fetchGetMenuList(), ComponentLoader, IframeRouteManager, MenuProcessor, RouteRegistry, RouteTransformer, useAppMode(), useAuth() (+25 more)
Nodes (60): fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionProjects(), fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchCreateCheckupInstitutionProject(), fetchUpdateCheckupInstitution(), fetchUpdateCheckupInstitutionInvoice(), fetchUpdateCheckupInstitutionProject() (+52 more)
### Community 4 - "Community 4"
Cohesion: 0.03
Nodes (33): fetchGetMenuList(), ComponentLoader, IframeRouteManager, MenuProcessor, RouteRegistry, RouteTransformer, useAppMode(), useAuth() (+25 more)
### Community 5 - "Community 5"
Cohesion: 0.04
Nodes (69): formatNowDatetime(), formatTodayDate(), addPaymentDetail(), applyFqPaymentDefaults(), applyPaymentPresetForMode(), createEmptyTransport(), datetimeToYmd(), defaultInstallmentStartDateYmd() (+61 more)
### Community 5 - "Community 5"
Cohesion: 0.02
Nodes (28): fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllConsumableStockLogs(), fetchAllEquipments(), fetchAllOutputTypes(), fetchAllProcessCategories(), fetchAllProcesses(), fetchAllReagents() (+20 more)
### Community 6 - "Community 6"
Cohesion: 0.04
Nodes (49): fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionProjects(), fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchCreateCheckupInstitutionProject(), fetchUpdateCheckupInstitution(), fetchUpdateCheckupInstitutionInvoice(), fetchUpdateCheckupInstitutionProject() (+41 more)
Cohesion: 0.03
Nodes (57): fetchMyProductionTasks(), fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), fetchMineTasksForWorkOrders(), useInboundSiblingNavigation(), shouldApplyTriggerSourceFilter(), useQcWorkOrderTabPage() (+49 more)
### Community 7 - "Community 7"
Cohesion: 0.04
Nodes (47): buildInboundBasicSection(), buildInboundCellStorageViewSections(), buildInboundResearchDonationViewSections(), buildReceptionSection(), buildTransportSection(), resolveInboundProtocolStatus(), buildBaseFields(), buildInboundBasicSection() (+39 more)
Cohesion: 0.03
Nodes (58): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList(), fetchCreateProtocolInvoiceRequest(), fetchInvoiceEligiblePayments(), fetchPaymentDetailList() (+50 more)
### Community 8 - "Community 8"
Cohesion: 0.04
Nodes (40): collectIds(), useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), if() (+32 more)
Nodes (42): buildBaseFields(), buildFeeSection(), buildInboundBasicSection(), buildInboundCellStorageProductionViewSections(), buildInboundResearchDonationProductionViewSections(), buildOutboundBasicExperimentProductionViewSections(), buildOutboundClinicalProductionViewSections(), buildOutboundDetail() (+34 more)
### Community 9 - "Community 9"
Cohesion: 0.04
Nodes (45): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), handleDialogClose(), handleAdd(), handleBatchDelete() (+37 more)
Nodes (46): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), handleDialogClose(), handleAdd(), handleBatchDelete() (+38 more)
### Community 10 - "Community 10"
Cohesion: 0.04
Nodes (44): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList(), fetchCreateProtocolInvoiceRequest(), fetchInvoiceEligiblePayments(), fetchPaymentDetailList() (+36 more)
Nodes (39): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), if(), walk() (+31 more)
### Community 11 - "Community 11"
Cohesion: 0.05
Nodes (48): fetchEthnicList(), applyDonationBundleToForm(), createEmptyTransport(), ensureEthnicOptionInList(), handleOpenForAdd(), if(), loadEthnicOptions(), normalizeSampleRow() (+40 more)
### Community 12 - "Community 12"
Cohesion: 0.05
Nodes (34): fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed(), fetchClinicalRefundPending(), fetchOrderAdjusts(), fetchOrderDetail() (+26 more)
Cohesion: 0.04
Nodes (40): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchCreateMenu(), fetchDeleteCellSampleType(), fetchDeleteMenu(), fetchMenuTree(), fetchRoleOptions(), fetchUpdateCellSampleType() (+32 more)
### Community 13 - "Community 13"
Cohesion: 0.05
Nodes (37): fetchProductionReceptionBySampleCode(), fetchProductionReceptionSubmit(), fetchProductionReceptionUpdate(), onUserSelectVisible(), remoteSearchUsers(), buildPayload(), ensureDefaultHandler(), initDialog() (+29 more)
Cohesion: 0.04
Nodes (33): fetchMineProductionWorkOrderTabStepCounts(), fetchMineProductionWorkOrderTabStepCountsDeduped(), fetchProductionWorkOrderCellProductOptions(), fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList(), fetchProductionWorkOrderQcDispatchOptions(), fetchProductionWorkOrderQcInfo(), fetchProductionWorkOrderTabStepCounts() (+25 more)
### Community 14 - "Community 14"
Cohesion: 0.05
Nodes (33): qcAttachmentFullUrl(), qcDownloadAttachment(), qcPreviewAttachment(), formatHandoverUserLabel(), formatNowDatetime(), fullFileUrl(), handleDownloadAttachment(), handlePreviewAttachment() (+25 more)
Nodes (34): fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed(), fetchClinicalRefundPending(), fetchOrderAdjusts(), fetchOrderDetail() (+26 more)
### Community 15 - "Community 15"
Cohesion: 0.06
Nodes (20): fetchQcMaterialBatchList(), fetchQcMaterialBatchOptions(), fetchQcMaterialList(), fetchQcMaterialOptions(), fetchUpdateQcMaterialBatch(), fetchMarkQcMaterialUsageFullyUsed(), financeAttachmentsToUrlString(), ensureTabMounted() (+12 more)
Nodes (38): fetchUserList(), fetchAddTaskStep(), fetchCopyTaskStep(), fetchDeleteTaskStep(), fetchDispatchProductionTaskSteps(), fetchForwardProductionTask(), fetchProductionTaskDetail(), fetchProductionTaskEditorInit() (+30 more)
### Community 16 - "Community 16"
Cohesion: 0.06
Nodes (13): fetchProductionWorkOrderQcInfo(), dash(), fmtMoney(), auditorDisplay(), dash(), ensureUnitsInOptions(), expressName(), formatYm() (+5 more)
Cohesion: 0.05
Nodes (15): handleBlur(), handleFocus(), handleInput(), formatAmount(), formatAmount(), formatProtocolAmount(), dash(), fmtMoney() (+7 more)
### Community 17 - "Community 17"
Cohesion: 0.06
Nodes (24): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchRoleOptions(), fetchUpdateMenu(), postorder(), preorder(), applyTreeExpand() (+16 more)
Cohesion: 0.04
Nodes (21): fetchAvailableMaterialBatches(), fetchMyProductionMaterialConsumptions(), fetchMyProductionMaterialUsageList(), fetchProductionMaterialBatchList(), fetchProductionMaterialBatchOptions(), fetchProductionMaterialConsumptions(), fetchProductionMaterialFormula(), fetchProductionMaterialLinkedStepUsages() (+13 more)
### Community 18 - "Community 18"
Cohesion: 0.06
Nodes (22): fetchQcMaterialBatchDetail(), fetchQcMaterialBatchList(), fetchQcMaterialBatchOptions(), fetchQcMaterialList(), fetchQcMaterialOptions(), fetchUpdateQcMaterialBatch(), fetchMarkQcMaterialUsageFullyUsed(), financeAttachmentsToUrlString() (+14 more)
### Community 19 - "Community 19"
Cohesion: 0.09
Nodes (36): attachmentFullUrl(), dash(), handleAttachmentDownload(), handleAttachmentPreview(), buildPaymentFlowSteps(), dash(), formatAmount(), hasFinanceReceipt() (+28 more)
### Community 20 - "Community 20"
Cohesion: 0.1
Nodes (2): WebSocketClient, TableCache
### Community 19 - "Community 19"
### Community 21 - "Community 21"
Cohesion: 0.08
Nodes (33): fetchRefreshToken(), toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url() (+25 more)
### Community 20 - "Community 20"
### Community 22 - "Community 22"
Cohesion: 0.09
Nodes (8): getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager, validateStorageData()
### Community 21 - "Community 21"
Cohesion: 0.08
Nodes (31): fetchUserList(), fetchAddTaskStep(), fetchCopyTaskStep(), fetchDeleteTaskStep(), fetchDispatchProductionTaskSteps(), fetchForwardProductionTask(), fetchProductionTaskDetail(), fetchProductionTaskEditorInit() (+23 more)
### Community 22 - "Community 22"
### Community 23 - "Community 23"
Cohesion: 0.08
Nodes (20): createEmptySnapshots(), normalizeConfiguredReagents(), normalizeConsumables(), normalizeDataCollections(), normalizeReagents(), normalizeStepOutputs(), serializeAttachments(), serializeEquipmentIds() (+12 more)
### Community 23 - "Community 23"
Cohesion: 0.07
Nodes (14): handleBlur(), handleFocus(), handleInput(), formatAmount(), formatAmount(), formatProtocolAmount(), buildFeeSection(), formatInvoiceAmount() (+6 more)
### Community 24 - "Community 24"
Cohesion: 0.07
Nodes (19): fetchDeleteMaterialBatch(), fetchMaterialBatchList(), fetchMaterialBatchOptions(), fetchMaterialList(), fetchMaterialOptions(), fetchUpdateMaterialBatch(), fetchMaterialUsageList(), fetchMyMaterialUsageList() (+11 more)
Cohesion: 0.08
Nodes (18): fetchProductionReceptionBySampleCode(), fetchProductionReceptionSubmit(), fetchProductionReceptionUpdate(), onUserSelectVisible(), remoteSearchUsers(), buildPayload(), ensureDefaultHandler(), initDialog() (+10 more)
### Community 25 - "Community 25"
Cohesion: 0.09
Nodes (27): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), handleBatchComplete(), handleBatchStart(), handleBatchVoid() (+19 more)
Nodes (28): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), clearTableSelection(), handleBatchComplete(), handleBatchStart() (+20 more)
### Community 26 - "Community 26"
Cohesion: 0.09
Nodes (22): fetchMineProductionWorkOrderTabStepCounts(), fetchMineProductionWorkOrderTabStepCountsDeduped(), fetchProductionWorkOrderCellProductOptions(), fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList(), fetchProductionWorkOrderQcDispatchOptions(), fetchProductionWorkOrderTabStepCounts(), fetchProductionWorkOrderTabStepCountsDeduped() (+14 more)
Cohesion: 0.07
Nodes (19): fetchDeleteMaterialBatch(), fetchMaterialBatchList(), fetchMaterialBatchOptions(), fetchMaterialList(), fetchMaterialOptions(), fetchUpdateMaterialBatch(), fetchMaterialUsageList(), fetchMyMaterialUsageList() (+11 more)
### Community 27 - "Community 27"
Cohesion: 0.12
@@ -216,164 +215,166 @@ Cohesion: 0.12
Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
### Community 30 - "Community 30"
Cohesion: 0.11
Nodes (11): fetchOutboundReleaseMaterial(), fetchOutboundReleaseReviewDetail(), fetchOutboundReleaseReviewList(), fetchReleaseReviewList(), handleReset(), handleSearch(), handleToggleSelect(), loadData() (+3 more)
### Community 31 - "Community 31"
Cohesion: 0.13
Nodes (18): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchDeleteCellSampleType(), fetchUpdateCellSampleType(), handleAdd(), handleDelete(), handleDropdownCommand(), handleEdit() (+10 more)
### Community 32 - "Community 32"
Cohesion: 0.19
Nodes (15): fetchAttachmentDownloadUrl(), attachmentFullUrl(), ensureUniqueZipEntryName(), fetchAttachmentBlob(), getAttachmentExtension(), resolveAttachmentFileName(), sanitizeZipPathSegment(), applyInboundLabStorageCodePrefix() (+7 more)
### Community 33 - "Community 33"
### Community 31 - "Community 31"
Cohesion: 0.12
Nodes (12): fetchApproveTask(), fetchBusinessAllTasks(), fetchCompletedTasks(), fetchDesignerData(), fetchInstanceDetail(), fetchMyInstances(), fetchPendingTasks(), fetchProcessDefList() (+4 more)
### Community 32 - "Community 32"
Cohesion: 0.16
Nodes (14): fetchCreateEnvDetectItem(), fetchDeleteEnvDetectItem(), fetchEnvDetectItemDetail(), fetchEnvDetectItemList(), fetchEnvDetectItemsActive(), fetchUpdateEnvDetectItem(), handleAdd(), handleBatchDelete() (+6 more)
### Community 34 - "Community 34"
### Community 33 - "Community 33"
Cohesion: 0.16
Nodes (10): useTable(), useTableImpl(), getColumnChecks(), useTableColumns(), createErrorHandler(), createSmartDebounce(), defaultResponseAdapter(), extractPagination() (+2 more)
### Community 35 - "Community 35"
### Community 34 - "Community 34"
Cohesion: 0.27
Nodes (14): useChart(), useChartComponent(), useChartOps(), colourBlend(), getCssVar(), getDarkColor(), getLightColor(), handleElementThemeColor() (+6 more)
### Community 36 - "Community 36"
Cohesion: 0.33
Nodes (13): buildProtocolPaymentFlowSteps(), dash(), financeReceiptTime(), formatAmount(), hasFinanceReceipt(), hasFinanceRefund(), hasReceiptSubmit(), hasRefundSubmit() (+5 more)
### Community 37 - "Community 37"
### Community 35 - "Community 35"
Cohesion: 0.19
Nodes (6): fetchServiceOrderTxnList(), handleReset(), handleSearch(), handleTabChange(), loadData(), switchTab()
### Community 39 - "Community 39"
### Community 36 - "Community 36"
Cohesion: 0.24
Nodes (8): fullFileUrl(), handlePreviewAttachment(), isVideoFile(), normalizeDisplayValue(), resolveReviewCellType(), resolveReviewQuantity(), resolveReviewSpecText(), uniqueJoined()
### Community 38 - "Community 38"
Cohesion: 0.15
Nodes (4): fetchNextDonationSampleCode(), fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList()
### Community 40 - "Community 40"
Cohesion: 0.24
Nodes (4): addMaterialRow(), nextMaterialRowKey(), onRequisitionSelect(), removeMaterialRow()
### Community 41 - "Community 41"
### Community 39 - "Community 39"
Cohesion: 0.25
Nodes (2): handleTouchEnd(), setTransition()
### Community 43 - "Community 43"
Cohesion: 0.31
Nodes (4): annotateForkEdges(), chainApiToElements(), walkAncestorBranch(), walkAncestorParents()
### Community 45 - "Community 45"
### Community 40 - "Community 40"
Cohesion: 0.28
Nodes (4): fetchMyProductionMaterialConsumptions(), handleReset(), handleSearch(), loadData()
Nodes (1): FireworkSystem
### Community 47 - "Community 47"
### Community 44 - "Community 44"
Cohesion: 0.39
Nodes (6): isIgnorableScriptError(), normalizeErrorMessage(), registerPromiseErrorHandler(), registerResourceErrorHandler(), scriptErrorHandler(), setupErrorHandle()
### Community 48 - "Community 48"
### Community 45 - "Community 45"
Cohesion: 0.36
Nodes (1): TableHeightCalculator
### Community 50 - "Community 50"
### Community 47 - "Community 47"
Cohesion: 0.33
Nodes (2): logApiCryptoBootInfo(), maskSecret()
### Community 51 - "Community 51"
### Community 48 - "Community 48"
Cohesion: 0.38
Nodes (4): handleFocus(), handleInput(), parseDecimalToNumber(), sanitizeDecimalInput()
### Community 52 - "Community 52"
### Community 49 - "Community 49"
Cohesion: 0.4
Nodes (2): isUnfinishedQcWorkOrder(), resolveQcWorkOrderUnfinishedBadgeCount()
### Community 53 - "Community 53"
### Community 50 - "Community 50"
Cohesion: 0.47
Nodes (3): isPaymentDueWithinWarnWindow(), parsePaymentDueYmd(), startOfLocalDay()
### Community 54 - "Community 54"
### Community 51 - "Community 51"
Cohesion: 0.5
Nodes (2): formatProtocolDocDeleteConfirm(), formatProtocolDocSubject()
### Community 55 - "Community 55"
### Community 52 - "Community 52"
Cohesion: 0.5
Nodes (2): parseEquipmentIds(), syncEquipmentNamesFromOptions()
### Community 57 - "Community 57"
### Community 54 - "Community 54"
Cohesion: 0.5
Nodes (2): focusInput(), handleKeydown()
### Community 59 - "Community 59"
### Community 56 - "Community 56"
Cohesion: 0.67
Nodes (2): if(), logSidebarMenu()
### Community 61 - "Community 61"
### Community 58 - "Community 58"
Cohesion: 0.5
Nodes (1): fetchStorageEntrySmsList()
### Community 59 - "Community 59"
Cohesion: 0.5
Nodes (1): fetchSampleSmsNotificationList()
### Community 64 - "Community 64"
### Community 60 - "Community 60"
Cohesion: 0.5
Nodes (1): fetchQcSmsList()
### Community 63 - "Community 63"
Cohesion: 1.0
Nodes (2): getSettingDefaults(), resetToDefaults()
### Community 66 - "Community 66"
### Community 65 - "Community 65"
Cohesion: 1.0
Nodes (2): copyTextToClipboard(), copyTextWithFallback()
### Community 74 - "Community 74"
### Community 73 - "Community 73"
Cohesion: 1.0
Nodes (2): emptyTabCounts(), useProductionWorkOrderTabStepCounts()
### Community 76 - "Community 76"
### Community 75 - "Community 75"
Cohesion: 1.0
Nodes (2): initialProgress(), useQcWorkOrderAttachmentExport()
### Community 77 - "Community 77"
### Community 76 - "Community 76"
Cohesion: 1.0
Nodes (2): emptyTabCounts(), useQcWorkOrderTabUnfinishedCounts()
## Knowledge Gaps
- **Thin community `Community 18`** (42 nodes): `WebSocketClient`, `.calculateReconnectDelay()`, `.clearAllTimers()`, `.clearConnectionTimers()`, `.clearTimer()`, `.close()`, `.closeCurrentSocketForReconnect()`, `.connect()`, `.connectionStatusText()`, `.constructor()`, `.destroyInstance()`, `.flushMessageQueue()`, `.getInstance()`, `.getReadyStateText()`, `.handleClose()`, `.handleConnectionTimeout()`, `.handleError()`, `.handleMessage()`, `.handleOpen()`, `.init()`, `.isWebSocketConnected()`, `.reconnect()`, `.resetHeartbeat()`, `.send()`, `.startHeartbeat()`, `.startPing()`, `TableCache`, `.cleanupExpired()`, `.clear()`, `.clearByTags()`, `.clearCurrentSearch()`, `.clearPagination()`, `.constructor()`, `.evictLRU()`, `.generateKey()`, `.generateTags()`, `.get()`, `.getStats()`, `.log()`, `.set()`, `index.ts`, `tableCache.ts`
- **Thin community `Community 20`** (42 nodes): `WebSocketClient`, `.calculateReconnectDelay()`, `.clearAllTimers()`, `.clearConnectionTimers()`, `.clearTimer()`, `.close()`, `.closeCurrentSocketForReconnect()`, `.connect()`, `.connectionStatusText()`, `.constructor()`, `.destroyInstance()`, `.flushMessageQueue()`, `.getInstance()`, `.getReadyStateText()`, `.handleClose()`, `.handleConnectionTimeout()`, `.handleError()`, `.handleMessage()`, `.handleOpen()`, `.init()`, `.isWebSocketConnected()`, `.reconnect()`, `.resetHeartbeat()`, `.send()`, `.startHeartbeat()`, `.startPing()`, `TableCache`, `.cleanupExpired()`, `.clear()`, `.clearByTags()`, `.clearCurrentSearch()`, `.clearPagination()`, `.constructor()`, `.evictLRU()`, `.generateKey()`, `.generateTags()`, `.get()`, `.getStats()`, `.log()`, `.set()`, `index.ts`, `tableCache.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 41`** (9 nodes): `cleanupEventListeners()`, `handleTouchEnd()`, `handleTouchMove()`, `handleTouchStart()`, `handleWheelScroll()`, `if()`, `setTransition()`, `setupEventListeners()`, `index.vue`
- **Thin community `Community 39`** (9 nodes): `cleanupEventListeners()`, `handleTouchEnd()`, `handleTouchMove()`, `handleTouchStart()`, `handleWheelScroll()`, `if()`, `setTransition()`, `setupEventListeners()`, `index.vue`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 48`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
- **Thin community `Community 40`** (9 nodes): `FireworkSystem`, `.constructor()`, `.createFirework()`, `.createParticle()`, `.getAvailableParticle()`, `.initializePool()`, `.preloadAllImages()`, `.preloadImage()`, `index.vue`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 50`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
- **Thin community `Community 45`** (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 52`** (6 nodes): `formatQcWorkOrderUnfinishedBadgeCount()`, `isUnfinishedQcWorkOrder()`, `qcWorkOrderUnfinishedBadgeTitle()`, `resolveQcWorkOrderUnfinishedBadgeCount()`, `sumQcWorkOrderGroupUnfinishedBadgeCount()`, `qc-work-order-unfinished-badge.ts`
- **Thin community `Community 47`** (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 54`** (5 nodes): `formatProtocolDocBatchDeleteConfirm()`, `formatProtocolDocDeleteConfirm()`, `formatProtocolDocSubject()`, `getProtocolDocTypeLabel()`, `protocol-doc-label.ts`
- **Thin community `Community 49`** (6 nodes): `formatQcWorkOrderUnfinishedBadgeCount()`, `isUnfinishedQcWorkOrder()`, `qcWorkOrderUnfinishedBadgeTitle()`, `resolveQcWorkOrderUnfinishedBadgeCount()`, `sumQcWorkOrderGroupUnfinishedBadgeCount()`, `qc-work-order-unfinished-badge.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 55`** (5 nodes): `equipmentOptionLabel()`, `joinEquipmentIds()`, `parseEquipmentIds()`, `syncEquipmentNamesFromOptions()`, `equipment-select.ts`
- **Thin community `Community 51`** (5 nodes): `formatProtocolDocBatchDeleteConfirm()`, `formatProtocolDocDeleteConfirm()`, `formatProtocolDocSubject()`, `getProtocolDocTypeLabel()`, `protocol-doc-label.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 57`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
- **Thin community `Community 52`** (5 nodes): `equipmentOptionLabel()`, `joinEquipmentIds()`, `parseEquipmentIds()`, `syncEquipmentNamesFromOptions()`, `equipment-select.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 59`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
- **Thin community `Community 54`** (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 61`** (4 nodes): `fetchGenerateSms()`, `fetchSampleSmsNotificationList()`, `fetchToggleSmsNotified()`, `sample-sms-notification.ts`
- **Thin community `Community 56`** (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 64`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
- **Thin community `Community 58`** (4 nodes): `fetchGenerateStorageEntrySms()`, `fetchStorageEntrySmsList()`, `fetchToggleStorageEntrySmsNotified()`, `storage-entry-sms-notification.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 66`** (3 nodes): `copyTextToClipboard()`, `copyTextWithFallback()`, `copy-text.ts`
- **Thin community `Community 59`** (4 nodes): `fetchGenerateSms()`, `fetchSampleSmsNotificationList()`, `fetchToggleSmsNotified()`, `sample-sms-notification.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 74`** (3 nodes): `emptyTabCounts()`, `useProductionWorkOrderTabStepCounts()`, `useProductionWorkOrderTabStepCounts.ts`
- **Thin community `Community 60`** (4 nodes): `fetchGenerateQcSms()`, `fetchQcSmsList()`, `fetchToggleQcSmsNotified()`, `qc-sms-notification.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 76`** (3 nodes): `initialProgress()`, `useQcWorkOrderAttachmentExport()`, `useQcWorkOrderAttachmentExport.ts`
- **Thin community `Community 63`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 77`** (3 nodes): `emptyTabCounts()`, `useQcWorkOrderTabUnfinishedCounts()`, `useQcWorkOrderTabUnfinishedCounts.ts`
- **Thin community `Community 65`** (3 nodes): `copyTextToClipboard()`, `copyTextWithFallback()`, `copy-text.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 73`** (3 nodes): `emptyTabCounts()`, `useProductionWorkOrderTabStepCounts()`, `useProductionWorkOrderTabStepCounts.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 75`** (3 nodes): `initialProgress()`, `useQcWorkOrderAttachmentExport()`, `useQcWorkOrderAttachmentExport.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 76`** (3 nodes): `emptyTabCounts()`, `useQcWorkOrderTabUnfinishedCounts()`, `useQcWorkOrderTabUnfinishedCounts.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 2`, `Community 4`, `Community 5`, `Community 6`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 15`, `Community 16`, `Community 17`, `Community 21`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 30`, `Community 31`, `Community 33`, `Community 37`, `Community 39`, `Community 43`, `Community 45`, `Community 61`?**
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 5`, `Community 6`, `Community 7`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 17`, `Community 18`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 31`, `Community 32`, `Community 35`, `Community 38`, `Community 58`, `Community 59`, `Community 60`?**
_High betweenness centrality (0.273) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 1` to `Community 0`, `Community 2`, `Community 4`, `Community 6`, `Community 7`, `Community 8`, `Community 10`, `Community 11`, `Community 13`, `Community 14`, `Community 16`, `Community 17`, `Community 18`, `Community 19`, `Community 21`, `Community 22`, `Community 25`, `Community 26`, `Community 28`, `Community 32`, `Community 40`?**
_High betweenness centrality (0.264) - this node is a cross-community bridge._
- **Why does `handleDynamicRoutes()` connect `Community 3` to `Community 8`, `Community 26`, `Community 27`, `Community 28`?**
_High betweenness centrality (0.042) - this node is a cross-community bridge._
- **Are the 279 inferred relationships involving `get()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
_`get()` has 279 INFERRED edges - model-reasoned connections that need verification._
- **Why does `push()` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 10`, `Community 11`, `Community 13`, `Community 15`, `Community 19`, `Community 20`, `Community 21`, `Community 23`, `Community 25`, `Community 28`, `Community 30`, `Community 40`?**
_High betweenness centrality (0.255) - this node is a cross-community bridge._
- **Why does `fetchNotDeletedRegions()` connect `Community 0` to `Community 1`?**
_High betweenness centrality (0.034) - this node is a cross-community bridge._
- **Are the 280 inferred relationships involving `get()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
_`get()` has 280 INFERRED edges - model-reasoned connections that need verification._
- **Are the 77 inferred relationships involving `push()` (e.g. with `refreshQcMenuBadges()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
_`push()` has 77 INFERRED edges - model-reasoned connections that need verification._
- **Are the 24 inferred relationships involving `emit()` (e.g. with `handleSubmit()` and `handleDialogClose()`) actually correct?**
+4 -4
View File
@@ -57,12 +57,12 @@
</div>
<div id="legend"></div>
</div>
<div id="stats">2862 nodes &middot; 4009 edges &middot; 337 communities</div>
<div id="stats">2866 nodes &middot; 4016 edges &middot; 336 communities</div>
</div>
<script>
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 50, "community_name": "Community 50", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 50, "community_name": "Community 50", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 50, "community_name": "Community 50", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 50, "community_name": "Community 50", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 50, "community_name": "Community 50", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 50, "community_name": "Community 50", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 113, "community_name": "Community 113", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 114, "community_name": "Community 114", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 29, "community_name": "Community 29", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 29, "community_name": "Community 29", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 29, "community_name": "Community 29", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 29, "community_name": "Community 29", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 29, "community_name": "Community 29", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_setuprolesdirective",Line 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": 441}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 216}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 117}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 94}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 91}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 88}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 81}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 79}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 75}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 70}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 69}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 66}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 61}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 59}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 53}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 44}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 43}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 43}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 42}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 41}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 37}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 37}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 36}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 36}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 35}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 34}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 34}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 28}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 25}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 22}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 22}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 22}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 20}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 19}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 17}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 16}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 14}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 14}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 13}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 13}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 10}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 9}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 9}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 9}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 9}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 9}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 9}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 8}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 8}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 8}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 7}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 7}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 6}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 6}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 5}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 5}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 5}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 5}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 4}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 4}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 4}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 4}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 4}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 4}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 3}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 3}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 3}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 3}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 3}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 3}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "cLine truncated
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 47, "community_name": "Community 47", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 47, "community_name": "Community 47", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 47, "community_name": "Community 47", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 47, "community_name": "Community 47", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 47, "community_name": "Community 47", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 47, "community_name": "Community 47", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 112, "community_name": "Community 112", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 113, "community_name": "Community 113", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 29, "community_name": "Community 29", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 29, "community_name": "Community 29", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 29, "community_name": "Community 29", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 29, "community_name": "Community 29", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 29, "community_name": "Community 29", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_setuprolesdirective",Line 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": 466}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 144}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 119}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 103}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 94}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 91}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 89}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 89}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 72}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 72}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 70}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 66}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 65}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 62}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 61}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 51}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 50}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 48}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 46}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 43}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 42}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 41}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 37}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 36}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 36}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 35}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 35}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 28}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 25}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 22}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 20}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 19}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 19}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 17}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 16}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 14}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 13}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 13}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 13}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 9}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 9}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 9}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 9}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 9}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 8}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 8}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 8}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 7}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 7}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 6}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 6}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 5}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 5}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 5}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 5}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 4}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 4}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 4}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 4}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 4}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 4}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 4}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 4}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 3}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 3}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 3}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 3}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 3}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 3}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 3}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "coLine truncated
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
function esc(s) {
File diff suppressed because it is too large. Load diff
+9 -9
View File
@@ -17,8 +17,8 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/common/index.ts": 1781272556.3597305,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/directive/directive.d.ts": 1781272556.3601494,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/api/api.d.ts": 1781272556.3606477,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1783394766.287882,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1783394698.1355608,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1783428533.0117855,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1783428029.977557,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/store/index.ts": 1781272556.364766,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/router/index.ts": 1782394569.8806834,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentDropZone.ts": 1782873161.9839864,
@@ -300,10 +300,10 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-task.ts": 1783327864.9737554,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-item-param.ts": 1782446790.5508618,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/env-detect-item.ts": 1781272556.668322,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts": 1783305570.9180024,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts": 1783402792.460588,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-stock-check.ts": 1781424012.5471919,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-usage.ts": 1781424013.8349903,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts": 1781690334.9639037,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts": 1783428526.370803,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-sms-notification.ts": 1781272556.670129,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/system.ts": 1782802585.0325377,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material.ts": 1782894693.658258,
@@ -396,17 +396,17 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/reagent/index.vue": 1783326448.9403174,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue": 1782893853.82419,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionStepBadge.vue": 1783307223.0443783,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts": 1783393558.504367,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts": 1783402793.260901,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/StepDetailPanel.vue": 1782893853.2023683,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/CompleteProductionTaskDialog.vue": 1782893853.1254928,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskInputEnhancedTable.vue": 1782893853.0951817,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchQcWorkOrderDialog.vue": 1782893852.9989007,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/SampleReceptionDialog.vue": 1782894085.3789353,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskEquipmentPanel.vue": 1782893853.803821,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue": 1783395073.68483,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue": 1783403211.24666,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue": 1782893853.6561613,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskOutputList.vue": 1783395073.7065923,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue": 1782893853.4321866,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue": 1783402801.3269055,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskPaperAttachmentsPanel.vue": 1782893853.2361045,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/WorkOrderTaskSubList.vue": 1782893853.2094715,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskOutputProductDialog.vue": 1783395103.1997178,
@@ -504,9 +504,9 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/index.vue": 1782893853.832618,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/ThirdPartyCompanyTab.vue": 1783326448.9753742,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/my-qc-material-usage/index.vue": 1782893853.6503608,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue": 1783326448.9782045,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue": 1783428546.2955363,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialStockCheckTab.vue": 1783326448.981454,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue": 1783326448.9838498,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue": 1783428549.951238,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialBatchAttachmentDialog.vue": 1782893853.076457,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/index.vue": 1783326448.9852715,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue": 1783391495.9213836,
+30
View File
@@ -282,6 +282,36 @@ export function fetchSetTaskInputs(
})
}
export interface SpawnTemporaryWorkOrderResult {
workOrder: {
id: string
workOrderNo: string
workOrderStatus: string
remark?: string
}
sourceTaskId: string
sourceTaskNo: string
inputItems: Array<{
inputType: string
inputId?: string
inputCode?: string
inputName?: string
remark?: string
}>
}
export function fetchSpawnTemporaryWorkOrderFromTask(
taskId: string,
data: { remark?: string },
operateScope?: ProductionTaskOperateScope
) {
return request.post<SpawnTemporaryWorkOrderResult>({
url: `/web/admin/production-tasks/${taskId}/spawn-temporary-work-order`,
data,
params: scopeQuery(operateScope)
})
}
export function fetchSetTaskOutputs(
taskId: string,
data: any[] | Record<string, any>,
+8
View File
@@ -44,6 +44,8 @@ export type QcMaterialBatch = {
amount: number
inQty: number
remainingQty: number
outTotal?: number
outCount?: number
qcAttachmentUrls?: string
stockQty: number
warningQty: number
@@ -118,6 +120,12 @@ export function fetchQcMaterialBatchList(params?: {
})
}
export function fetchQcMaterialBatchDetail(batchId: string) {
return request.get<QcMaterialBatch>({
url: `/web/admin/qc-material-batches/${batchId}`
})
}
export function fetchQcMaterialBatchOptions(params?: {
keyword?: string
materialId?: string
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "label": "TaskExecutionDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L1"}, {"id": "production_work_order_taskexecutiondialog_onsteplistdrop", "label": "onStepListDrop()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L769"}, {"id": "production_work_order_taskexecutiondialog_handleforwardsuccess", "label": "handleForwardSuccess()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L774"}, {"id": "production_work_order_taskexecutiondialog_openforwarddialog", "label": "openForwardDialog()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L780"}, {"id": "production_work_order_taskexecutiondialog_savetaskoutputsmanual", "label": "saveTaskOutputsManual()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L785"}, {"id": "production_work_order_taskexecutiondialog_savetaskattachmentsmanual", "label": "saveTaskAttachmentsManual()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L789"}, {"id": "production_work_order_taskexecutiondialog_savetaskequipmentmanual", "label": "saveTaskEquipmentManual()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L793"}, {"id": "production_work_order_taskexecutiondialog_handlespawntemporaryworkorderclick", "label": "handleSpawnTemporaryWorkOrderClick()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L797"}, {"id": "production_work_order_taskexecutiondialog_submitspawntemporary", "label": "submitSpawnTemporary()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L808"}, {"id": "production_work_order_taskexecutiondialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L847"}, {"id": "production_work_order_taskexecutiondialog_stepseqclass", "label": "stepSeqClass()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L866"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "target": "production_work_order_taskexecutiondialog_onsteplistdrop", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L769", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "target": "production_work_order_taskexecutiondialog_handleforwardsuccess", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L774", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "target": "production_work_order_taskexecutiondialog_openforwarddialog", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L780", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "target": "production_work_order_taskexecutiondialog_savetaskoutputsmanual", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L785", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "target": "production_Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "label": "useTaskStepEditor.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L1"}, {"id": "production_work_order_usetaskstepeditor_parsetaskattachmentsfromurls", "label": "parseTaskAttachmentsFromUrls()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L67"}, {"id": "production_work_order_usetaskstepeditor_toapiflag", "label": "toApiFlag()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L77"}, {"id": "production_work_order_usetaskstepeditor_fromapiflag", "label": "fromApiFlag()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L81"}, {"id": "production_work_order_usetaskstepeditor_normalizestepsubtables", "label": "normalizeStepSubTables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L84"}, {"id": "production_work_order_usetaskstepeditor_parseordernum", "label": "parseOrderNum()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L111"}, {"id": "production_work_order_usetaskstepeditor_usetaskstepeditor", "label": "useTaskStepEditor()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L118"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_production_step_assignee", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L20", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L21", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_admin", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L30", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L31", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_sample_reception", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L32", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_usetaskstepeditor_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_equipment_select", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts", "source_location": "L33", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_prodLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task_ts", "label": "production-task.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L1"}, {"id": "api_production_task_scopequery", "label": "scopeQuery()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L5"}, {"id": "api_production_task_fetchcreateproductiontask", "label": "fetchCreateProductionTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L9"}, {"id": "api_production_task_fetchproductiontasklist", "label": "fetchProductionTaskList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L13"}, {"id": "api_production_task_fetchproductiontasksbyworkorderids", "label": "fetchProductionTasksByWorkOrderIds()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L33"}, {"id": "api_production_task_groupproductiontasksbyworkorderid", "label": "groupProductionTasksByWorkOrderId()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L54"}, {"id": "api_production_task_fetchmyproductiontasks", "label": "fetchMyProductionTasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L67"}, {"id": "api_production_task_fetchforwardproductiontask", "label": "fetchForwardProductionTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L90"}, {"id": "api_production_task_fetchreassignproductiontask", "label": "fetchReassignProductionTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L102"}, {"id": "api_production_task_fetchdispatchproductiontasksteps", "label": "fetchDispatchProductionTaskSteps()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L112"}, {"id": "api_production_task_fetchproductiontaskdetail", "label": "fetchProductionTaskDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L130"}, {"id": "api_production_task_fetchproductiontaskeditorinit", "label": "fetchProductionTaskEditorInit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L154"}, {"id": "api_production_task_fetchupdateproductiontask", "label": "fetchUpdateProductionTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L165"}, {"id": "api_production_task_fetchupdateproductiontaskstatus", "label": "fetchUpdateProductionTaskStatus()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L169"}, {"id": "api_production_task_fetchdeleteproductiontask", "label": "fetchDeleteProductionTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L181"}, {"id": "api_production_task_fetchaddtaskstep", "label": "fetchAddTaskStep()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L185"}, {"id": "api_production_task_fetchupdatetaskstep", "label": "fetchUpdateTaskStep()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L197"}, {"id": "api_production_task_fetchdeletetaskstep", "label": "fetchDeleteTaskStep()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L210"}, {"id": "api_production_task_fetchreplacestepreagents", "label": "fetchReplaceStepReagents()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L221"}, {"id": "api_production_task_fetchreplacestepconsumables", "label": "fetchReplaceStepConsumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L234"}, {"id": "api_production_task_fetchreplacestepconfiguredreagents", "label": "fetchReplaceStepConfiguredReagents()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L247"}, {"id": "api_production_task_fetchreplacestepdatacollection", "label": "fetchReplLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "label": "TaskExecutionDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L1"}, {"id": "production_work_order_taskexecutiondialog_onsteplistdrop", "label": "onStepListDrop()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L760"}, {"id": "production_work_order_taskexecutiondialog_handleforwardsuccess", "label": "handleForwardSuccess()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L765"}, {"id": "production_work_order_taskexecutiondialog_openforwarddialog", "label": "openForwardDialog()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L771"}, {"id": "production_work_order_taskexecutiondialog_savetaskoutputsmanual", "label": "saveTaskOutputsManual()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L776"}, {"id": "production_work_order_taskexecutiondialog_savetaskattachmentsmanual", "label": "saveTaskAttachmentsManual()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L780"}, {"id": "production_work_order_taskexecutiondialog_savetaskequipmentmanual", "label": "saveTaskEquipmentManual()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L784"}, {"id": "production_work_order_taskexecutiondialog_handlespawntemporaryworkorderclick", "label": "handleSpawnTemporaryWorkOrderClick()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L788"}, {"id": "production_work_order_taskexecutiondialog_submitspawntemporary", "label": "submitSpawnTemporary()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L799"}, {"id": "production_work_order_taskexecutiondialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L838"}, {"id": "production_work_order_taskexecutiondialog_stepseqclass", "label": "stepSeqClass()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L857"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "target": "production_work_order_taskexecutiondialog_onsteplistdrop", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L760", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "target": "production_work_order_taskexecutiondialog_handleforwardsuccess", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L765", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "target": "production_work_order_taskexecutiondialog_openforwarddialog", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L771", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "target": "production_work_order_taskexecutiondialog_savetaskoutputsmanual", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue", "source_location": "L776", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_taskexecutiondialog_vue", "target": "production_Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1"}, {"id": "qc_material_index_ensuretabmounted", "label": "ensureTabMounted()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1263"}, {"id": "qc_material_index_handletabchange", "label": "handleTabChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1268"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1200", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1201", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_system_view_dialog_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1216", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_common_amount_input_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1217", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_money_format", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1218", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_material_ui", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1219", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_admin", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1220", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1221", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1234", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_usage", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue", "source_location": "L1235", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_constants_material_discard", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/qualityLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_dispatchtaskdialog_vue", "label": "DispatchTaskDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L1"}, {"id": "production_work_order_dispatchtaskdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L442"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_dispatchtaskdialog_vue", "target": "production_work_order_dispatchtaskdialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L442", "weight": 1.0}], "raw_calls": [{"caller_nid": "production_work_order_dispatchtaskdialog_if", "callee": "enterEditPhase", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue", "source_location": "L445"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_qcmaterialusagetab_vue", "label": "QcMaterialUsageTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L1"}, {"id": "qc_material_qcmaterialusagetab_ismanualoutrow", "label": "isManualOutRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L436"}, {"id": "qc_material_qcmaterialusagetab_isdiscardrow", "label": "isDiscardRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L442"}, {"id": "qc_material_qcmaterialusagetab_parsefromremark", "label": "parseFromRemark()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L446"}, {"id": "qc_material_qcmaterialusagetab_displayreceiver", "label": "displayReceiver()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L455"}, {"id": "qc_material_qcmaterialusagetab_displaypurpose", "label": "displayPurpose()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L461"}, {"id": "qc_material_qcmaterialusagetab_displayusetime", "label": "displayUseTime()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L467"}, {"id": "qc_material_qcmaterialusagetab_displayusageqty", "label": "displayUsageQty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L473"}, {"id": "qc_material_qcmaterialusagetab_displaytaskusageqty", "label": "displayTaskUsageQty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L479"}, {"id": "qc_material_qcmaterialusagetab_displayqctaskno", "label": "displayQcTaskNo()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L483"}, {"id": "qc_material_qcmaterialusagetab_displaystockbefore", "label": "displayStockBefore()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L488"}, {"id": "qc_material_qcmaterialusagetab_getchangetypelabel", "label": "getChangeTypeLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L495"}, {"id": "qc_material_qcmaterialusagetab_getchangetypetagtype", "label": "getChangeTypeTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L503"}, {"id": "qc_material_qcmaterialusagetab_getsourcetagtype", "label": "getSourceTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L511"}, {"id": "qc_material_qcmaterialusagetab_getsourcelabel", "label": "getSourceLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L521"}, {"id": "qc_material_qcmaterialusagetab_canmarkfullyused", "label": "canMarkFullyUsed()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L533"}, {"id": "qc_material_qcmaterialusagetab_handlemarkfullyused", "label": "handleMarkFullyUsed()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L537"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_material_qcmaterialusagetab_vue", "target": "qc_material_qcmaterialusagetab_ismanualoutrow", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue", "source_location": "L436", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admiLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_ts", "label": "qc-material.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L1"}, {"id": "api_qc_material_fetchqcmaterialbatchlist", "label": "fetchQcMaterialBatchList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L110"}, {"id": "api_qc_material_fetchqcmaterialbatchdetail", "label": "fetchQcMaterialBatchDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L123"}, {"id": "api_qc_material_fetchqcmaterialbatchoptions", "label": "fetchQcMaterialBatchOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L129"}, {"id": "api_qc_material_fetchqcmateriallist", "label": "fetchQcMaterialList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L140"}, {"id": "api_qc_material_fetchqcmaterialoptions", "label": "fetchQcMaterialOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L152"}, {"id": "api_qc_material_fetchcreateqcmaterial", "label": "fetchCreateQcMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L158"}, {"id": "api_qc_material_fetchupdateqcmaterial", "label": "fetchUpdateQcMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L165"}, {"id": "api_qc_material_fetchdeleteqcmaterial", "label": "fetchDeleteQcMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L172"}, {"id": "api_qc_material_fetchstockinqcmaterial", "label": "fetchStockInQcMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L178"}, {"id": "api_qc_material_fetchbatchstockinqcmaterial", "label": "fetchBatchStockInQcMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L185"}, {"id": "api_qc_material_fetchupdateqcmaterialbatch", "label": "fetchUpdateQcMaterialBatch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L196"}, {"id": "api_qc_material_fetchdeleteqcmaterialbatch", "label": "fetchDeleteQcMaterialBatch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L203"}, {"id": "api_qc_material_fetchbatchstockoutqcmaterial", "label": "fetchBatchStockOutQcMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L209"}, {"id": "api_qc_material_fetchbatchdiscardqcmaterial", "label": "fetchBatchDiscardQcMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L222"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_http", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_ts", "target": "api_qc_material_fetchqcmaterialbatchlist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L110", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_ts", "target": "api_qc_material_fetchqcmaterialbatchdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L123", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_ts", "target": "api_qc_material_fetchqcmaterialbatchoptions", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L129", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_material_ts", "target": "api_qc_material_fetchqcmateriallist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts", "source_location": "L140", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_webLine truncated
@@ -142,7 +142,7 @@
</el-table-column>
<el-table-column
prop="changeQty"
label="领用数量"
label="变动数量"
min-width="120"
align="center"
header-align="center"
@@ -158,7 +158,7 @@
</el-table-column>
<el-table-column
prop="changeQty"
label="领用数量"
label="变动数量"
min-width="120"
align="center"
header-align="center"
@@ -287,6 +287,7 @@
e: 'needStepDispatch',
payload: { taskId: string; taskName: string; presetSteps?: Record<string, any>[] }
): void
(e: 'taskCreated', payload: { taskId: string; taskName: string }): void
}>()
const dialogVisible = computed({
@@ -413,6 +414,7 @@
presetSteps: stepList.value
})
}
emit('taskCreated', { taskId, taskName: form.taskName })
pendingListRefresh.value = true
} catch {
/* global error handling */
@@ -431,16 +431,36 @@
@search-unit="(q: string) => editor.searchItemUnitOptions(q)"
/>
</div>
<div v-if="!readonly" class="execution-detail-step-footer">
<el-button
class="task-exec-toolbar-btn task-exec-save-btn"
:type="editor.isScopeDirty('output') ? 'primary' : 'danger'"
:loading="editor.outputSaving.value"
@click="saveTaskOutputsManual"
>
<el-icon><Check /></el-icon>
保存
</el-button>
<div v-if="showOutputStepFooter" class="execution-detail-step-footer">
<div class="execution-detail-actions">
<el-tooltip
:disabled="!spawnTemporaryDisabledReason"
:content="spawnTemporaryDisabledReason"
placement="top"
>
<span class="execution-detail-action-wrap">
<el-button
v-if="canShowSpawnTemporaryWorkOrder"
class="btn-ghost task-exec-toolbar-btn"
:disabled="!!spawnTemporaryDisabledReason"
@click="handleSpawnTemporaryWorkOrderClick"
>
<el-icon><Position /></el-icon>
派发临时工单
</el-button>
</span>
</el-tooltip>
<el-button
v-if="!readonly"
class="task-exec-toolbar-btn task-exec-save-btn"
:type="editor.isScopeDirty('output') ? 'primary' : 'danger'"
:loading="editor.outputSaving.value"
@click="saveTaskOutputsManual"
>
<el-icon><Check /></el-icon>
保存
</el-button>
</div>
</div>
</template>
@@ -539,6 +559,56 @@
:operate-scope="operateScope"
@success="handleForwardSuccess"
/>
<el-dialog
v-model="spawnTempVisible"
title="新增临时工单"
width="560px"
class="dialog-form-layout"
align-center
append-to-body
modal-class="protocol-dialog-mask"
destroy-on-close
:close-on-click-modal="false"
>
<el-form label-position="top" class="biz-dialog-form">
<p class="hint-muted spawn-temp-hint">
将复制当前任务已保存的原材料至新临时工单的生产任务。临时工单不关联样本与协议,创建后请派发任务。
</p>
<div class="form-grid-2">
<el-form-item label="备注" class="form-col-span-2">
<el-input
v-model="spawnTempForm.remark"
type="textarea"
:rows="3"
placeholder="选填"
maxlength="512"
/>
</el-form-item>
</div>
</el-form>
<template #footer>
<el-button class="btn-ghost" @click="spawnTempVisible = false">
<el-icon><Close /></el-icon>
取消
</el-button>
<el-button
class="btn-main"
type="primary"
:loading="spawnTempLoading"
@click="submitSpawnTemporary"
>
<el-icon><Check /></el-icon>
确认
</el-button>
</template>
</el-dialog>
<DispatchTaskDialog
v-model:visible="spawnDispatchVisible"
:work-order-row="spawnDispatchWorkOrderRow"
@task-created="handleSpawnTaskCreated"
/>
</div>
</template>
@@ -551,7 +621,9 @@
CopyDocument,
Delete,
Share,
Loading
Loading,
Position,
Close
} from '@element-plus/icons-vue'
import { VueDraggable as draggable } from 'vue-draggable-plus'
import { useTaskStepEditor } from './useTaskStepEditor'
@@ -563,7 +635,14 @@
import TaskEquipmentPanel from './TaskEquipmentPanel.vue'
import CompleteProductionTaskDialog from './CompleteProductionTaskDialog.vue'
import ForwardTaskDialog from './ForwardTaskDialog.vue'
import DispatchTaskDialog from './DispatchTaskDialog.vue'
import type { ProductionTaskOperateScope } from '@/api/production-task'
import {
fetchSetTaskInputs,
fetchSpawnTemporaryWorkOrderFromTask,
type SpawnTemporaryWorkOrderResult
} from '@/api/production-task'
import { ElMessage } from 'element-plus'
import {
productionConclusionLabel,
productionConclusionTagType,
@@ -614,7 +693,11 @@
completeConclusionInitial,
taskActionLoading,
submitCompleteWithConclusion,
taskDetail
taskDetail,
taskInputs,
validateTaskInputs,
isScopeDirty,
guardBeforeLeaveCurrentScope
} = editor
const executionTaskConclusion = computed(
@@ -647,6 +730,36 @@
const forwardVisible = ref(false)
const spawnTempVisible = ref(false)
const spawnTempLoading = ref(false)
const spawnTempForm = reactive({ remark: '' })
const spawnDispatchVisible = ref(false)
const spawnDispatchWorkOrderRow = ref<Record<string, any> | null>(null)
const pendingSpawnInputItems = ref<SpawnTemporaryWorkOrderResult['inputItems']>([])
const canShowSpawnTemporaryWorkOrder = computed(() => {
const status = taskDetail.value?.taskStatus
if (status !== 'dpz' && status !== 'jxz' && status !== 'ywc') return false
// 已完成任务常通过「查看」只读进入,仍允许派发临时工单
if (props.readonly && status !== 'ywc') return false
return true
})
const showOutputStepFooter = computed(
() => !props.readonly || canShowSpawnTemporaryWorkOrder.value
)
const spawnTemporaryDisabledReason = computed(() => {
if (!canShowSpawnTemporaryWorkOrder.value) return ''
if (!taskInputs.value.length) return '请先在原材料中填写至少一条记录'
const inputErr = validateTaskInputs()
if (inputErr) return inputErr
if (taskDetail.value?.taskStatus !== 'ywc' && isScopeDirty('input')) {
return '请先保存原材料后再派发'
}
return ''
})
const isMineScope = computed(() => props.operateScope === 'mine')
const stepDragHandle = computed(() =>
@@ -681,6 +794,55 @@
void editor.saveTaskEquipment()
}
async function handleSpawnTemporaryWorkOrderClick() {
const reason = spawnTemporaryDisabledReason.value
if (reason) {
ElMessage.warning(reason)
return
}
if (!(await guardBeforeLeaveCurrentScope())) return
spawnTempForm.remark = ''
spawnTempVisible.value = true
}
async function submitSpawnTemporary() {
if (!props.taskId) return
spawnTempLoading.value = true
try {
const res = await fetchSpawnTemporaryWorkOrderFromTask(
props.taskId,
{ remark: spawnTempForm.remark?.trim() || undefined },
props.operateScope
)
pendingSpawnInputItems.value = res.inputItems || []
spawnDispatchWorkOrderRow.value = {
id: res.workOrder.id,
workOrderNo: res.workOrder.workOrderNo,
workOrderType: 'temporary'
}
spawnTempVisible.value = false
spawnDispatchVisible.value = true
ElMessage.success(`已创建临时工单 ${res.workOrder.workOrderNo},请派发生产任务`)
} catch {
/* global error handling */
} finally {
spawnTempLoading.value = false
}
}
async function handleSpawnTaskCreated(payload: { taskId: string }) {
const items = pendingSpawnInputItems.value
const taskId = (payload.taskId || '').trim()
pendingSpawnInputItems.value = []
if (!items.length || !taskId) return
try {
await fetchSetTaskInputs(taskId, items, props.operateScope)
ElMessage.success('已复制原材料至新任务')
} catch {
ElMessage.warning('临时任务已创建,但复制原材料失败,请在新任务中手动添加')
}
}
async function handleBeforeClose(done: () => void) {
if (props.readonly) {
done()
@@ -1078,6 +1240,15 @@
border-top: 1px solid #e5e7eb;
background: #fff;
}
.execution-detail-action-wrap {
display: inline-flex;
}
.spawn-temp-hint {
margin: 0 0 12px;
font-size: 13px;
line-height: 1.5;
color: var(--mint-text-muted, #64748b);
}
.execution-detail-actions {
display: flex;
gap: 8px;
@@ -2633,6 +2633,7 @@ export function useTaskStepEditor() {
addTaskInputRow,
removeTaskInputRow,
saveTaskInputs,
validateTaskInputs,
addTaskOutputRow,
removeTaskOutputRow,
saveTaskOutputs,
@@ -38,6 +38,7 @@
<el-option label="出库" value="out" />
<el-option v-if="SHOW_QC_TASK_MATERIAL_USAGE" label="任务使用" value="use" />
<el-option label="废弃" value="discard" />
<el-option v-if="!mineOnly" label="库存调整" value="adjust" />
</el-select>
</el-form-item>
<el-form-item label="时间范围">
@@ -173,7 +174,7 @@
</el-table-column>
<el-table-column
prop="changeQty"
label="领用数量"
label="变动数量"
min-width="120"
align="center"
header-align="center"
@@ -493,6 +494,7 @@
function getChangeTypeLabel(row: QcMaterialUsage) {
if (row.changeType === 'in') return '入库'
if (row.changeType === 'adjust') return '库存调整'
if (isDiscardRow(row)) return '废弃'
if (isManualOutRow(row)) return '出库'
return '任务使用'
@@ -500,6 +502,7 @@
function getChangeTypeTagType(row: QcMaterialUsage) {
if (row.changeType === 'in') return 'success'
if (row.changeType === 'adjust') return 'warning'
if (isDiscardRow(row)) return 'danger'
if (isManualOutRow(row)) return 'warning'
return 'primary'
@@ -511,6 +514,7 @@
if (sourceType === 'manual_out') return 'warning'
if (sourceType === 'manual_discard') return 'danger'
if (sourceType === 'outbound_handover') return 'primary'
if (sourceType === 'batch_qty_edit') return 'warning'
return 'info'
}
@@ -520,6 +524,7 @@
if (sourceType === 'manual_out') return '手动出库'
if (sourceType === 'manual_discard') return '手动废弃'
if (sourceType === 'outbound_handover') return '出库交接'
if (sourceType === 'batch_qty_edit') return '批次数量修正'
return sourceType || '-'
}
@@ -332,8 +332,14 @@
/>
</el-select>
</el-form-item>
<el-form-item label="入库数量">
<el-input :model-value="String(formData.inQty ?? 0)" disabled />
<el-form-item label="入库数量" prop="inQty">
<DecimalInput
v-model="formData.inQty"
:min="0.01"
:precision="4"
style="width: 100%"
@change="onEditInQtyChange"
/>
</el-form-item>
<el-form-item v-if="showAmountColumns" label="单价(元)" prop="unitPrice">
<AmountInput
@@ -351,8 +357,51 @@
@change="formData.amountManual = true"
/>
</el-form-item>
<el-form-item label="剩余数量">
<el-input :model-value="String(formData.remainingQty ?? 0)" disabled />
<el-form-item label="剩余数量" prop="remainingQty">
<DecimalInput
v-model="formData.remainingQty"
:min="0"
:precision="4"
style="width: 100%"
@change="onEditRemainingQtyChange"
/>
</el-form-item>
<el-form-item>
<template #label>
已出库总量
<span class="form-label-tip">含出库、废弃及任务扣减</span>
</template>
<el-input :model-value="String(formData.outTotal ?? 0)" disabled />
</el-form-item>
<el-form-item label="理论剩余">
<el-input :model-value="String(editTheoreticalRemaining)" disabled />
</el-form-item>
<el-form-item v-if="editOutTotal > 0" class="form-col-span-3">
<el-alert
type="info"
:closable="false"
show-icon
:title="`该批次已出库/废弃共 ${editOutTotal}${formData.unit || ''}。修改入库数量后,若未手工改动剩余数量,将自动调整为 ${editTheoreticalRemaining}${formData.unit || ''}。`"
/>
</el-form-item>
<el-form-item v-if="editInQtyChanged" class="form-col-span-3">
<el-alert
type="info"
:closable="false"
show-icon
title="修改入库数量后,保存时将写入一条「编辑修正入库数量」的库存调整记录;原入库流水保持不变。"
/>
</el-form-item>
<el-form-item
v-if="editRemainingQtyChanged && editRemainingDiffersFromTheoretical"
class="form-col-span-3"
>
<el-alert
type="warning"
:closable="false"
show-icon
title="剩余数量与「入库数量 − 已出库」不一致,保存时将额外写入一条「编辑修正剩余数量」的库存调整记录。"
/>
</el-form-item>
<el-form-item label="备注" class="form-col-span-3">
<el-input v-model="formData.remark" type="textarea" :rows="2" placeholder="可选" />
@@ -1184,6 +1233,7 @@
fetchQcMaterialBatchList,
fetchQcMaterialOptions,
fetchQcMaterialBatchOptions,
fetchQcMaterialBatchDetail,
fetchCreateQcMaterial,
fetchUpdateQcMaterialBatch,
fetchDeleteQcMaterialBatch,
@@ -1336,6 +1386,7 @@
amountManual: false,
inQty: 0,
remainingQty: 0,
outTotal: 0,
materialCode: '',
materialName: '',
specModel: '',
@@ -1344,6 +1395,27 @@
status: '1',
remark: ''
})
const remainingQtyTouched = ref(false)
const editInitialInQty = ref(0)
const editInitialRemainingQty = ref(0)
const editOutTotal = computed(() => Number(formData.outTotal) || 0)
const editTheoreticalRemaining = computed(() => {
const inQty = Number(formData.inQty) || 0
return Math.max(0, Math.round((inQty - editOutTotal.value) * 10000) / 10000)
})
const editRemainingDiffersFromTheoretical = computed(() => {
const remaining = Number(formData.remainingQty) || 0
return Math.abs(remaining - editTheoreticalRemaining.value) > 0.0001
})
const editInQtyChanged = computed(() => {
const inQty = Number(formData.inQty) || 0
return Math.abs(inQty - editInitialInQty.value) > 0.0001
})
const editRemainingQtyChanged = computed(() => {
const remaining = Number(formData.remainingQty) || 0
return Math.abs(remaining - editInitialRemainingQty.value) > 0.0001
})
const formRules = computed(() => {
const rules: Record<string, unknown[]> = {
@@ -1354,7 +1426,9 @@
batchNo: [{ required: true, message: '请输入批号', trigger: 'blur' }],
manufacturer: [{ required: true, message: '请输入厂家', trigger: 'blur' }],
materialCode: [{ required: true, message: '请输入物料编码', trigger: 'blur' }],
materialName: [{ required: true, message: '请输入物料名称', trigger: 'blur' }]
materialName: [{ required: true, message: '请输入物料名称', trigger: 'blur' }],
inQty: [{ required: true, message: '请输入入库数量', trigger: 'change' }],
remainingQty: [{ required: true, message: '请输入剩余数量', trigger: 'change' }]
}
if (showAmountColumns.value) {
rules.unitPrice = [{ required: true, message: '请输入单价', trigger: 'change' }]
@@ -1736,13 +1810,23 @@
formData.amount = calcAmount(formData.unitPrice ?? 0, formData.inQty)
}
function onEditInQtyChange() {
if (!remainingQtyTouched.value) {
formData.remainingQty = editTheoreticalRemaining.value
}
onEditPriceQtyChange()
}
function onEditRemainingQtyChange() {
remainingQtyTouched.value = true
}
function handleOpenAttachment(row: QcMaterialBatch) {
attachmentBatch.value = row
attachmentDialogVisible.value = true
}
function handleEdit(row: QcMaterialBatch) {
editingBatchId.value = row.batchId || row.id
function fillEditFormFromBatch(row: QcMaterialBatch) {
formData.stockInNo = row.stockInNo || ''
formData.stockInDate = row.stockInDate || ''
formData.expireDate = row.expireDate || ''
@@ -1754,6 +1838,7 @@
formData.amountManual = false
formData.inQty = row.inQty ?? 0
formData.remainingQty = row.remainingQty ?? 0
formData.outTotal = row.outTotal ?? 0
formData.materialCode = row.materialCode || ''
formData.materialName = row.materialName || ''
formData.specModel = row.specModel || ''
@@ -1761,15 +1846,53 @@
formData.warningQty = row.warningQty ?? 0
formData.status = row.status || '1'
formData.remark = row.remark || ''
editInitialInQty.value = row.inQty ?? 0
editInitialRemainingQty.value = row.remainingQty ?? 0
remainingQtyTouched.value = false
}
async function handleEdit(row: QcMaterialBatch) {
editingBatchId.value = row.batchId || row.id
fillEditFormFromBatch(row)
ensureUnitOption(row.unit || '')
dialogVisible.value = true
void searchUnitOptions('')
formRef.value?.clearValidate?.()
const batchId = editingBatchId.value
if (!batchId) return
try {
const detail = await fetchQcMaterialBatchDetail(batchId)
fillEditFormFromBatch(detail)
ensureUnitOption(detail.unit || '')
} catch {
/* 列表行数据仍可编辑 */
}
}
async function handleSubmit() {
await formRef.value?.validate?.()
if (!editingBatchId.value) return
const inQty = Number(formData.inQty) || 0
const remainingQty = Number(formData.remainingQty) || 0
const outTotal = editOutTotal.value
if (inQty <= 0) {
ElMessage.warning('入库数量必须大于 0')
return
}
if (remainingQty < 0) {
ElMessage.warning('剩余数量不能为负数')
return
}
if (remainingQty > inQty) {
ElMessage.warning('剩余数量不能大于入库数量')
return
}
if (inQty < outTotal) {
ElMessage.warning(`入库数量不能小于已出库量 ${outTotal}`)
return
}
submitLoading.value = true
try {
const payload: Record<string, unknown> = {
@@ -1785,7 +1908,9 @@
unit: formData.unit?.trim() || undefined,
warningQty: formData.warningQty,
status: String(formData.status ?? '1'),
remark: formData.remark?.trim() || undefined
remark: formData.remark?.trim() || undefined,
inQty,
remainingQty
}
if (showAmountColumns.value) {
payload.unitPrice = Number(formData.unitPrice) || 0