This commit is contained in:
zlwu committed 2026-06-16 18:33:52 +08:00
1 parent 8ff159c251
commit c1832f9d03
60 files changed
+13400 -10821

No files matched your search

+1 -1
View File
@@ -1 +1 @@
79568
55086
+42
View File
@@ -2408,6 +2408,48 @@ async def get_next_cell_product_code(
return success_response({"codes": codes, "code": codes[0] if codes else ""})
@router.get("/cell-products/max-passage-seq")
async def get_cell_product_max_passage_seq(
productCode: str = Query(..., alias="productCode"),
passage: Optional[str] = None,
passages: Optional[str] = None,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
"""查询 `{productCode}-{代次}-XX` 在细胞产品库中的最大两位序号。"""
tenant_no = _get_tenant_no(db, user)
base = (productCode or "").strip()
if not base:
return error_response(400, "产品编码不能为空")
passage_list: List[str] = []
if passages:
passage_list.extend(p.strip() for p in passages.split(",") if p and p.strip())
if passage and passage.strip():
passage_list.append(passage.strip())
if not passage_list:
return error_response(400, "请指定代次")
max_seq_map = cell_product_svc.get_max_passage_product_seq_map(
db, tenant_no, base, passage_list
)
next_seq_map = {p: max_seq_map.get(p, 0) + 1 for p in max_seq_map}
if len(max_seq_map) == 1:
only_passage = next(iter(max_seq_map))
only_max = max_seq_map[only_passage]
only_next = next_seq_map[only_passage]
return success_response(
{
"passage": only_passage,
"maxSeq": only_max,
"nextSeq": only_next,
"maxSeqByPassage": max_seq_map,
"nextSeqByPassage": next_seq_map,
}
)
return success_response(
{"maxSeqByPassage": max_seq_map, "nextSeqByPassage": next_seq_map}
)
@router.get("/cell-products")
async def list_cell_products(
page: int = Query(1, ge=1),
+52
View File
@@ -555,6 +555,58 @@ def get_next_code(db: Session, tenant_no: str) -> str:
_PRODUCT_CODE_SUFFIX_RE = re.compile(r"^(.+)-(\d{2})$")
def get_max_passage_product_seq(
db: Session,
tenant_no: str,
base_code: str,
passage: str,
) -> int:
"""查询 `{base_code}-{passage}-XX` 形式产品编码在库中的最大两位序号(无匹配则 0)。"""
base = (base_code or "").strip()
passage = (passage or "").strip()
if not base or not passage:
return 0
prefix = f"{base}-{passage}-"
suffix_re = re.compile(rf"^{re.escape(prefix)}(\d{{2}})$")
rows = (
db.query(BizCellProduct.product_code)
.filter(
BizCellProduct.tenant_no == tenant_no,
BizCellProduct.product_code.like(f"{prefix}%"),
BizCellProduct.del_flag == 0,
)
.all()
)
max_seq = 0
for (code,) in rows:
m = suffix_re.match((code or "").strip())
if not m:
continue
try:
max_seq = max(max_seq, int(m.group(1)))
except ValueError:
continue
return max_seq
def get_max_passage_product_seq_map(
db: Session,
tenant_no: str,
base_code: str,
passages: List[str],
) -> Dict[str, int]:
"""批量查询各代次在 `{base_code}-{passage}-XX` 规则下的最大序号。"""
result: Dict[str, int] = {}
seen: set[str] = set()
for raw in passages or []:
passage = (raw or "").strip()
if not passage or passage in seen:
continue
seen.add(passage)
result[passage] = get_max_passage_product_seq(db, tenant_no, base_code, passage)
return result
def normalize_product_code_base(code: str) -> str:
"""去掉末尾 -01/-02 等序号,得到多份入库时的基础编码。"""
c = (code or "").strip()
@@ -186,6 +186,8 @@ def list_reviews_paginated(
or_(
BizPilotApplication.application_no.like(like),
BizPilotApplication.application_name.like(like),
BizPilotApplication.project_title.like(like),
BizPilotApplication.customer_name.like(like),
),
)
.subquery()
@@ -443,6 +445,8 @@ def list_reviews_paginated(
"applicationNo": (app.application_no or "") if app else "",
"applicationName": (app.application_name or "") if app else "",
"channelName": (app.channel_name or "") if app else "",
"projectTitle": (app.project_title or "") if app else "",
"customerName": (app.customer_name or "") if app else "",
"patientName": (patient.patient_name or "") if patient else "",
"cellType": s.cell_type or (plan.cell_type or "") if plan else (s.cell_type or ""),
"specText": s.spec_text or (plan.spec_text or "") if plan else (s.spec_text or ""),
@@ -90,6 +90,9 @@ def _row_to_dict_schedule(
d["channelId"] = application.channel_id or ""
d["pilotApplicationId"] = application.id or ""
d["channelServiceOrderId"] = application.channel_service_order_id or ""
d["projectTitle"] = application.project_title or ""
d["customerName"] = application.customer_name or ""
d["bizType"] = application.biz_type or "pilot_service"
else:
d["applicationNo"] = ""
d["applicationName"] = ""
@@ -98,6 +101,9 @@ def _row_to_dict_schedule(
d["channelId"] = ""
d["pilotApplicationId"] = ""
d["channelServiceOrderId"] = ""
d["projectTitle"] = ""
d["customerName"] = ""
d["bizType"] = ""
if plan:
d["channelAgreementId"] = plan.channel_agreement_id or ""
@@ -270,13 +276,15 @@ def list_infusion_schedules_mgmt(
if bt:
q = q.filter(app.biz_type == bt)
# keyword: LIKE on application_no, channel_name, patient_name
# keyword: application_no, channel_name, patient_name; basic_experiment also project_title/customer_name
if keyword:
kw = f"%{keyword}%"
q = q.filter(
or_(
app.application_no.like(kw),
app.channel_name.like(kw),
app.project_title.like(kw),
app.customer_name.like(kw),
pat.patient_name.like(kw),
)
)
@@ -486,8 +494,14 @@ def get_infusion_schedule_detail(
app["orderType"] = flat.get("orderType") or ""
app["channelServiceOrderName"] = flat.get("channelServiceOrderName") or ""
app["channelServiceOrderId"] = flat.get("channelServiceOrderId") or ""
app["projectTitle"] = app.get("projectTitle") or flat.get("projectTitle") or ""
app["customerName"] = app.get("customerName") or flat.get("customerName") or ""
if application:
app["bizType"] = application.biz_type or "pilot_service"
if not app.get("projectTitle"):
app["projectTitle"] = application.project_title or ""
if not app.get("customerName"):
app["customerName"] = application.customer_name or ""
plan = dict(aggregated.get("infusionPlan") or {})
if plan_row:
+2
View File
@@ -2408,6 +2408,8 @@ def build_outbound_pilot_context_by_schedule(
"infusionTime": _fmt_dt(sched.infusion_time),
"infusionLocation": sched.infusion_location or "",
"infusionMethod": sched.infusion_method or "",
"cellType": sched.cell_type or "",
"specText": sched.spec_text or "",
"scheduleStatus": sched.schedule_status or "",
"infusionStatus": sched.infusion_status or "",
"qcStatus": sched.qc_status or "",
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_outbound_release_review_py", "label": "outbound_release_review.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L1"}, {"id": "crud_outbound_release_review_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L52"}, {"id": "crud_outbound_release_review_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L56"}, {"id": "crud_outbound_release_review_total_pages", "label": "_total_pages()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L65"}, {"id": "crud_outbound_release_review_get_user_name", "label": "_get_user_name()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L71"}, {"id": "crud_outbound_release_review_resolve_schedule_biz_type", "label": "_resolve_schedule_biz_type()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L76"}, {"id": "crud_outbound_release_review_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L93"}, {"id": "crud_outbound_release_review_list_reviews_paginated", "label": "list_reviews_paginated()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L124"}, {"id": "crud_outbound_release_review_get_schedule_detail", "label": "get_schedule_detail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L510"}, {"id": "crud_outbound_release_review_review_schedule", "label": "review_schedule()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L586"}, {"id": "crud_outbound_release_review_batch_review", "label": "batch_review()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L676"}, {"id": "crud_outbound_release_review_rationale_81", "label": "\u8f93\u6ce8\u8ba1\u5212\u4e1a\u52a1\u7c7b\u578b\uff1a\u4f18\u5148\u51fa\u5e93\u5de5\u5355 biz_type\uff0c\u5426\u5219\u53d6\u7533\u8bf7\u5355 biz_type\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L81"}, {"id": "crud_outbound_release_review_rationale_94", "label": "\u5c06 BizOutboundReleaseReview ORM \u5bf9\u8c61\u8f6c\u4e3a\u524d\u7aef\u5b57\u5178\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L94"}, {"id": "crud_outbound_release_review_rationale_139", "label": "\u5206\u9875\u5217\u51fa\u51fa\u5e93\u653e\u884c\u5ba1\u6838\u6570\u636e\uff0c\u4ee5\u8f93\u6ce8\u8ba1\u5212\u4e3a\u4e3b\u8868 LEFT JOIN \u5ba1\u6838/\u751f\u4ea7/\u8d28\u68c0\u5de5\u5355\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L139"}, {"id": "crud_outbound_release_review_rationale_513", "label": "\u6309\u8f93\u6ce8\u8ba1\u5212 ID \u805a\u5408\u51fa\u5e93\u653e\u884c\u5ba1\u6838\u8be6\u60c5\uff08\u4e2d\u8bd5\u4e0a\u4e0b\u6587 + \u751f\u4ea7 + \u8d28\u68c0 + \u5ba1\u6838\uff09\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L513"}, {"id": "crud_outbound_release_review_rationale_596", "label": "\u5bf9\u6307\u5b9a\u8f93\u6ce8\u8ba1\u5212\u6267\u884c\u51fa\u5e93\u653e\u884c\u5ba1\u6838\uff08upsert\uff09\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L596"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_outbound_release_review_py", "target": "math", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_outbound_release_review_py", "target": "collections", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00cLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_work_order_py", "label": "qc_work_order.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L1"}, {"id": "crud_qc_work_order_resolve_outbound_biz_type_for_schedule", "label": "resolve_outbound_biz_type_for_schedule()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L84"}, {"id": "crud_qc_work_order_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L125"}, {"id": "crud_qc_work_order_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L131"}, {"id": "crud_qc_work_order_normalize_date_bound", "label": "_normalize_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L135"}, {"id": "crud_qc_work_order_reception_source_label", "label": "_reception_source_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L142"}, {"id": "crud_qc_work_order_qc_biz_type_label", "label": "_qc_biz_type_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L147"}, {"id": "crud_qc_work_order_work_order_qc_biz_type", "label": "_work_order_qc_biz_type()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L152"}, {"id": "crud_qc_work_order_validate_cell_product_id", "label": "_validate_cell_product_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L159"}, {"id": "crud_qc_work_order_enrich_work_order_cell_products", "label": "_enrich_work_order_cell_products()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L171"}, {"id": "crud_qc_work_order_enrich_outbound_work_orders", "label": "_enrich_outbound_work_orders()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L200"}, {"id": "crud_qc_work_order_outbound_qc_work_order_ids_by_keyword", "label": "_outbound_qc_work_order_ids_by_keyword()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L293"}, {"id": "crud_qc_work_order_accept_conclusion_label", "label": "_accept_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L340"}, {"id": "crud_qc_work_order_load_sample_type_name_map", "label": "_load_sample_type_name_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L345"}, {"id": "crud_qc_work_order_effective_reception_source", "label": "_effective_reception_source()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L357"}, {"id": "crud_qc_work_order_effective_donation_sample_id", "label": "_effective_donation_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L366"}, {"id": "crud_qc_work_order_effective_protocol_sample_id", "label": "_effective_protocol_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L375"}, {"id": "crud_qc_work_order_sample_type_name_for_item", "label": "_sample_type_name_for_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L383"}, {"id": "crud_qc_work_order_sample_type_name_for_reception", "label": "_sample_type_name_for_reception()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L401"}, {"id": "crud_qc_work_order_enrich_work_order_list_items", "label": "_enrich_work_order_list_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L424"}, {"id": "crud_qc_work_order_enrich_production_work_order_refs", "label": "_enrich_production_work_order_refs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L588"}, {"id": "crud_qc_work_order_gen_daily_no", "label": "_gen_daily_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_orLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_pilot_infusion_schedule_mgmt_py", "label": "pilot_infusion_schedule_mgmt.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L1"}, {"id": "crud_pilot_infusion_schedule_mgmt_row_to_dict_schedule", "label": "_row_to_dict_schedule()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L55"}, {"id": "crud_pilot_infusion_schedule_mgmt_row_to_dict_product", "label": "_row_to_dict_product()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L137"}, {"id": "crud_pilot_infusion_schedule_mgmt_get_plan_schedule_course_meta", "label": "_get_plan_schedule_course_meta()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L154"}, {"id": "crud_pilot_infusion_schedule_mgmt_resolve_course_display", "label": "_resolve_course_display()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L194"}, {"id": "crud_pilot_infusion_schedule_mgmt_get_products_for_schedule", "label": "_get_products_for_schedule()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L224"}, {"id": "crud_pilot_infusion_schedule_mgmt_list_infusion_schedules_mgmt", "label": "list_infusion_schedules_mgmt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L246"}, {"id": "crud_pilot_infusion_schedule_mgmt_get_infusion_schedule_detail", "label": "get_infusion_schedule_detail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L422"}, {"id": "crud_pilot_infusion_schedule_mgmt_update_infusion_status", "label": "update_infusion_status()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L573"}, {"id": "crud_pilot_infusion_schedule_mgmt_update_qc_status", "label": "update_qc_status()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L675"}, {"id": "crud_pilot_infusion_schedule_mgmt_settlement_remark_marker", "label": "_settlement_remark_marker()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L714"}, {"id": "crud_pilot_infusion_schedule_mgmt_settlement_remark_markers_for_lookup", "label": "_settlement_remark_markers_for_lookup()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L719"}, {"id": "crud_pilot_infusion_schedule_mgmt_find_existing_settlement_txn", "label": "_find_existing_settlement_txn()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L723"}, {"id": "crud_pilot_infusion_schedule_mgmt_resolve_yfk_unit_price", "label": "_resolve_yfk_unit_price()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L743"}, {"id": "crud_pilot_infusion_schedule_mgmt_find_service_order_product", "label": "_find_service_order_product()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L786"}, {"id": "crud_pilot_infusion_schedule_mgmt_schedule_product_to_txn_item", "label": "_schedule_product_to_txn_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L819"}, {"id": "crud_pilot_infusion_schedule_mgmt_create_settlement_txn", "label": "_create_settlement_txn()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L832"}, {"id": "crud_pilot_infusion_schedule_mgmt_deduct_fee_on_complete", "label": "_deduct_fee_on_complete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L879"}, {"id": "crud_pilot_infusion_schedule_mgmt_update_infusion_schedule_mgmt", "label": "update_infusion_schedule_mgmt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py", "source_location": "L1089"}, {"id": "crud_pilot_infusion_schedule_mgmtLine truncated
@@ -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": "L75"}, {"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": "L79"}, {"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": "L87"}, {"id": "api_production_assert_production_task_write_access", "label": "_assert_production_task_write_access()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L91"}, {"id": "api_production_consumablecreatebody", "label": "ConsumableCreateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L115"}, {"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": "L129"}, {"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": "L144"}, {"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": "L158"}, {"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": "L168"}, {"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": "L177"}, {"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": "L187"}, {"id": "api_production_stockinbody", "label": "StockInBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L195"}, {"id": "api_production_stockoutbody", "label": "StockOutBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L201"}, {"id": "api_production_batchstockinitem", "label": "BatchStockInItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L209"}, {"id": "api_production_batchstockinbody", "label": "BatchStockInBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L216"}, {"id": "api_production_batchstockoutitem", "label": "BatchStockOutItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L222"}, {"id": "api_production_batchstockoutbody", "label": "BatchStockOutBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L228"}, {"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": "L237"}, {"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": "L259"}, {"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": "L283"}, {"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": "L301"}, {"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": "L320"}, {"id": "api_production_list_all_consumable_stock_logs", "labLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_cell_product_py", "label": "cell_product.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L1"}, {"id": "crud_cell_product_apply_cell_product_status_change", "label": "_apply_cell_product_status_change()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L31"}, {"id": "crud_cell_product_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L86"}, {"id": "crud_cell_product_build_facility_path_label", "label": "_build_facility_path_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L119"}, {"id": "crud_cell_product_enrich_product_dicts", "label": "_enrich_product_dicts()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L134"}, {"id": "crud_cell_product_product_to_response", "label": "product_to_response()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L264"}, {"id": "crud_cell_product_list_cell_products", "label": "list_cell_products()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L269"}, {"id": "crud_cell_product_get_cell_product", "label": "get_cell_product()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L333"}, {"id": "crud_cell_product_create_cell_product", "label": "create_cell_product()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L347"}, {"id": "crud_cell_product_update_cell_product", "label": "update_cell_product()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L419"}, {"id": "crud_cell_product_delete_cell_product", "label": "delete_cell_product()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L510"}, {"id": "crud_cell_product_next_code_start_seq", "label": "_next_code_start_seq()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L527"}, {"id": "crud_cell_product_get_next_code", "label": "get_next_code()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L548"}, {"id": "crud_cell_product_get_max_passage_product_seq", "label": "get_max_passage_product_seq()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L558"}, {"id": "crud_cell_product_get_max_passage_product_seq_map", "label": "get_max_passage_product_seq_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L592"}, {"id": "crud_cell_product_normalize_product_code_base", "label": "normalize_product_code_base()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L610"}, {"id": "crud_cell_product_build_split_product_codes", "label": "build_split_product_codes()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L621"}, {"id": "crud_cell_product_reserve_next_codes", "label": "reserve_next_codes()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L628"}, {"id": "crud_cell_product_validate_batch_items", "label": "_validate_batch_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L638"}, {"id": "crud_cell_product_create_cell_products_by_quantity", "label": "create_cell_products_by_quantity()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L683"}, {"id": "crud_cell_product_create_cell_products_batch", "label": "create_cell_products_batch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L717"}, {"id": "crud_cell_product_total_pages", "label": "total_pages()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py", "source_location": "L793"}, {"id": "crud_cell_product_product_node", "label": "_product_node()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/Line truncated
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+155 -85
View File
@@ -1,11 +1,11 @@
# Graph Report - app (2026-06-16)
## Corpus Check
- Large corpus: 208 files · ~242,198 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
- Large corpus: 208 files · ~242,541 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
## Summary
- 4157 nodes · 21763 edges · 43 communities detected
- Extraction: 33% EXTRACTED · 67% INFERRED · 0% AMBIGUOUS · INFERRED: 14643 edges (avg confidence: 0.6)
- 4163 nodes · 21838 edges · 57 communities detected
- Extraction: 33% EXTRACTED · 67% INFERRED · 0% AMBIGUOUS · INFERRED: 14710 edges (avg confidence: 0.6)
- Token cost: 0 input · 0 output
## Community Hubs (Navigation)
@@ -46,17 +46,31 @@
- [[_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 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 53|Community 53]]
- [[_COMMUNITY_Community 54|Community 54]]
- [[_COMMUNITY_Community 55|Community 55]]
- [[_COMMUNITY_Community 56|Community 56]]
- [[_COMMUNITY_Community 57|Community 57]]
- [[_COMMUNITY_Community 58|Community 58]]
## God Nodes (most connected - your core abstractions)
1. `success_response()` - 636 edges
2. `error_response()` - 528 edges
3. `SysUser` - 451 edges
1. `success_response()` - 637 edges
2. `error_response()` - 529 edges
3. `SysUser` - 452 edges
4. `BizProductionMaterialUsage` - 294 edges
5. `BizProductionMaterial` - 293 edges
6. `BizQcTaskResult` - 292 edges
@@ -70,227 +84,283 @@
core/api_request_log_middleware.py → models/models.py
- `get_menu_list()` --calls--> `success_response()` [INFERRED]
api/menu.py → core/response.py
- `中试服务交付管理 API(交付信息、交付物料、交付方式)` --uses--> `SysUser` [INFERRED]
api/pilot_delivery.py → models/models.py
- `保留匹配节点及其全部上级,供关键词检索后仍能正确组树。` --uses--> `SysDept` [INFERRED]
crud/dept.py → models/models.py
- `物品单位 CRUD(biz_item_unit)` --uses--> `BizItemUnit` [INFERRED]
crud/item_unit.py → models/models.py
- `快递公司 CRUD(biz_express_company)` --uses--> `BizExpressCompany` [INFERRED]
crud/express_company.py → models/models.py
- `客户 CRUD(biz_customer)` --uses--> `BizCustomer` [INFERRED]
crud/customer.py → models/models.py
## Communities
### 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 (792): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+784 more)
### Community 1 - "Community 1"
Cohesion: 0.01
Nodes (598): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+590 more)
Nodes (525): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+517 more)
### Community 2 - "Community 2"
Cohesion: 0.07
Nodes (481): 细胞存储 — 采集协议单 / 审核 / 财务确认 / 分期预警 API, If mother info exists but no customerId, create a customer record and link it., Base, 细胞产品 CRUD(biz_cell_product), 解析任务样本投入物,返回祖先链单段(样本终止节点)。, 管理端手动改状态:允许在合法枚举间任意变更,并同步库位占用。, 去掉末尾 -01/-02 等序号,得到多份入库时的基础编码。, 按基础编码生成 基础-01、基础-02 … (+473 more)
Nodes (387): 保险公司及险种价格管理 API(保险公司 + 开票信息 + 险种价格), AccessLogCreateBody, AccessLogUpdateBody, CleanRoomCreateBody, CleanRoomUpdateBody, ExhibitionAppointmentCreateBody, ExhibitionAppointmentUpdateBody, OccupancyCreateBody (+379 more)
### Community 3 - "Community 3"
Cohesion: 0.01
Nodes (407): _persist_protocol_sub_resources(), generate_uuid(), ApiRequestLogCRUD, delete(), get_multi_with_filters(), batch_create_sterilize_logs(), batch_create_wash_logs(), batch_discard_garments() (+399 more)
Cohesion: 0.02
Nodes (256): create_collection_protocol(), delete_collection_protocol(), _ensure_customer_for_mother(), get_collection_protocol_detail(), _get_current_user_id(), _get_tenant_no(), list_collection_protocol_audits(), list_collection_protocols() (+248 more)
### Community 4 - "Community 4"
Cohesion: 0.02
Nodes (243): eq_unicode(), like_unicode(), MySQL 字符串比较/模糊匹配时统一排序规则,避免 Illegal mix of collations。, 跨表字符串等值比较(JOIN / WHERE)时统一为 utf8mb4_unicode_ci。, 将列显式设为 utf8mb4_unicode_ci。, unicode_ci(), _format_attachment_file_size(), urls_to_attachment_list() (+235 more)
Nodes (253): eq_unicode(), like_unicode(), MySQL 字符串比较/模糊匹配时统一排序规则,避免 Illegal mix of collations。, 跨表字符串等值比较(JOIN / WHERE)时统一为 utf8mb4_unicode_ci。, 将列显式设为 utf8mb4_unicode_ci。, unicode_ci(), _format_attachment_file_size(), urls_to_attachment_list() (+245 more)
### Community 5 - "Community 5"
Cohesion: 0.02
Nodes (113): get_designer_data(), _error_json(), lifespan(), 数据库异常:返回 JSON 并保留 CORS 头,避免浏览器只报跨域错误, 未捕获异常:统一 JSON 500,确保跨域场景下仍有 Access-Control-Allow-Origin, sqlalchemy_exception_handler(), unhandled_exception_handler(), BaseHTTPMiddleware (+105 more)
Cohesion: 0.04
Nodes (217): generate_uuid(), batch_stock_in(), batch_stock_out(), consumable_code_exists(), create_consumable(), _dec(), get_consumable(), _is_enabled_status() (+209 more)
### Community 6 - "Community 6"
Cohesion: 0.02
Nodes (140): _jwt_user_payload(), Web 端登录用 RSA 公钥(PKCS#1 v1.5,与 JSEncrypt 一致), Web 端登录:账号为 sys_user.user_no,密码为 sys_user.password(bcrypt)。, refresh_token(), web_login(), web_login_rsa_public_key(), create_access_token(), create_refresh_token() (+132 more)
Nodes (185): _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), get_material_entity(), get_my_usages(), _is_enabled_status() (+177 more)
### Community 7 - "Community 7"
Cohesion: 0.03
Nodes (140): _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(), create_cell_product() (+132 more)
Cohesion: 0.06
Nodes (192): CellSampleTypeCreateBody, CellSampleTypeUpdateBody, CollectionRegionCreateBody, CollectionRegionUpdateBody, CustomerCreateBody, CustomerUpdateBody, HospitalCreateBody, HospitalUpdateBody (+184 more)
### Community 8 - "Community 8"
Cohesion: 0.03
Nodes (119): _batch_line_to_dict(), _check_header_to_dict(), get_check_detail(), _line_counts(), list_checks(), _parse_check_time(), _resolve_unused_item_fields(), _status_label() (+111 more)
Cohesion: 0.02
Nodes (133): get_by_schedule(), get_method(), _get_tenant_no(), list_by_application(), list_materials(), 中试服务交付管理 API(交付信息、交付物料、交付方式), soft_delete(), generate_id() (+125 more)
### Community 9 - "Community 9"
Cohesion: 0.03
Nodes (115): list_ethnics_for_select(), apply_data_scope(), _get_child_dept_ids(), get_user_dept_id(), _resolve_user_role_scopes(), _cascade_soft_delete(), create_dept(), get_dept() (+107 more)
Cohesion: 0.02
Nodes (100): get_designer_data(), _error_json(), 数据库异常:返回 JSON 并保留 CORS 头,避免浏览器只报跨域错误, 未捕获异常:统一 JSON 500,确保跨域场景下仍有 Access-Control-Allow-Origin, sqlalchemy_exception_handler(), unhandled_exception_handler(), BaseHTTPMiddleware, ApiCryptoError (+92 more)
### Community 10 - "Community 10"
Cohesion: 0.03
Nodes (104): format_date(), optional_date(), parse_date(), 将字符串 / date / datetime 转为 date 或 None, allocate_next_biz_no(), _format_biz_no(), _prefix_for(), 业务协议号自动生成:XBCC / JZCC + YYYYMMDD + 6 位序号 (+96 more)
Nodes (136): 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() (+128 more)
### Community 11 - "Community 11"
Cohesion: 0.06
Nodes (89): AccessLogCreateBody, AccessLogUpdateBody, CleanRoomCreateBody, CleanRoomUpdateBody, ExhibitionAppointmentCreateBody, ExhibitionAppointmentUpdateBody, OccupancyCreateBody, 运营支撑 API(洁净室、进出记录、仓储设施、储位、展厅预约) (+81 more)
Cohesion: 0.05
Nodes (68): _avatar_url_field(), _build_current_user_payload(), _build_user_info_payload(), get_current_user_profile(), _jwt_user_payload(), logout(), 公共接口(Web 登录、刷新 Token、登出;用户模型对齐 docs/sql/zkxw.sql 基线), Web 端登录用 RSA 公钥(PKCS#1 v1.5,与 JSEncrypt 一致) (+60 more)
### Community 12 - "Community 12"
Cohesion: 0.36
Nodes (66): BatchStockInBody, BatchStockInItem, BatchStockOutBody, BatchStockOutItem, ConsumableCreateBody, ConsumablePackCreateBody, ConsumablePackUpdateBody, ConsumableUpdateBody (+58 more)
Nodes (67): BatchStockInBody, BatchStockInItem, BatchStockOutBody, BatchStockOutItem, ConsumableCreateBody, ConsumablePackCreateBody, ConsumablePackUpdateBody, ConsumableUpdateBody (+59 more)
### Community 13 - "Community 13"
Cohesion: 0.08
Nodes (57): api_save_application(), auto_generate_schedules(), complete_application(), create_application(), create_basic_experiment_sale_schedules(), create_infusion_plan(), create_schedule(), _create_schedule_products() (+49 more)
Nodes (58): api_save_application(), auto_create_payment(), auto_generate_schedules(), complete_application(), create_application(), create_basic_experiment_sale_schedules(), create_infusion_plan(), create_schedule() (+50 more)
### Community 14 - "Community 14"
Cohesion: 0.1
Nodes (44): _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), get_material_entity(), get_my_usages(), _is_enabled_status() (+36 more)
Cohesion: 0.08
Nodes (50): join_equipment_ids(), parse_equipment_ids(), 工艺/步骤设备多选:逗号分隔 ID 与名称快照解析, 校验设备列表,返回 (equipment_ids 逗号串, equipment_name 逗号串快照)。, resolve_equipment_list_snapshot(), _consumable_row_to_dict(), create_process(), _create_sub_consumable() (+42 more)
### Community 15 - "Community 15"
Cohesion: 0.11
Nodes (36): batch_create_sterilize_logs(), batch_create_wash_logs(), batch_discard_garments(), batch_soft_delete_garments(), _count_map(), create_garment(), create_sterilize_log(), create_wash_log() (+28 more)
### Community 16 - "Community 16"
Cohesion: 0.12
Nodes (10): 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, 小程序调起支付的二次签名参数(与公众号 JSAPI 规则一致), 统一下单 (V2 API) Args: out_trade_no: 商户订单号 tot, 生成签名 V3 (SHA256 with RSA), wechat_pay() (+2 more)
### Community 16 - "Community 16"
Cohesion: 0.15
Nodes (24): join_equipment_ids(), parse_equipment_ids(), 工艺/步骤设备多选:逗号分隔 ID 与名称快照解析, 校验设备列表,返回 (equipment_ids 逗号串, equipment_name 逗号串快照)。, resolve_equipment_list_snapshot(), _consumable_row_to_dict(), create_process(), _create_sub_consumable() (+16 more)
### Community 17 - "Community 17"
Cohesion: 0.19
Nodes (26): _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() (+18 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)
### Community 18 - "Community 18"
### Community 19 - "Community 19"
Cohesion: 0.15
Nodes (20): _access_log_to_dict(), _calc_duration_minutes(), create_access_log(), create_clean_room(), create_uv_disinfect_log(), get_access_log(), get_clean_room(), get_uv_disinfect_log() (+12 more)
### Community 20 - "Community 20"
Cohesion: 0.18
Nodes (18): company_code_exists(), create_company(), get_company(), list_companies(), list_company_options(), _row_to_dict(), soft_delete_company(), update_company() (+10 more)
### Community 19 - "Community 19"
### Community 21 - "Community 21"
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 22 - "Community 22"
Cohesion: 0.25
Nodes (13): batch_issue_protocol_nos(), batch_revoke_protocol_nos(), create_protocol_no(), get_protocol_no(), list_protocol_nos(), _parse_issued_time(), protocol_no_exists(), 采集协议号池 CRUD(biz_collection_protocol_no) (+5 more)
### Community 23 - "Community 23"
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 20 - "Community 20"
### Community 24 - "Community 24"
Cohesion: 0.31
Nodes (11): create_equipment(), _dec(), equipment_code_exists(), equipment_is_referenced(), get_equipment(), list_equipments(), _norm_status(), _parse_date() (+3 more)
### Community 21 - "Community 21"
### Community 25 - "Community 25"
Cohesion: 0.27
Nodes (11): create_consumable_pack(), get_consumable_pack(), get_pack_detail(), _item_row_to_dict(), list_all_packs(), list_consumable_packs(), pack_code_exists(), 耗材包 CRUD(biz_consumable_pack + biz_consumable_pack_item) (+3 more)
### Community 22 - "Community 22"
### Community 26 - "Community 26"
Cohesion: 0.24
Nodes (12): appointment_no_exists(), create_exhibition_appointment(), _format_visit_date(), _generate_appointment_no(), get_exhibition_appointment(), list_exhibition_appointments(), 展览预约 CRUD(biz_exhibition_appointment), 生成预约编号:YYYYMMDD + 6位序号(如 20260515000001) (+4 more)
### Community 27 - "Community 27"
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 23 - "Community 23"
### Community 28 - "Community 28"
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 24 - "Community 24"
### Community 29 - "Community 29"
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 25 - "Community 25"
### Community 30 - "Community 30"
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()
Nodes (11): _build_tree(), _cascade_soft_delete(), _collect_with_ancestors(), create_dept(), get_dept(), list_depts(), list_depts_tree(), 保留匹配节点及其全部上级,供关键词检索后仍能正确组树。 (+3 more)
### Community 26 - "Community 26"
### Community 31 - "Community 31"
Cohesion: 0.29
Nodes (9): _build_tree(), _cascade_soft_delete(), create_menu(), get_menu(), list_menus(), list_menus_tree(), _row_to_dict(), soft_delete_menu() (+1 more)
### Community 32 - "Community 32"
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 33 - "Community 33"
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 27 - "Community 27"
### Community 34 - "Community 34"
Cohesion: 0.27
Nodes (8): create_dict_data(), get_dict_data(), list_dict_data(), list_dict_data_options(), 字典数据 CRUD(sys_dict_data), _row_to_dict(), soft_delete_dict_data(), update_dict_data()
### Community 35 - "Community 35"
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 28 - "Community 28"
### Community 36 - "Community 36"
Cohesion: 0.31
Nodes (8): category_code_exists(), create_process_category(), get_process_category(), list_process_categories(), 工艺工序分类 CRUD(biz_process_category), _row_to_dict(), soft_delete_process_category(), update_process_category()
### Community 37 - "Community 37"
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 38 - "Community 38"
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 29 - "Community 29"
### Community 39 - "Community 39"
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 40 - "Community 40"
Cohesion: 0.36
Nodes (7): create_post(), get_post(), list_posts(), post_code_exists(), _row_to_dict(), soft_delete_post(), update_post()
### Community 41 - "Community 41"
Cohesion: 0.36
Nodes (7): create_site(), get_site(), list_sites(), _row_to_dict(), site_code_exists(), soft_delete_site(), update_site()
### Community 42 - "Community 42"
Cohesion: 0.36
Nodes (7): create_tenant(), get_tenant(), list_tenants(), _row_to_dict(), soft_delete_tenant(), tenant_no_exists(), update_tenant()
### Community 43 - "Community 43"
Cohesion: 0.25
Nodes (7): 菜单 code 权限守卫(V0.3:通过 sys_user_role → sys_role_menu → sys_menu.perms), 运营端角色守卫:admin / super_admin 可访问。, 接口菜单权限守卫。super_admin 直接放行。, 接口菜单权限守卫:拥有任一 menuCode 即可访问。super_admin 直接放行。, require_admin_or_super_admin(), require_any_menu_code(), require_menu_code()
### Community 30 - "Community 30"
### Community 44 - "Community 44"
Cohesion: 0.29
Nodes (2): BaseModel, SoftDeleteModel
### Community 31 - "Community 31"
### Community 45 - "Community 45"
Cohesion: 0.38
Nodes (6): derive_legacy_status_from_three(), derive_three_status_from_legacy(), 阶段A兼容:从旧 status 推导三字段。 约束:旧 status 本身混合了支付/配送/订单生命周期,因此只能尽力推断; 若业务侧已有更精确, 阶段A兼容:从三字段反推旧 status(用于旧前端/旧筛选参数兼容)。, ThreeStatus, _to_decimal()
### Community 32 - "Community 32"
### Community 46 - "Community 46"
Cohesion: 0.5
Nodes (3): BaseSettings, Config, Settings
### Community 33 - "Community 33"
### Community 47 - "Community 47"
Cohesion: 0.5
Nodes (2): _auto_fill_create_dept_id(), ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID
### Community 34 - "Community 34"
### Community 48 - "Community 48"
Cohesion: 0.67
Nodes (2): get_menu_list(), 运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,5 个一级菜单分组)
### Community 35 - "Community 35"
### Community 49 - "Community 49"
Cohesion: 1.0
Nodes (1): 请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传
### Community 36 - "Community 36"
### Community 50 - "Community 50"
Cohesion: 1.0
Nodes (1): API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)
### Community 39 - "Community 39"
### Community 53 - "Community 53"
Cohesion: 1.0
Nodes (1): 发送订单状态通知 Args: openid: 用户openid ord
### Community 40 - "Community 40"
### Community 54 - "Community 54"
Cohesion: 1.0
Nodes (1): 发送支付成功通知 Args: openid: 用户openid ord
### Community 41 - "Community 41"
### Community 55 - "Community 55"
Cohesion: 1.0
Nodes (1): 发送配送通知 Args: openid: 配送员openid task
### Community 42 - "Community 42"
### Community 56 - "Community 56"
Cohesion: 1.0
Nodes (1): 发送配送时效预警 Args: openid: 配送员openid ta
### Community 43 - "Community 43"
### Community 57 - "Community 57"
Cohesion: 1.0
Nodes (1): 发送退款结果通知 Args: openid: 用户openid ord
### Community 44 - "Community 44"
### Community 58 - "Community 58"
Cohesion: 1.0
Nodes (1): 发送催单通知给配送员 Args: deliver_openid: 配送员openid
## Knowledge Gaps
- **127 isolated node(s):** `刷新会话 TTL(refreshToken 续期;已登录用户每次 API 校验通过后滑动续期)`, `写入 refreshToken(用于 one-time 使用/吊销)`, `根据 token 获取当前用户(包含 Redis 会话校验;会话滑动续期)`, `登录凭据 RSA 解密(与前端 JSEncrypt PKCS#1 v1.5 兼容)。`, `Base64 密文 -> JSON 对象(须含 username、password、ts 毫秒时间戳)。` (+122 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **Thin community `Community 30`** (8 nodes): `BaseModel`, `.to_dict()`, `get_active()`, `base.py`, `SoftDeleteModel`, `.restore()`, `.soft_delete()`, `__tablename__()`
- **Thin community `Community 44`** (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 33`** (4 nodes): `_auto_fill_create_dept_id()`, `get_db()`, `database.py`, `ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID`
- **Thin community `Community 47`** (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 34`** (3 nodes): `get_menu_list()`, `menu.py`, `运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,5 个一级菜单分组)`
- **Thin community `Community 48`** (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 35`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
- **Thin community `Community 49`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 36`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
- **Thin community `Community 50`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 39`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord`
- **Thin community `Community 53`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 40`** (1 nodes): `发送支付成功通知 Args: openid: 用户openid ord`
- **Thin community `Community 54`** (1 nodes): `发送支付成功通知 Args: openid: 用户openid ord`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 41`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task`
- **Thin community `Community 55`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 42`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta`
- **Thin community `Community 56`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 43`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord`
- **Thin community `Community 57`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 44`** (1 nodes): `发送催单通知给配送员 Args: deliver_openid: 配送员openid`
- **Thin community `Community 58`** (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 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 14`, `Community 22`, `Community 24`?**
_High betweenness centrality (0.124) - this node is a cross-community bridge._
- **Why does `generate_uuid()` connect `Community 3` to `Community 0`, `Community 1`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 13`, `Community 14`, `Community 16`, `Community 17`, `Community 18`, `Community 20`, `Community 21`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`?**
_High betweenness centrality (0.061) - this node is a cross-community bridge._
- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 34`, `Community 5`, `Community 6`, `Community 9`, `Community 13`?**
_High betweenness centrality (0.049) - this node is a cross-community bridge._
- **Why does `SysUser` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 10`, `Community 11`, `Community 12`, `Community 22`, `Community 27`, `Community 29`?**
_High betweenness centrality (0.107) - this node is a cross-community bridge._
- **Why does `generate_uuid()` connect `Community 5` to `Community 0`, `Community 3`, `Community 4`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 13`, `Community 14`, `Community 15`, `Community 17`, `Community 18`, `Community 19`, `Community 20`, `Community 21`, `Community 22`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 33`, `Community 34`, `Community 35`, `Community 36`, `Community 37`, `Community 38`, `Community 39`, `Community 40`, `Community 41`, `Community 42`?**
_High betweenness centrality (0.059) - this node is a cross-community bridge._
- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 3`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 13`, `Community 48`?**
_High betweenness centrality (0.055) - this node is a cross-community bridge._
- **Are the 689 inferred relationships involving `str` (e.g. with `unhandled_exception_handler()` and `get_current_user_by_token()`) actually correct?**
_`str` has 689 INFERRED edges - model-reasoned connections that need verification._
- **Are the 635 inferred relationships involving `success_response()` (e.g. with `list_storage_release_reviews()` and `get_storage_release_review_detail()`) actually correct?**
_`success_response()` has 635 INFERRED edges - model-reasoned connections that need verification._
- **Are the 527 inferred relationships involving `error_response()` (e.g. with `_json_error_response()` and `list_storage_release_reviews()`) actually correct?**
_`error_response()` has 527 INFERRED edges - model-reasoned connections that need verification._
- **Are the 449 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤) data_scope 值: 1 = 全部数据 2 = 本部门数据 3` and `从 SysUser 读取用户的 dept_id。`) actually correct?**
_`SysUser` has 449 INFERRED edges - model-reasoned connections that need verification._
- **Are the 636 inferred relationships involving `success_response()` (e.g. with `list_storage_release_reviews()` and `get_storage_release_review_detail()`) actually correct?**
_`success_response()` has 636 INFERRED edges - model-reasoned connections that need verification._
- **Are the 528 inferred relationships involving `error_response()` (e.g. with `_json_error_response()` and `list_storage_release_reviews()`) actually correct?**
_`error_response()` has 528 INFERRED edges - model-reasoned connections that need verification._
- **Are the 450 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤) data_scope 值: 1 = 全部数据 2 = 本部门数据 3` and `从 SysUser 读取用户的 dept_id。`) actually correct?**
_`SysUser` has 450 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">4157 nodes &middot; 21763 edges &middot; 49 communities</div>
<div id="stats">4163 nodes &middot; 21838 edges &middot; 63 communities</div>
</div>
<script>
const RAW_NODES = [{"id": "init_py", "label": "__init__.py", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 37, "community_name": "Community 37", "source_file": "__init__.py", "file_type": "code", "degree": 0}, {"id": "main_py", "label": "main.py", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "main.py", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 7}, {"id": "app_main_lifespan", "label": "lifespan()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_error_json", "label": "_error_json()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "_error_json()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 3}, {"id": "app_main_sqlalchemy_exception_handler", "label": "sqlalchemy_exception_handler()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "sqlalchemy_exception_handler()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_unhandled_exception_handler", "label": "unhandled_exception_handler()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "unhandled_exception_handler()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 5}, {"id": "app_main_mask_secret", "label": "_mask_secret()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "_mask_secret()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_root", "label": "root()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "root()", "community": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_health_check", "label": "health_check()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "health_check()", "community": 5, "community_name": "Community 5", "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": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "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": 5, "community_name": "Community 5", "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": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "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": 5, "community_name": "Community 5", "source_file": "main.py", "file_type": "rationale", "degree": 3}, {"id": "tasks_init_py", "label": "__init__.py", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 5, "community_name": "Community 5", "source_file": "tasks/__init__.py", "file_type": "code", "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": 903}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 635}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 487}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 459}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 262}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 180}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 170}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 150}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 128}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 125}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 121}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 94}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 73}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 59}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 46}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 29}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 27}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 23}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 20}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 13}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 13}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 13}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 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": 8}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 8}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 7}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 4}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 4}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 3}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 2}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 2}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 1}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 1}, {"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": 0}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 0}, {"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}];
const RAW_NODES = [{"id": "init_py", "label": "__init__.py", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 51, "community_name": "Community 51", "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": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 11, "community_name": "Community 11", "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": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 11, "community_name": "Community 11", "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": 825}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 560}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 392}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 289}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 274}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 231}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 198}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 197}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 164}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 164}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 146}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 76}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 74}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 60}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 55}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 39}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 29}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 27}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 23}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 22}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 20}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 15}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 15}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 13}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 13}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 13}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 13}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 12}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 12}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 12}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 12}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 11}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 10}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 10}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 10}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 10}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 10}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 10}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 10}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 10}, {"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": 8}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 8}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 7}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 4}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 4}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 3}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 2}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 2}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 1}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 1}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 1}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 1}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 1}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 1}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 1}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 1}];
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
function esc(s) {
File diff suppressed because it is too large. Load diff
+5 -5
View File
@@ -78,7 +78,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/process_route.py": 1781524077.6406052,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py": 1780479191.5382729,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py": 1779331731.6720955,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py": 1781597286.8580213,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py": 1781603141.940902,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_check.py": 1781423988.9720724,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/material_stock_batch.py": 1781521998.393167,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/post.py": 1779265648.38155,
@@ -106,7 +106,7 @@
"/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,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py": 1781595844.0818596,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py": 1781604486.4315972,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/clean_room.py": 1781403189.1288755,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/__init__.py": 1778605691.3816392,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_check.py": 1781427225.7574296,
@@ -121,7 +121,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_sms_notification.py": 1781590614.9654794,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_assignee.py": 1781233180.3766735,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/research_donation_sample_collection.py": 1781063441.5812025,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py": 1781348112.27207,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_product.py": 1781605163.863542,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/menu.py": 1779265729.0381103,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/collection_region.py": 1779277867.6408322,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_delivery.py": 1779935673.6808827,
@@ -136,7 +136,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_item.py": 1781145689.9525824,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/process_category.py": 1779265700.0606413,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/item_unit.py": 1779265653.7504313,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py": 1781595812.8827713,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py": 1781603212.996301,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_handover_inventory.py": 1781598316.476379,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py": 1781145773.959546,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_material.py": 1781598316.369666,
@@ -195,7 +195,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": 1781535825.750677,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py": 1781410837.9443986,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py": 1781583185.3240008,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py": 1781605168.6365004,
"/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": 1781601416.6412482,
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+100 -129
View File
@@ -1,11 +1,11 @@
# Graph Report - src (2026-06-16)
## Corpus Check
- Large corpus: 781 files · ~515,617 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
- Large corpus: 782 files · ~514,925 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
## Summary
- 2560 nodes · 3538 edges · 54 communities detected
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 775 edges (avg confidence: 0.8)
- 2581 nodes · 3576 edges · 49 communities detected
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 778 edges (avg confidence: 0.8)
- Token cost: 0 input · 0 output
## Community Hubs (Navigation)
@@ -41,28 +41,23 @@
- [[_COMMUNITY_Community 29|Community 29]]
- [[_COMMUNITY_Community 30|Community 30]]
- [[_COMMUNITY_Community 31|Community 31]]
- [[_COMMUNITY_Community 32|Community 32]]
- [[_COMMUNITY_Community 33|Community 33]]
- [[_COMMUNITY_Community 34|Community 34]]
- [[_COMMUNITY_Community 35|Community 35]]
- [[_COMMUNITY_Community 36|Community 36]]
- [[_COMMUNITY_Community 37|Community 37]]
- [[_COMMUNITY_Community 38|Community 38]]
- [[_COMMUNITY_Community 39|Community 39]]
- [[_COMMUNITY_Community 40|Community 40]]
- [[_COMMUNITY_Community 41|Community 41]]
- [[_COMMUNITY_Community 42|Community 42]]
- [[_COMMUNITY_Community 43|Community 43]]
- [[_COMMUNITY_Community 45|Community 45]]
- [[_COMMUNITY_Community 46|Community 46]]
- [[_COMMUNITY_Community 44|Community 44]]
- [[_COMMUNITY_Community 47|Community 47]]
- [[_COMMUNITY_Community 48|Community 48]]
- [[_COMMUNITY_Community 50|Community 50]]
- [[_COMMUNITY_Community 51|Community 51]]
- [[_COMMUNITY_Community 52|Community 52]]
- [[_COMMUNITY_Community 54|Community 54]]
- [[_COMMUNITY_Community 55|Community 55]]
- [[_COMMUNITY_Community 56|Community 56]]
- [[_COMMUNITY_Community 53|Community 53]]
- [[_COMMUNITY_Community 58|Community 58]]
- [[_COMMUNITY_Community 63|Community 63]]
- [[_COMMUNITY_Community 65|Community 65]]
- [[_COMMUNITY_Community 60|Community 60]]
## God Nodes (most connected - your core abstractions)
1. `get()` - 260 edges
@@ -83,76 +78,76 @@
components/business/clinical-schedule-payment-detail/index.vue → utils/money-format.ts
- `subscribeTokenRefresh()` --calls--> `push()` [INFERRED]
utils/http/index.ts → views/operations/storage-facility/index.vue
- `handleUnauthorizedResponse()` --calls--> `fetchRefreshToken()` [INFERRED]
utils/http/index.ts → api/auth.ts
- `fetchLeaveList()` --calls--> `get()` [INFERRED]
api/leave.ts → views/production/process/ProcessRouteTab.vue
- `fetchSampleReceptionCheckItemList()` --calls--> `get()` [INFERRED]
api/sample-reception-check-item.ts → views/production/process/ProcessRouteTab.vue
- `fetchStorageReleaseReviewList()` --calls--> `get()` [INFERRED]
api/storage-release-review.ts → views/production/process/ProcessRouteTab.vue
## Communities
### Community 0 - "Community 0"
Cohesion: 0.01
Nodes (144): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchChannelAccount(), fetchChannelAgreementPrices(), fetchChannelAgreements() (+136 more)
Nodes (179): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchChannelAccount(), fetchChannelAgreementPrices(), fetchChannelAgreements() (+171 more)
### Community 1 - "Community 1"
Cohesion: 0.02
Nodes (101): fetchUploadAttachment(), fetchMyProductionTasks(), fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), reload(), handleReportUpload(), handleReportUpload() (+93 more)
Cohesion: 0.01
Nodes (11): fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchDeleteProjectSystemItem(), fetchGetRoleList(), fetchNotDeletedRegions(), fetchRegionList(), fetchUpdateCheckupInstitution(), fetchUpdateCheckupInstitutionInvoice() (+3 more)
### Community 2 - "Community 2"
Cohesion: 0.02
Nodes (42): fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllConsumableStockLogs(), fetchAllEquipments(), fetchAllOutputTypes(), fetchAllProcessCategories(), fetchAllProcesses(), fetchAllReagents() (+34 more)
Cohesion: 0.03
Nodes (50): fetchGetMenuList(), fetchGetMenuCodes(), fetchGetUserInfo(), fetchLogin(), fetchUpdateProfile(), fetchUploadProfileAvatar(), IframeRouteManager, MenuProcessor (+42 more)
### Community 3 - "Community 3"
Cohesion: 0.04
Nodes (75): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchPilotCheckupDetail(), markPilotCheckupChecked(), savePilotCheckup(), savePilotCheckupActualItems() (+67 more)
Cohesion: 0.03
Nodes (62): fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionList(), fetchCheckupInstitutionProjects(), fetchCreateCheckupInstitutionProject(), fetchUpdateCheckupInstitutionProject(), submitOutboundReleaseReview(), fetchConsumablePackDetail(), fetchConsumablePackList() (+54 more)
### Community 4 - "Community 4"
Cohesion: 0.03
Nodes (52): fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionList(), fetchCheckupInstitutionProjects(), fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchCreateCheckupInstitutionProject(), fetchUpdateCheckupInstitution(), fetchUpdateCheckupInstitutionInvoice() (+44 more)
Nodes (59): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), fetchProductionTaskList(), handleAdd(), handleDelete() (+51 more)
### Community 5 - "Community 5"
Cohesion: 0.03
Nodes (42): fetchProductionTaskList(), fetchApproveTask(), fetchBusinessAllTasks(), fetchCompletedTasks(), fetchDesignerData(), fetchInstanceDetail(), fetchMyInstances(), fetchPendingTasks() (+34 more)
Cohesion: 0.04
Nodes (66): fetchUploadAttachment(), FireworkSystem, reload(), handleReportUpload(), handleReportUpload(), walk(), formatTodayDate(), handleMenuJump() (+58 more)
### Community 6 - "Community 6"
Cohesion: 0.04
Nodes (30): fetchGetUserInfo(), ComponentLoader, IframeRouteManager, RouteRegistry, RouteTransformer, useCommon(), setupAfterEachGuard(), closeLoading() (+22 more)
Nodes (75): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchPilotCheckupActualItems(), fetchPilotCheckupDetail(), fetchPilotCheckupReserveItems(), markPilotCheckupChecked() (+67 more)
### Community 7 - "Community 7"
Cohesion: 0.04
Nodes (44): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), fetchCreateEnvDetectItem(), fetchDeleteEnvDetectItem(), fetchEnvDetectItemDetail(), fetchEnvDetectItemList() (+36 more)
Cohesion: 0.03
Nodes (43): fetchMyProductionTasks(), fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), for(), set(), annotateForkEdges(), chainApiToElements() (+35 more)
### Community 8 - "Community 8"
Cohesion: 0.05
Nodes (34): fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed(), fetchClinicalRefundPending(), fetchOrderAdjusts(), fetchOrderDetail() (+26 more)
Cohesion: 0.04
Nodes (51): fetchCellProductSpecList(), fetchCellProductTypeList(), fetchStorageSlotSelectOptions(), useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony() (+43 more)
### Community 9 - "Community 9"
Cohesion: 0.06
Nodes (11): fetchGetLatestUpgradeLog(), getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager (+3 more)
Cohesion: 0.04
Nodes (48): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchCreateMenu(), fetchDeleteCellSampleType(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateCellSampleType(), fetchUpdateMenu() (+40 more)
### Community 10 - "Community 10"
Cohesion: 0.06
Nodes (30): buildBaseFields(), buildInboundBasicSection(), buildInboundCellStorageProductionViewSections(), buildInboundResearchDonationProductionViewSections(), buildOutboundBasicExperimentProductionViewSections(), buildOutboundClinicalProductionViewSections(), buildOutboundDetail(), buildOutboundPilotProductionViewSections() (+22 more)
Cohesion: 0.04
Nodes (37): fetchInfusionScheduleMgmtDetail(), fetchAttachmentDownloadUrl(), qcAttachmentFullUrl(), qcDownloadAttachment(), qcPreviewAttachment(), handleDownloadAttachment(), attachmentFullUrl(), handleAttachmentDownload() (+29 more)
### Community 11 - "Community 11"
Cohesion: 0.05
Nodes (29): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), collectAllPostBindDeptIds(), collectPostBindDeptSubtreeIds() (+21 more)
Nodes (34): fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed(), fetchClinicalRefundPending(), fetchOrderAdjusts(), fetchOrderDetail() (+26 more)
### Community 12 - "Community 12"
Cohesion: 0.05
Nodes (28): handleBlur(), handleFocus(), handleInput(), fetchEthnicList(), formatAmount(), formatAmount(), formatProtocolAmount(), buildFeeSection() (+20 more)
Cohesion: 0.06
Nodes (35): fetchRefreshToken(), toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url() (+27 more)
### Community 13 - "Community 13"
Cohesion: 0.05
Nodes (13): fmtMoney(), auditorDisplay(), dash(), ensureUnitsInOptions(), expressName(), formatYm(), formatYmd(), sampleTypeName() (+5 more)
Cohesion: 0.06
Nodes (37): buildBaseFields(), buildInboundBasicSection(), buildInboundCellStorageProductionViewSections(), buildInboundResearchDonationProductionViewSections(), buildOutboundBasicExperimentProductionViewSections(), buildOutboundClinicalProductionViewSections(), buildOutboundDetail(), buildOutboundPilotProductionViewSections() (+29 more)
### Community 14 - "Community 14"
Cohesion: 0.05
Nodes (28): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList(), fetchPaymentDetailList(), fetchReceiptConfirmedList(), fetchReceiptConfirmList() (+20 more)
Nodes (28): handleBlur(), handleFocus(), handleInput(), fetchEthnicList(), formatAmount(), formatAmount(), formatProtocolAmount(), buildFeeSection() (+20 more)
### Community 15 - "Community 15"
Cohesion: 0.07
Nodes (23): fetchGetMenuList(), fetchGetMenuCodes(), fetchLogin(), fetchRefreshToken(), fetchUpdateProfile(), fetchUploadProfileAvatar(), MenuProcessor, useAppMode() (+15 more)
Cohesion: 0.05
Nodes (13): fmtMoney(), auditorDisplay(), dash(), ensureUnitsInOptions(), expressName(), formatYm(), formatYmd(), sampleTypeName() (+5 more)
### Community 16 - "Community 16"
Cohesion: 0.07
@@ -163,184 +158,160 @@ Cohesion: 0.07
Nodes (24): fetchDeleteQcMaterialBatch(), fetchQcMaterialBatchList(), fetchQcMaterialBatchOptions(), fetchQcMaterialList(), fetchQcMaterialOptions(), fetchUpdateQcMaterialBatch(), fetchMarkQcMaterialUsageFullyUsed(), ensureTabMounted() (+16 more)
### Community 18 - "Community 18"
Cohesion: 0.06
Nodes (24): fetchAttachmentDownloadUrl(), qcAttachmentFullUrl(), qcDownloadAttachment(), qcPreviewAttachment(), handleDownloadAttachment(), fullFileUrl(), handleDownloadAttachment(), handlePreviewAttachment() (+16 more)
### Community 19 - "Community 19"
Cohesion: 0.1
Nodes (2): WebSocketClient, TableCache
### Community 20 - "Community 20"
### Community 19 - "Community 19"
Cohesion: 0.08
Nodes (28): fetchUserOptions(), fetchSampleReceptionCheckItemList(), fetchSampleReceptionCheckItemsActive(), fetchAllocateLabStorageCodes(), fetchSampleReceptionBySampleCode(), fetchSampleReceptionDetail(), fetchSampleReceptionPendingList(), fetchSampleReceptionReceivedList() (+20 more)
### Community 20 - "Community 20"
Cohesion: 0.09
Nodes (8): getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager, validateStorageData()
### Community 21 - "Community 21"
Cohesion: 0.08
Nodes (32): toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes() (+24 more)
Nodes (29): fetchCreateUser(), fetchDeleteUser(), fetchDeptTree(), fetchPostBoundUserIds(), fetchResetPassword(), fetchRoleOptions(), fetchUpdateUser(), fetchUserDetail() (+21 more)
### Community 22 - "Community 22"
Cohesion: 0.09
Nodes (26): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), handleDelete(), handleDropdownCommand(), handleEdit() (+18 more)
### Community 23 - "Community 23"
Cohesion: 0.09
Nodes (28): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), clearTableSelection(), handleBatchComplete(), handleBatchStart() (+20 more)
### Community 23 - "Community 23"
Cohesion: 0.07
Nodes (18): fetchDictDataOptions(), fetchDeleteMaterialBatch(), fetchMaterialBatchList(), fetchMaterialBatchOptions(), fetchMaterialList(), fetchMaterialOptions(), fetchUpdateMaterialBatch(), fetchMaterialUsageList() (+10 more)
### Community 24 - "Community 24"
Cohesion: 0.08
Nodes (16): fetchDeleteMaterialBatch(), fetchMaterialBatchList(), fetchMaterialBatchOptions(), fetchMaterialList(), fetchMaterialOptions(), fetchUpdateMaterialBatch(), fetchMaterialUsageList(), fetchMyMaterialUsageList() (+8 more)
Cohesion: 0.1
Nodes (21): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolDetail(), buildInsuranceAttachmentsValue(), buildInsurancePayload(), formatYmdFromAny(), fullFileUrl(), handleBatchEdit() (+13 more)
### Community 25 - "Community 25"
Cohesion: 0.11
Nodes (26): fetchCellProductSpecList(), fetchCellProductTypeList(), handleAdd(), resetForm(), applyProductCodeToLines(), calcExpiryFromFreeze(), createEmptyProductLine(), createQuantityValue() (+18 more)
### Community 26 - "Community 26"
Cohesion: 0.13
Nodes (20): fetchCreateUser(), fetchDeleteUser(), fetchResetPassword(), fetchUpdateUser(), fetchUserDetail(), formatUserDeptDisplay(), handleAdd(), handleBatchDelete() (+12 more)
### Community 27 - "Community 27"
Cohesion: 0.12
Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
### Community 28 - "Community 28"
Cohesion: 0.11
Nodes (11): fetchOutboundReleaseMaterial(), fetchOutboundReleaseReviewDetail(), fetchOutboundReleaseReviewList(), fetchReleaseReviewList(), handleReset(), handleSearch(), handleToggleSelect(), loadData() (+3 more)
### Community 26 - "Community 26"
Cohesion: 0.16
Nodes (14): fetchCreateEnvDetectItem(), fetchDeleteEnvDetectItem(), fetchEnvDetectItemDetail(), fetchEnvDetectItemList(), fetchEnvDetectItemsActive(), fetchUpdateEnvDetectItem(), handleAdd(), handleBatchDelete() (+6 more)
### Community 29 - "Community 29"
Cohesion: 0.13
Nodes (18): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchDeleteCellSampleType(), fetchUpdateCellSampleType(), handleAdd(), handleDelete(), handleDropdownCommand(), handleEdit() (+10 more)
### Community 30 - "Community 30"
### Community 27 - "Community 27"
Cohesion: 0.16
Nodes (10): useTable(), useTableImpl(), getColumnChecks(), useTableColumns(), createErrorHandler(), createSmartDebounce(), defaultResponseAdapter(), extractPagination() (+2 more)
### Community 31 - "Community 31"
### Community 28 - "Community 28"
Cohesion: 0.2
Nodes (2): ComponentLoader, RouteTransformer
### Community 29 - "Community 29"
Cohesion: 0.27
Nodes (14): useChart(), useChartComponent(), useChartOps(), colourBlend(), getCssVar(), getDarkColor(), getLightColor(), handleElementThemeColor() (+6 more)
### Community 32 - "Community 32"
### Community 30 - "Community 30"
Cohesion: 0.33
Nodes (13): buildProtocolPaymentFlowSteps(), dash(), financeReceiptTime(), formatAmount(), hasFinanceReceipt(), hasFinanceRefund(), hasReceiptSubmit(), hasRefundSubmit() (+5 more)
### Community 33 - "Community 33"
### Community 31 - "Community 31"
Cohesion: 0.19
Nodes (6): fetchServiceOrderTxnList(), handleReset(), handleSearch(), handleTabChange(), loadData(), switchTab()
### Community 33 - "Community 33"
Cohesion: 0.21
Nodes (7): handleReset(), handleSearch(), handleToggleSelect(), loadData(), onReviewSubmitted(), rowId(), isSelected()
### Community 34 - "Community 34"
Cohesion: 0.18
Nodes (3): normalizeStepSubTables(), parseEquipmentIds(), syncEquipmentNamesFromOptions()
### Community 35 - "Community 35"
Cohesion: 0.17
Nodes (3): fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList()
### Community 36 - "Community 36"
Cohesion: 0.18
Nodes (3): normalizeStepSubTables(), parseEquipmentIds(), syncEquipmentNamesFromOptions()
### Community 37 - "Community 37"
Cohesion: 0.24
Nodes (6): buildInboundMetaFields(), getCardMetaConfig(), getCardMetaConfigForLegacyTab(), parseReceptionTime(), receptionOver24HoursLabel(), receptionOver24HoursTagType()
### Community 38 - "Community 38"
### Community 37 - "Community 37"
Cohesion: 0.42
Nodes (9): buildPaymentFlowSteps(), dash(), formatAmount(), hasFinanceReceipt(), hasFinanceRefund(), hasReceiptSubmit(), hasRefundSubmit(), receiptSubmitTime() (+1 more)
### Community 39 - "Community 39"
### Community 38 - "Community 38"
Cohesion: 0.29
Nodes (5): canConfigureWorkOrder(), canDeleteWorkOrder(), canEditRemarkWorkOrder(), canEditTemporaryWorkOrder(), hasMoreWorkOrderActions()
### Community 40 - "Community 40"
### Community 39 - "Community 39"
Cohesion: 0.25
Nodes (2): handleTouchEnd(), setTransition()
### Community 41 - "Community 41"
Cohesion: 0.28
Nodes (1): FireworkSystem
### Community 43 - "Community 43"
Cohesion: 0.31
Nodes (4): annotateForkEdges(), chainApiToElements(), walkAncestorBranch(), walkAncestorParents()
### Community 45 - "Community 45"
### Community 42 - "Community 42"
Cohesion: 0.28
Nodes (4): fetchMyProductionMaterialConsumptions(), handleReset(), handleSearch(), loadData()
### Community 46 - "Community 46"
### Community 43 - "Community 43"
Cohesion: 0.39
Nodes (6): isIgnorableScriptError(), normalizeErrorMessage(), registerPromiseErrorHandler(), registerResourceErrorHandler(), scriptErrorHandler(), setupErrorHandle()
### Community 47 - "Community 47"
### Community 44 - "Community 44"
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"
Cohesion: 0.29
Nodes (2): fetchLeaveDetail(), fetchLeaveList()
### Community 52 - "Community 52"
### Community 48 - "Community 48"
Cohesion: 0.47
Nodes (3): isPaymentDueWithinWarnWindow(), parsePaymentDueYmd(), startOfLocalDay()
### Community 54 - "Community 54"
Cohesion: 0.33
Nodes (2): fetchQcLabTestItemList(), fetchQcLabTestItemsActive()
### Community 55 - "Community 55"
### Community 50 - "Community 50"
Cohesion: 0.5
Nodes (2): formatProtocolDocDeleteConfirm(), formatProtocolDocSubject()
### Community 56 - "Community 56"
### Community 51 - "Community 51"
Cohesion: 0.5
Nodes (2): focusInput(), handleKeydown()
### Community 58 - "Community 58"
### Community 53 - "Community 53"
Cohesion: 0.67
Nodes (2): if(), logSidebarMenu()
### Community 63 - "Community 63"
### Community 58 - "Community 58"
Cohesion: 1.0
Nodes (2): getSettingDefaults(), resetToDefaults()
### Community 65 - "Community 65"
### Community 60 - "Community 60"
Cohesion: 1.0
Nodes (2): copyTextToClipboard(), copyTextWithFallback()
## Knowledge Gaps
- **Thin community `Community 19`** (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 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`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 40`** (9 nodes): `cleanupEventListeners()`, `handleTouchEnd()`, `handleTouchMove()`, `handleTouchStart()`, `handleWheelScroll()`, `if()`, `setTransition()`, `setupEventListeners()`, `index.vue`
- **Thin community `Community 28`** (17 nodes): `ComponentLoader`, `.constructor()`, `.createEmptyComponent()`, `.createErrorComponent()`, `.load()`, `.loadIframe()`, `.loadLayout()`, `.load()`, `RouteTransformer`, `.extractFirstSegment()`, `.handleFirstLevelRoute()`, `.handleIframeRoute()`, `.handleNormalRoute()`, `.isFirstLevelRoute()`, `.transform()`, `ComponentLoader.ts`, `RouteTransformer.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 41`** (9 nodes): `FireworkSystem`, `.constructor()`, `.createFirework()`, `.createParticle()`, `.getAvailableParticle()`, `.initializePool()`, `.preloadAllImages()`, `.preloadImage()`, `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 47`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
- **Thin community `Community 44`** (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 50`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.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 51`** (7 nodes): `fetchCreateLeave()`, `fetchDeleteLeave()`, `fetchLeaveDetail()`, `fetchLeaveList()`, `fetchSubmitLeave()`, `fetchUpdateLeave()`, `leave.ts`
- **Thin community `Community 50`** (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 54`** (6 nodes): `fetchCreateQcLabTestItem()`, `fetchDeleteQcLabTestItem()`, `fetchQcLabTestItemList()`, `fetchQcLabTestItemsActive()`, `fetchUpdateQcLabTestItem()`, `qc-lab-test-item.ts`
- **Thin community `Community 51`** (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 55`** (5 nodes): `formatProtocolDocBatchDeleteConfirm()`, `formatProtocolDocDeleteConfirm()`, `formatProtocolDocSubject()`, `getProtocolDocTypeLabel()`, `protocol-doc-label.ts`
- **Thin community `Community 53`** (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 56`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
- **Thin community `Community 58`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 58`** (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 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 65`** (3 nodes): `copyTextToClipboard()`, `copyTextWithFallback()`, `copy-text.ts`
- **Thin community `Community 60`** (3 nodes): `copyTextToClipboard()`, `copyTextWithFallback()`, `copy-text.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 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 11`, `Community 12`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 20`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 28`, `Community 29`, `Community 33`, `Community 35`, `Community 43`, `Community 45`, `Community 51`, `Community 54`?**
_High betweenness centrality (0.368) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 7`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 16`, `Community 19`, `Community 21`, `Community 23`, `Community 25`, `Community 37`, `Community 41`?**
_High betweenness centrality (0.188) - this node is a cross-community bridge._
- **Why does `emit()` connect `Community 5` to `Community 3`, `Community 4`, `Community 12`, `Community 16`, `Community 20`, `Community 22`, `Community 25`?**
_High betweenness centrality (0.043) - this node is a cross-community bridge._
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 14`, `Community 16`, `Community 17`, `Community 19`, `Community 21`, `Community 22`, `Community 23`, `Community 24`, `Community 26`, `Community 31`, `Community 35`, `Community 42`?**
_High betweenness centrality (0.365) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 5` to `Community 1`, `Community 3`, `Community 36`, `Community 4`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 16`, `Community 18`, `Community 21`, `Community 22`, `Community 24`?**
_High betweenness centrality (0.184) - this node is a cross-community bridge._
- **Why does `emit()` connect `Community 4` to `Community 0`, `Community 3`, `Community 6`, `Community 14`, `Community 16`, `Community 19`?**
_High betweenness centrality (0.032) - this node is a cross-community bridge._
- **Are the 259 inferred relationships involving `get()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
_`get()` has 259 INFERRED edges - model-reasoned connections that need verification._
- **Are the 62 inferred relationships involving `push()` (e.g. with `collectLeafFacilityNodesInTreeOrder()` and `formatDetectMethods()`) actually correct?**
+4 -4
View File
@@ -57,12 +57,12 @@
</div>
<div id="legend"></div>
</div>
<div id="stats">2560 nodes &middot; 3538 edges &middot; 316 communities</div>
<div id="stats">2581 nodes &middot; 3576 edges &middot; 309 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": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 102, "community_name": "Community 102", "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": 103, "community_name": "Community 103", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 27, "community_name": "Community 27", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 27, "community_name": "Community 27", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 27, "community_name": "Community 27", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 27, "community_name": "Community 27", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 27, "community_name": "Community 27", "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": 412}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 156}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 104}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 93}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 90}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 80}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 77}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 72}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 59}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 55}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 54}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 52}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 51}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 49}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 48}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 47}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 45}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 44}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 43}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 42}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 41}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 40}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 37}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 35}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 32}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 30}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 24}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 22}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 22}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 22}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 17}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 16}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 14}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 14}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 13}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 12}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 12}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 11}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 10}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 10}, {"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": 9}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 9}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 8}, {"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": 6}, {"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": 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
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": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 97, "community_name": "Community 97", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 98, "community_name": "Community 98", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 25, "community_name": "Community 25", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 25, "community_name": "Community 25", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 25, "community_name": "Community 25", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 25, "community_name": "Community 25", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 25, "community_name": "Community 25", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_setuprolesdirective", "laLine truncated
const RAW_EDGES = [{"from": "app_vue", "to": "src_app_refreshbuttonautoicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "src_app_refreshpaneltitleicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "main_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "utils_sys_console_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_masksecret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_logapicryptobootinfo", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_main_masksecret", "to": "src_main_logapicryptobootinfo", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_ts", "to": "directives_index_setupglobdirectives", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_setupglobdirectives", "to": "core_auth_setupauthdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "core_roles_setuprolesdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_highlight_setuphighlightdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_ripple_setuprippledirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_core_roles_ts", "to": "core_roles_checkrolepermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_setuprolesdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_roles_checkrolepermission", "to": "core_roles_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_checkauthpermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_setupauthdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_checkauthpermission", "to": "core_auth_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_ripple_ts", "to": "business_ripple_setuprippledirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_highlightcode", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_insertlinenumbers", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_addcopybutton", "label": "contains", "title": "contains [EXTRACTED]", "dLine truncated
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 354}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 194}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 106}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 104}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 101}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 96}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 92}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 82}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 76}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 75}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 63}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 59}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 58}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 57}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 51}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 50}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 45}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 44}, {"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": 35}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 35}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 34}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 30}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 22}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 19}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 17}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 17}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 16}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 14}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 14}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 13}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 13}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 12}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 12}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 11}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 10}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 10}, {"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": 8}, {"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": 6}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 6}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 5}, {"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": 4}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 4}, {"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": 3}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 3}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 3}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 3}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 3}, {"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": 2}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 2}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 2}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 2}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "cLine 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
+17 -16
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": 1781602052.782289,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1781601612.8187408,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1781604188.41692,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1781603268.522488,
"/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": 1781272556.3652694,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/locales/index.ts": 1781272556.3657222,
@@ -53,7 +53,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-mine-task-groups.ts": 1781583493.924234,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-mine-task-groups.ts": 1781595945.3450615,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-payment-labels.ts": 1781272556.3878465,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts": 1781590344.2129211,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts": 1781604158.2285209,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts": 1781595872.8488274,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/fetch-paged-list.ts": 1781272556.3903377,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/sort-order.ts": 1781272556.3913012,
@@ -196,6 +196,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/protocol-finance-confirm-fields/finance-attachments.ts": 1781272556.6256514,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/qc-task-view-dialog/index.vue": 1781590356.7882614,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-payment-confirm-timeline/index.vue": 1781601573.628867,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue": 1781604188.1794512,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/dialog-form-body/index.vue": 1781272556.6276903,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-payment-submit-readonly/index.vue": 1781566692.993364,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-cards/index.vue": 1781596037.4093332,
@@ -203,7 +204,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/product-view-dialog/index.vue": 1781563767.2879,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-production-info-cards/index.vue": 1781585388.6388853,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-storage-release-info/index.vue": 1781585388.6396642,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue": 1781595984.8103893,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue": 1781604395.3414226,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/work-order-remark-dialog/index.vue": 1781563767.2910764,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-grouped-panel/index.vue": 1781596014.9588113,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue": 1781585388.6415968,
@@ -230,7 +231,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception-check-item.ts": 1781272556.654672,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts": 1781497438.3206656,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/infusion-schedule-handover.ts": 1781272556.6558568,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts": 1781597289.1718442,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts": 1781603141.9232655,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-third-party-item.ts": 1781272556.6567156,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/env-detect-record.ts": 1781272556.6569912,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts": 1781536765.5084789,
@@ -265,7 +266,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material.ts": 1781346022.817811,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts": 1781496419.5874305,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/auth.ts": 1781272556.6719868,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts": 1781596860.828625,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts": 1781603236.5340948,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/auth/login/index.vue": 1781272556.6735966,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/refund-confirm/index.vue": 1781272556.6742516,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/my-material-usage/index.vue": 1781518736.690082,
@@ -382,7 +383,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/view-dialog-registry.ts": 1781583337.2398212,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/OutboundPilotProductionViewDialog.vue": 1781583332.539871,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/OutboundBasicExperimentProductionViewDialog.vue": 1781583335.5489588,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/ProductionWorkOrderViewDialogFrame.vue": 1781588255.6300747,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/ProductionWorkOrderViewDialogFrame.vue": 1781604410.6211355,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/TemporaryProductionViewDialog.vue": 1781583336.381873,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable-pack/index.vue": 1781272556.8373108,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable/index.vue": 1781563767.346933,
@@ -425,15 +426,15 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/inbound-view-sections.ts": 1781581785.95148,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts": 1781600311.9968688,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/QcWorkOrderSystemViewDialog.vue": 1781589553.6371684,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundQcProductTable.vue": 1781588255.5778198,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundQcProductTable.vue": 1781604200.1464918,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundQcDiagnosisAttachments.vue": 1781581843.4276094,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/view-dialog-registry.ts": 1781582168.445552,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/InboundResearchDonationViewDialog.vue": 1781589531.009138,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundBasicExperimentViewDialog.vue": 1781589544.2223613,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundClinicalViewDialog.vue": 1781589542.842761,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundBasicExperimentViewDialog.vue": 1781604200.1465678,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundClinicalViewDialog.vue": 1781604200.291363,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/InboundCellStorageViewDialog.vue": 1781589526.0101316,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/TemporaryQcViewDialog.vue": 1781589531.7431345,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundPilotViewDialog.vue": 1781589545.1827385,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundPilotViewDialog.vue": 1781604200.1465576,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception-check-item/index.vue": 1781563767.3726647,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/index.vue": 1781585388.7276096,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/ThirdPartyCompanyTab.vue": 1781585388.7286375,
@@ -463,7 +464,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-institution/CheckupPackagePanel.vue": 1781563767.3335872,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/index.vue": 1781272556.9129293,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/InfusionScheduleHandoverDialog.vue": 1781598379.1921296,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleViewDialog.vue": 1781595979.906165,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleViewDialog.vue": 1781604365.0831292,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleCancelDialog.vue": 1781566676.0091887,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleEditDialog.vue": 1781585388.7521496,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue": 1781272556.9223943,
@@ -475,11 +476,11 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-refund-confirm/index.vue": 1781272556.946893,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/index.vue": 1781602093.5398912,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue": 1781602099.6746335,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue": 1781600465.6143773,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseViewDialog.vue": 1781596823.2469816,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue": 1781596862.0797033,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue": 1781603476.7874172,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseViewDialog.vue": 1781604292.523926,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue": 1781603474.5398026,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseMaterialDialog.vue": 1781597037.1667814,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue": 1781598589.824023,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue": 1781603141.923382,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/index.vue": 1781600006.408287,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationDetailDialog.vue": 1781599768.7755723,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue": 1781272557.1928792,
+16
View File
@@ -40,6 +40,22 @@ export function fetchNextCellProductCode(count = 1) {
})
}
export function fetchMaxPassageProductSeq(productCode: string, passages: string[]) {
const normalized = [...new Set(passages.map((p) => p.trim()).filter(Boolean))]
return request.get<{
maxSeq?: number
nextSeq?: number
maxSeqByPassage?: Record<string, number>
nextSeqByPassage?: Record<string, number>
}>({
url: '/web/admin/cell-products/max-passage-seq',
params: {
productCode: productCode.trim(),
passages: normalized.join(',')
}
})
}
export function fetchCellProductChain(productId: string) {
return request.get<any>({ url: `/web/admin/cell-products/${productId}/chain` })
}
@@ -22,6 +22,8 @@ export type OutboundReleaseReview = {
bizType?: string
bizTypeLabel?: string
applicationNo?: string
projectTitle?: string
customerName?: string
patientName?: string
cellType?: string
specText?: string
+3
View File
@@ -281,10 +281,13 @@ export type OutboundQcDetailInfusionSchedule = {
infusionTime?: string
infusionLocation?: string
infusionMethod?: string
cellType?: string
specText?: string
scheduleStatus?: string
infusionStatus?: string
qcStatus?: string
cancelReason?: string
amount?: number
}
export type OutboundQcDetailProduct = {
@@ -21,156 +21,10 @@
<div class="outbound-chain-section">
<div class="section-subtitle">出库物料准备</div>
<div class="outbound-material-view">
<div v-if="!hasOutboundMaterial" class="outbound-material-empty">暂无出库物料准备记录</div>
<template v-else>
<div v-if="outboundMaterialCells.length" class="outbound-material-block">
<h4 class="outbound-material-subtitle">出库细胞</h4>
<el-table
:data="outboundMaterialCells"
class="list-table inner-table"
stripe
size="small"
>
<el-table-column type="index" label="序号" min-width="56" align="center" />
<el-table-column
prop="productCode"
label="产品编码"
min-width="150"
show-overflow-tooltip
/>
<el-table-column
prop="productName"
label="产品名称"
min-width="120"
show-overflow-tooltip
/>
<el-table-column prop="productTypeName" label="类型" min-width="90" />
<el-table-column prop="specName" label="规格" min-width="90" />
<el-table-column
prop="storageSlotName"
label="储物格"
min-width="130"
show-overflow-tooltip
/>
<el-table-column label="状态" min-width="90" align="center">
<template #default="{ row }">
<el-tag
v-if="row.productStatus"
:type="cellProductStatusTagType(row.productStatus) as any"
size="small"
>
{{ cellProductStatusLabel(row.productStatus) }}
</el-tag>
<span v-else>—</span>
</template>
</el-table-column>
</el-table>
</div>
<div v-if="outboundMaterialQcRows.length" class="outbound-material-block">
<h4 class="outbound-material-subtitle">使用的物料</h4>
<el-table
:data="outboundMaterialQcRows"
class="list-table inner-table"
stripe
size="small"
>
<el-table-column type="index" label="序号" min-width="56" align="center" />
<el-table-column
prop="materialName"
label="物料名称"
min-width="140"
show-overflow-tooltip
/>
<el-table-column prop="specModel" label="规格型号" min-width="110" />
<el-table-column label="计划用量" min-width="100" align="center">
<template #default="{ row }">{{ row.qty ?? '—' }}</template>
</el-table-column>
<el-table-column prop="unit" label="单位" min-width="72" align="center" />
</el-table>
</div>
<div v-if="outboundPaperRows.length" class="outbound-material-block">
<h4 class="outbound-material-subtitle">其他纸质材料</h4>
<el-table
:data="outboundPaperRows"
class="list-table inner-table"
stripe
size="small"
>
<el-table-column type="index" label="序号" min-width="56" align="center" />
<el-table-column prop="paperName" label="名称" min-width="140" show-overflow-tooltip />
<el-table-column label="份数" min-width="80" align="center">
<template #default="{ row }">{{ row.copies ?? '—' }}</template>
</el-table-column>
<el-table-column label="附件" min-width="320">
<template #default="{ row }">
<div v-if="parsePaperAttachments(row.attachmentUrl).length" class="paper-att-cards">
<div
v-for="(att, attIdx) in parsePaperAttachments(row.attachmentUrl)"
:key="attIdx"
class="paper-att-card"
:class="{
'paper-att-card--image': isImageFile(att),
'paper-att-card--video': isVideoFile(att)
}"
:title="att.fileName"
>
<div
class="paper-att-card__preview"
:class="{
'is-clickable': isImageFile(att) || isVideoFile(att)
}"
@click="
(isImageFile(att) || isVideoFile(att)) &&
handlePreviewPaperAttachment(att)
"
>
<img
v-if="isImageFile(att)"
:src="attachmentFullUrl(att.attachmentUrl)"
:alt="att.fileName || '附件'"
/>
<template v-else-if="isVideoFile(att)">
<div class="paper-att-card__type-icon paper-att-card__type-icon--video">
<el-icon><VideoPlay /></el-icon>
</div>
</template>
<template v-else>
<el-icon class="paper-att-card__type-icon paper-att-card__type-icon--doc">
<Document />
</el-icon>
<span class="paper-att-card__name">{{ att.fileName || '附件' }}</span>
</template>
</div>
<div class="paper-att-card__actions">
<el-icon
v-if="isImageFile(att) || isVideoFile(att)"
class="paper-att-card__action"
title="预览"
@click.stop="handlePreviewPaperAttachment(att)"
>
<View />
</el-icon>
<el-icon
class="paper-att-card__action"
title="下载"
@click.stop="handleDownloadPaperAttachment(att)"
>
<Download />
</el-icon>
</div>
</div>
</div>
<span v-else>—</span>
</template>
</el-table-column>
</el-table>
</div>
<p v-if="outboundMaterialRemark" class="outbound-material-remark">
备注:{{ outboundMaterialRemark }}
</p>
</template>
</div>
<OutboundMaterialReadonlyPanel
:material="outboundMaterial"
:biz-type="scheduleBizType"
/>
</div>
<div class="outbound-chain-section">
@@ -278,7 +132,7 @@
<div class="data-item data-item--full">
<div class="data-label">说明</div>
<div class="data-value data-value--muted">
已在输注计划管理中确认,暂无独立应用确认记录
已在{{ scheduleBizConfig.scheduleLabel }}管理中确认,暂无独立应用确认记录
</div>
</div>
</template>
@@ -291,48 +145,23 @@
</div>
</div>
</template>
<el-dialog
v-model="previewVisible"
title="文件预览"
width="800px"
align-center
destroy-on-close
append-to-body
style="backdrop-filter: none"
>
<div v-if="previewType === 'image'" class="preview-container">
<img
:src="previewUrl"
alt="预览"
style="max-width: 100%; max-height: 70vh; display: block; margin: 0 auto"
/>
</div>
<div v-else class="preview-container">
<video
:src="previewUrl"
controls
style="max-width: 100%; max-height: 70vh; display: block; margin: 0 auto"
/>
</div>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { Document, Download, View, VideoPlay } from '@element-plus/icons-vue'
import SampleProductionInfoCards from '@/components/business/sample-production-info-cards/index.vue'
import SampleQcInfoGroupedPanel from '@/components/business/sample-qc-info-grouped-panel/index.vue'
import OutboundMaterialReadonlyPanel from '@/components/business/outbound-material-readonly-panel/index.vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
import { fetchInfusionScheduleMgmtDetail } from '@/api/admin'
import { getPilotBizConfig, resolvePilotBizType } from '@/config/pilot-biz-type'
import { resolveOutboundViewVariant } from '@/utils/outbound-qc-pilot-view-sections'
import {
storageReleaseConclusionLabel,
storageReleaseConclusionTagType,
infusionStatusLabel,
infusionStatusTagType,
cellProductStatusLabel,
cellProductStatusTagType
infusionStatusTagType
} from '@/utils/status-tag-registry'
import { downloadAttachmentFile } from '@/utils/download-attachment'
@@ -355,60 +184,26 @@
const loading = ref(false)
const fetchedDetail = ref<Record<string, any> | null>(null)
const previewVisible = ref(false)
const previewUrl = ref('')
const previewType = ref<'image' | 'video'>('image')
type PaperAttachmentView = {
fileName: string
attachmentUrl: string
fileUrl: string
fileType?: string
}
const minioBaseUrl = (import.meta.env.VITE_MINIO_BASE_URL || '').replace(/\/$/, '')
const detail = computed(() => props.detailData || fetchedDetail.value)
const scheduleBizConfig = computed(() =>
getPilotBizConfig(
resolvePilotBizType(detail.value?.application?.bizType || detail.value?.bizType)
)
)
const scheduleBizType = computed(() =>
resolveOutboundViewVariant(detail.value?.application?.bizType || detail.value?.bizType)
)
const review = computed(() => detail.value?.reviewInfo || {})
const outboundHandover = computed(() => detail.value?.outboundHandover || {})
const infusionConfirm = computed(() => detail.value?.infusionConfirm || {})
const outboundMaterial = computed(() => detail.value?.outboundMaterial || null)
const outboundMaterialCells = computed(() => outboundMaterial.value?.cells || [])
const outboundMaterialQcRows = computed(() => outboundMaterial.value?.qcMaterials || [])
const outboundMaterialRemark = computed(() => outboundMaterial.value?.remark || '')
const outboundPaperRows = computed(() => {
const materials = outboundMaterial.value?.paperMaterials || []
if (materials.length) {
return materials.map((p: Record<string, any>) => ({
paperName: p.paperName || '',
copies: p.copies,
attachmentUrl: p.attachmentUrl || ''
}))
}
const urls = outboundMaterial.value?.paperAttachments || ''
if (!urls.trim()) return []
return urls
.split(',')
.map((u: string) => u.trim())
.filter(Boolean)
.map((attachmentUrl: string) => ({
paperName: paperAttachmentName(attachmentUrl),
copies: 1,
attachmentUrl
}))
})
const hasOutboundMaterial = computed(
() =>
outboundMaterialCells.value.length > 0 ||
outboundMaterialQcRows.value.length > 0 ||
outboundPaperRows.value.length > 0 ||
!!outboundMaterialRemark.value.trim()
)
const reviewAttachmentFiles = computed(() => {
const urls = review.value?.reviewAttachments || ''
if (!urls.trim()) return []
@@ -464,46 +259,6 @@
return !!(confirm?.id || confirm?.confirmTime || confirm?.confirmUserName)
}
function paperAttachmentName(url: string) {
return url.split('/').pop() || '附件'
}
function splitUrls(str: string): string[] {
if (!str?.trim()) return []
return str
.split(',')
.map((u) => u.trim())
.filter(Boolean)
}
function parsePaperAttachments(urlStr: string): PaperAttachmentView[] {
return splitUrls(urlStr).map((url) => ({
fileName: paperAttachmentName(url),
attachmentUrl: url,
fileUrl: url
}))
}
function isImageFile(file: PaperAttachmentView) {
const url = (file.fileUrl || file.attachmentUrl || '').toLowerCase()
const name = (file.fileName || '').toLowerCase()
return (
/\.(jpg|jpeg|png|gif|bmp|webp|svg)(\?|$)/.test(url) ||
/\.(jpg|jpeg|png|gif|bmp|webp|svg)$/.test(name) ||
(file.fileType || '').startsWith('image/')
)
}
function isVideoFile(file: PaperAttachmentView) {
const url = (file.fileUrl || file.attachmentUrl || '').toLowerCase()
const name = (file.fileName || '').toLowerCase()
return (
/\.(mp4|webm|ogg|mov|avi)(\?|$)/.test(url) ||
/\.(mp4|webm|ogg|mov|avi)$/.test(name) ||
(file.fileType || '').startsWith('video/')
)
}
function attachmentFullUrl(url: string) {
const u = String(url || '').trim()
if (!u) return ''
@@ -511,25 +266,6 @@
return minioBaseUrl ? `${minioBaseUrl}/${u.replace(/^\//, '')}` : u
}
function handlePreviewPaperAttachment(att: PaperAttachmentView) {
if (!att.attachmentUrl) return
previewUrl.value = attachmentFullUrl(att.attachmentUrl)
previewType.value = isVideoFile(att) ? 'video' : 'image'
previewVisible.value = true
}
function handleDownloadPaperAttachment(att: PaperAttachmentView) {
if (!att.attachmentUrl) return
downloadAttachmentFile(
{
fileName: att.fileName,
fileUrl: att.attachmentUrl,
fileType: att.fileType || ''
},
{ fullFileUrl: attachmentFullUrl }
)
}
function handleAttachmentPreview(file: Record<string, unknown>) {
const url = attachmentFullUrl(String(file.fileUrl || ''))
if (url) window.open(url, '_blank')
@@ -592,36 +328,6 @@
color: var(--mint-text-muted, #334155);
}
.outbound-material-view {
width: 100%;
}
.outbound-material-empty {
font-size: 13px;
color: var(--mint-text-muted, #334155);
}
.outbound-material-block {
margin-bottom: 16px;
&:last-child {
margin-bottom: 0;
}
}
.outbound-material-subtitle {
margin: 0 0 8px;
font-size: 12px;
font-weight: 600;
color: var(--mint-text-muted, #334155);
}
.outbound-material-remark {
margin: 12px 0 0;
font-size: 13px;
color: var(--mint-text-muted, #334155);
}
.attachment-row {
margin-top: 12px;
}
@@ -667,122 +373,4 @@
padding-top: 0;
border-top: none;
}
.paper-att-cards {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.paper-att-card {
width: 100px;
height: 72px;
border: 1px solid #e2e8f0;
border-radius: 6px;
background: #f8fafc;
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: center;
padding: 0;
position: relative;
overflow: hidden;
}
.paper-att-card__preview {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 6px 4px;
overflow: hidden;
&.is-clickable {
cursor: pointer;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
}
.paper-att-card--image,
.paper-att-card--video {
.paper-att-card__preview {
padding: 0;
}
}
.paper-att-card__type-icon {
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
margin-bottom: 2px;
&--doc {
color: #0284c7;
}
&--video {
width: 36px;
height: 36px;
border-radius: 8px;
background: #ede9fe;
color: #7c3aed;
font-size: 20px;
margin-bottom: 4px;
}
}
.paper-att-card__name {
width: 100%;
font-size: 11px;
color: #334155;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 1.2;
}
.paper-att-card__actions {
position: absolute;
top: 2px;
right: 2px;
display: flex;
gap: 2px;
opacity: 0;
transition: opacity 0.15s;
}
.paper-att-card:hover .paper-att-card__actions {
opacity: 1;
}
.paper-att-card__action {
width: 18px;
height: 18px;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
color: #fff;
background: rgba(0, 0, 0, 0.35);
cursor: pointer;
&:hover {
background: #047857;
}
}
.preview-container {
text-align: center;
}
</style>
@@ -0,0 +1,536 @@
<!-- 出库物料准备 — 只读展示(出库细胞 / 物料 / 纸质材料) -->
<template>
<div class="outbound-material-readonly-panel">
<p v-if="!hasContent" class="view-empty-hint">{{ emptyText }}</p>
<template v-else>
<div v-if="cells.length" class="outbound-material-block">
<div class="section-subtitle">出库细胞</div>
<div class="list-body list-wrap view-inner-table-wrap">
<el-table
:data="cells"
stripe
class="list-table inner-table"
max-height="320"
>
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
/>
<el-table-column
prop="productCode"
label="产品编码"
min-width="150"
show-overflow-tooltip
/>
<el-table-column
prop="productName"
label="产品名称"
min-width="120"
show-overflow-tooltip
/>
<el-table-column
prop="productTypeName"
label="类型"
min-width="90"
show-overflow-tooltip
/>
<el-table-column prop="specName" label="规格" min-width="90" show-overflow-tooltip />
<el-table-column
prop="storageSlotName"
label="储物格"
min-width="130"
show-overflow-tooltip
/>
<el-table-column label="状态" min-width="100" align="center" header-align="center">
<template #default="{ row }">
<el-tag
:type="outboundMaterialCellStatusTagType(row.productStatus || '', bizType) as any"
size="small"
>
{{ outboundMaterialCellStatusLabel(row.productStatus || '', bizType) }}
</el-tag>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div v-if="qcMaterials.length" class="outbound-material-block">
<div class="section-subtitle">使用的物料</div>
<div class="list-body list-wrap view-inner-table-wrap">
<el-table
:data="qcMaterials"
stripe
class="list-table inner-table"
max-height="320"
>
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
/>
<el-table-column
prop="materialName"
label="物料名称"
min-width="140"
show-overflow-tooltip
/>
<el-table-column prop="specModel" label="规格型号" min-width="110" show-overflow-tooltip />
<el-table-column label="计划用量" min-width="100" align="center" header-align="center">
<template #default="{ row }">{{ row.qty ?? '—' }}</template>
</el-table-column>
<el-table-column
prop="unit"
label="单位"
min-width="72"
align="center"
header-align="center"
/>
</el-table>
</div>
</div>
<div v-if="paperRows.length" class="outbound-material-block">
<div class="section-subtitle">其他纸质材料</div>
<div class="list-body list-wrap view-inner-table-wrap">
<el-table
:data="paperRows"
stripe
class="list-table inner-table"
max-height="320"
>
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
/>
<el-table-column prop="paperName" label="名称" min-width="140" show-overflow-tooltip />
<el-table-column label="份数" min-width="80" align="center" header-align="center">
<template #default="{ row }">{{ row.copies ?? '—' }}</template>
</el-table-column>
<el-table-column label="附件" min-width="320">
<template #default="{ row }">
<div v-if="parsePaperAttachments(row.attachmentUrl).length" class="paper-att-cards">
<div
v-for="(att, attIdx) in parsePaperAttachments(row.attachmentUrl)"
:key="attIdx"
class="paper-att-card"
:class="{
'paper-att-card--image': isImageFile(att),
'paper-att-card--video': isVideoFile(att)
}"
:title="att.fileName"
>
<div
class="paper-att-card__preview"
:class="{
'is-clickable': isImageFile(att) || isVideoFile(att)
}"
@click="
(isImageFile(att) || isVideoFile(att)) &&
handlePreviewPaperAttachment(att)
"
>
<img
v-if="isImageFile(att)"
:src="attachmentFullUrl(att.attachmentUrl)"
:alt="att.fileName || '附件'"
/>
<template v-else-if="isVideoFile(att)">
<div class="paper-att-card__type-icon paper-att-card__type-icon--video">
<el-icon><VideoPlay /></el-icon>
</div>
</template>
<template v-else>
<el-icon class="paper-att-card__type-icon paper-att-card__type-icon--doc">
<Document />
</el-icon>
<span class="paper-att-card__name">{{ att.fileName || '附件' }}</span>
</template>
</div>
<div class="paper-att-card__actions">
<el-icon
v-if="isImageFile(att) || isVideoFile(att)"
class="paper-att-card__action"
title="预览"
@click.stop="handlePreviewPaperAttachment(att)"
>
<View />
</el-icon>
<el-icon
class="paper-att-card__action"
title="下载"
@click.stop="handleDownloadPaperAttachment(att)"
>
<Download />
</el-icon>
</div>
</div>
</div>
<span v-else>—</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
<p v-if="remark" class="outbound-material-remark">备注:{{ remark }}</p>
</template>
<el-dialog
v-model="previewVisible"
title="文件预览"
width="800px"
align-center
destroy-on-close
append-to-body
style="backdrop-filter: none"
>
<div v-if="previewType === 'image'" class="preview-container">
<img
:src="previewUrl"
alt="预览"
style="max-width: 100%; max-height: 70vh; display: block; margin: 0 auto"
/>
</div>
<div v-else class="preview-container">
<video
:src="previewUrl"
controls
style="max-width: 100%; max-height: 70vh; display: block; margin: 0 auto"
/>
</div>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
import { Document, Download, View, VideoPlay } from '@element-plus/icons-vue'
import type {
OutboundReleaseCellRow,
OutboundReleaseMaterialDetail,
OutboundReleaseQcMaterialRow
} from '@/api/outbound-release-review'
import {
outboundMaterialCellStatusLabel,
outboundMaterialCellStatusTagType
} from '@/utils/status-tag-registry'
import { downloadAttachmentFile } from '@/utils/download-attachment'
defineOptions({ name: 'OutboundMaterialReadonlyPanel' })
const props = withDefaults(
defineProps<{
material?: OutboundReleaseMaterialDetail | Record<string, any> | null
bizType?: string
emptyText?: string
}>(),
{
material: null,
bizType: '',
emptyText: '暂无出库物料准备记录'
}
)
type PaperAttachmentView = {
fileName: string
attachmentUrl: string
fileUrl: string
fileType?: string
}
const previewVisible = ref(false)
const previewUrl = ref('')
const previewType = ref<'image' | 'video'>('image')
const minioBaseUrl = (import.meta.env.VITE_MINIO_BASE_URL || '').replace(/\/$/, '')
const cells = computed<OutboundReleaseCellRow[]>(() => props.material?.cells || [])
const qcMaterials = computed<OutboundReleaseQcMaterialRow[]>(
() => props.material?.qcMaterials || []
)
const remark = computed(() => String(props.material?.remark || '').trim())
const paperRows = computed(() => {
const materials = props.material?.paperMaterials || []
if (materials.length) {
return materials.map((p: Record<string, any>) => ({
paperName: p.paperName || '',
copies: p.copies,
attachmentUrl: p.attachmentUrl || ''
}))
}
const urls = props.material?.paperAttachments || ''
if (!String(urls).trim()) return []
return String(urls)
.split(',')
.map((u: string) => u.trim())
.filter(Boolean)
.map((attachmentUrl: string) => ({
paperName: paperAttachmentName(attachmentUrl),
copies: 1,
attachmentUrl
}))
})
const hasContent = computed(
() =>
cells.value.length > 0 ||
qcMaterials.value.length > 0 ||
paperRows.value.length > 0 ||
!!remark.value
)
function paperAttachmentName(url: string) {
return url.split('/').pop() || '附件'
}
function splitUrls(str: string): string[] {
if (!str?.trim()) return []
return str
.split(',')
.map((u) => u.trim())
.filter(Boolean)
}
function parsePaperAttachments(urlStr: string): PaperAttachmentView[] {
return splitUrls(urlStr).map((url) => ({
fileName: paperAttachmentName(url),
attachmentUrl: url,
fileUrl: url
}))
}
function isImageFile(file: PaperAttachmentView) {
const url = (file.fileUrl || file.attachmentUrl || '').toLowerCase()
const name = (file.fileName || '').toLowerCase()
return (
/\.(jpg|jpeg|png|gif|bmp|webp|svg)(\?|$)/.test(url) ||
/\.(jpg|jpeg|png|gif|bmp|webp|svg)$/.test(name) ||
(file.fileType || '').startsWith('image/')
)
}
function isVideoFile(file: PaperAttachmentView) {
const url = (file.fileUrl || file.attachmentUrl || '').toLowerCase()
const name = (file.fileName || '').toLowerCase()
return (
/\.(mp4|webm|ogg|mov|avi)(\?|$)/.test(url) ||
/\.(mp4|webm|ogg|mov|avi)$/.test(name) ||
(file.fileType || '').startsWith('video/')
)
}
function attachmentFullUrl(url: string) {
const u = String(url || '').trim()
if (!u) return ''
if (/^https?:\/\//i.test(u)) return u
return minioBaseUrl ? `${minioBaseUrl}/${u.replace(/^\//, '')}` : u
}
function handlePreviewPaperAttachment(att: PaperAttachmentView) {
if (!att.attachmentUrl) return
previewUrl.value = attachmentFullUrl(att.attachmentUrl)
previewType.value = isVideoFile(att) ? 'video' : 'image'
previewVisible.value = true
}
function handleDownloadPaperAttachment(att: PaperAttachmentView) {
if (!att.attachmentUrl) return
downloadAttachmentFile(
{
fileName: att.fileName,
fileUrl: att.attachmentUrl,
fileType: att.fileType || ''
},
{ fullFileUrl: attachmentFullUrl }
)
}
</script>
<style lang="scss" scoped>
.outbound-material-readonly-panel {
width: 100%;
}
.view-empty-hint {
margin: 0;
font-size: 13px;
color: var(--mint-text-muted, #334155);
}
.outbound-material-block {
margin-bottom: 16px;
&:last-child {
margin-bottom: 0;
}
}
.section-subtitle {
margin: 0 0 8px;
font-size: 13px;
font-weight: 600;
color: var(--mint-text-muted, #334155);
}
.outbound-material-remark {
margin: 12px 0 0;
font-size: 13px;
color: var(--mint-text-muted, #334155);
}
.view-inner-table-wrap.list-body.list-wrap {
margin-top: 0;
border: 1px solid var(--mint-border, #e2e8f0);
border-radius: var(--mint-radius, 10px);
overflow: hidden;
background: #fff;
:deep(.el-table) {
--el-table-header-bg-color: var(--mint-table-head, #f8fafc);
--el-table-border-color: var(--mint-border, #e2e8f0);
--el-table-row-hover-bg-color: var(--mint-row-hover, #f0fdf4);
--el-table-text-color: var(--mint-text, #0f172a);
--el-table-header-text-color: var(--mint-text-muted, #64748b);
font-size: 14px;
}
:deep(.el-table th.el-table__cell) {
font-size: 12px;
font-weight: 600;
color: var(--mint-text-muted, #64748b);
}
:deep(.el-table td.el-table__cell) {
font-size: 14px;
font-weight: 500;
color: var(--mint-text, #0f172a);
}
}
.paper-att-cards {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.paper-att-card {
width: 100px;
height: 72px;
border: 1px solid #e2e8f0;
border-radius: 6px;
background: #f8fafc;
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: center;
padding: 0;
position: relative;
overflow: hidden;
}
.paper-att-card__preview {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 6px 4px;
overflow: hidden;
&.is-clickable {
cursor: pointer;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
}
.paper-att-card--image,
.paper-att-card--video {
.paper-att-card__preview {
padding: 0;
}
}
.paper-att-card__type-icon {
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
margin-bottom: 2px;
&--doc {
color: #0284c7;
}
&--video {
width: 36px;
height: 36px;
border-radius: 8px;
background: #ede9fe;
color: #7c3aed;
font-size: 20px;
margin-bottom: 4px;
}
}
.paper-att-card__name {
width: 100%;
font-size: 11px;
color: #334155;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 1.2;
}
.paper-att-card__actions {
position: absolute;
top: 2px;
right: 2px;
display: flex;
gap: 2px;
opacity: 0;
transition: opacity 0.15s;
}
.paper-att-card:hover .paper-att-card__actions {
opacity: 1;
}
.paper-att-card__action {
width: 18px;
height: 18px;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
color: #fff;
background: rgba(0, 0, 0, 0.35);
cursor: pointer;
&:hover {
background: #047857;
}
}
.preview-container {
text-align: center;
}
</style>
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_outbound_material_readonly_panel_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L1"}, {"id": "outbound_material_readonly_panel_index_paperattachmentname", "label": "paperAttachmentName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L291"}, {"id": "outbound_material_readonly_panel_index_spliturls", "label": "splitUrls()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L295"}, {"id": "outbound_material_readonly_panel_index_parsepaperattachments", "label": "parsePaperAttachments()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L303"}, {"id": "outbound_material_readonly_panel_index_isimagefile", "label": "isImageFile()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L311"}, {"id": "outbound_material_readonly_panel_index_isvideofile", "label": "isVideoFile()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L321"}, {"id": "outbound_material_readonly_panel_index_attachmentfullurl", "label": "attachmentFullUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L331"}, {"id": "outbound_material_readonly_panel_index_handlepreviewpaperattachment", "label": "handlePreviewPaperAttachment()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L338"}, {"id": "outbound_material_readonly_panel_index_handledownloadpaperattachment", "label": "handleDownloadPaperAttachment()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L345"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_outbound_material_readonly_panel_index_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L216", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_outbound_material_readonly_panel_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L217", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_outbound_material_readonly_panel_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_status_tag_registry", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L222", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_outbound_material_readonly_panel_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_download_attachment", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L226", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_outbound_material_readonly_panel_index_vue", "target": "outbound_material_readonly_panel_index_paperattachmentname", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue", "source_location": "L291", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_outbound_material_readonly_panel_index_vue", "target": "outbound_material_readonly_panel_index_spliturls", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readoLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L1"}, {"id": "outbound_release_review_index_rowid", "label": "rowId()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L169"}, {"id": "outbound_release_review_index_handletoggleselect", "label": "handleToggleSelect()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L173"}, {"id": "outbound_release_review_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L187"}, {"id": "outbound_release_review_index_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L206"}, {"id": "outbound_release_review_index_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L211"}, {"id": "outbound_release_review_index_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L222"}, {"id": "outbound_release_review_index_openreviewdialog", "label": "openReviewDialog()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L231"}, {"id": "outbound_release_review_index_onreviewsubmitted", "label": "onReviewSubmitted()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L242"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_rowid", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L169", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_handletoggleselect", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L173", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_loaddata", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L187", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_handlesearch", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L206", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_handlereset", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L211", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_handleview", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L222", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_index_vue", "target": "outbound_release_review_index_openreviewdialog", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue", "source_location": "L231", "weight": 1.0}, {"source": "userLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "label": "outbound-release-review.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L1"}, {"id": "api_outbound_release_review_fetchoutboundreleasereviewlist", "label": "fetchOutboundReleaseReviewList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L158"}, {"id": "api_outbound_release_review_fetchoutboundreleasereviewdetail", "label": "fetchOutboundReleaseReviewDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L176"}, {"id": "api_outbound_release_review_submitoutboundreleasereview", "label": "submitOutboundReleaseReview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L182"}, {"id": "api_outbound_release_review_batchreviewoutboundrelease", "label": "batchReviewOutboundRelease()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L196"}, {"id": "api_outbound_release_review_fetchoutboundreleasematerial", "label": "fetchOutboundReleaseMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L208"}, {"id": "api_outbound_release_review_fetchreleasereviewlist", "label": "fetchReleaseReviewList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L214"}, {"id": "api_outbound_release_review_updatereleasereview", "label": "updateReleaseReview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L220"}, {"id": "api_outbound_release_review_deletereleasereview", "label": "deleteReleaseReview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L227"}, {"id": "api_outbound_release_review_saveoutboundreleasematerial", "label": "saveOutboundReleaseMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L233"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_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/outbound-release-review.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_fetchoutboundreleasereviewlist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L158", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_fetchoutboundreleasereviewdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L176", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_submitoutboundreleasereview", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L182", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_batchreviewoutboundrelease", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L196", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_fetchoutboundreleasematerial", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L208", "wLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_view_dialogs_outboundqcproducttable_vue", "label": "OutboundQcProductTable.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundQcProductTable.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_status_tag_registry_ts", "label": "status-tag-registry.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L1"}, {"id": "utils_status_tag_registry_createlabelgetter", "label": "createLabelGetter()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L29"}, {"id": "utils_status_tag_registry_createtagtypegetter", "label": "createTagTypeGetter()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L33"}, {"id": "utils_status_tag_registry_txntypelabel", "label": "txnTypeLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L401"}, {"id": "utils_status_tag_registry_txntypetagtype", "label": "txnTypeTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L412"}, {"id": "utils_status_tag_registry_txnstatuslabel", "label": "txnStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L424"}, {"id": "utils_status_tag_registry_txnstatustagtype", "label": "txnStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L434"}, {"id": "utils_status_tag_registry_applicationstatuslabel", "label": "applicationStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L445"}, {"id": "utils_status_tag_registry_applicationstatustagtype", "label": "applicationStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L449"}, {"id": "utils_status_tag_registry_checkupstatuslabel", "label": "checkupStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L462"}, {"id": "utils_status_tag_registry_checkupstatustagtype", "label": "checkupStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L470"}, {"id": "utils_status_tag_registry_feestatuslabel", "label": "feeStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L478"}, {"id": "utils_status_tag_registry_feestatustagtype", "label": "feeStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L486"}, {"id": "utils_status_tag_registry_schedulestatuslabel", "label": "scheduleStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L495"}, {"id": "utils_status_tag_registry_schedulestatustagtype", "label": "scheduleStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L504"}, {"id": "utils_status_tag_registry_infusionstatuslabel", "label": "infusionStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L515"}, {"id": "utils_status_tag_registry_infusionstatustagtype", "label": "infusionStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L524"}, {"id": "utils_status_tag_registry_infusionmethodlabel", "label": "infusionMethodLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L535"}, {"id": "utils_status_tag_registry_qcstatuslabel", "label": "qcStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L546"}, {"id": "utils_status_tag_registry_qcstatustagtype", "label": "qcStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L550"}, {"id": "utils_status_tag_registry_releasereviewconclusionlabel", "label": "releaseReviewConclusionLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L556"}, {"id": "utils_status_tag_registry_releasereviewconclusiontagtype", "label": "releaseReviewConclusionTagTypeLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_view_dialogs_outboundqcproducttable_vue", "label": "OutboundQcProductTable.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundQcProductTable.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleaseviewdialog_vue", "label": "OutboundReleaseViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseViewDialog.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "label": "qc-work-order.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L1"}, {"id": "api_qc_work_order_fetchqcworkorderlist", "label": "fetchQcWorkOrderList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L174"}, {"id": "api_qc_work_order_fetchqcworkorderdetail", "label": "fetchQcWorkOrderDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L194"}, {"id": "api_qc_work_order_fetchconfigureqcworkorder", "label": "fetchConfigureQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L200"}, {"id": "api_qc_work_order_fetchcreateqcworkorder", "label": "fetchCreateQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L217"}, {"id": "api_qc_work_order_fetchupdateqcworkorder", "label": "fetchUpdateQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L232"}, {"id": "api_qc_work_order_fetchdeleteqcworkorder", "label": "fetchDeleteQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L242"}, {"id": "api_qc_work_order_fetchoutboundqcdetail", "label": "fetchOutboundQcDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L315"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_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-work-order.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchqcworkorderlist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L174", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchqcworkorderdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L194", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchconfigureqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L200", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchcreateqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L217", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchupdateqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L232", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchdeleteqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L242", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchoutboundqcdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L315", "weight": 1.0}], "raw_calls": [{"caller_nid": "api_qc_work_order_fetchqcworkorderlist", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L188"}, {"caller_nid": "api_qc_work_order_fetchqcworkorderdetail", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L195"}, {"caller_nid": "api_qc_work_order_fetchconfigureqcworkorder", "callee": "post", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L211"}, {"caller_nid": "api_qc_work_order_fetchcreateqcworkoLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_view_dialogs_outboundbasicexperimentviewdialog_vue", "label": "OutboundBasicExperimentViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundBasicExperimentViewDialog.vue", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_view_dialogs_outboundbasicexperimentviewdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_view_dialogs_qcworkordersystemviewdialog_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundBasicExperimentViewDialog.vue", "source_location": "L25", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_view_dialogs_outboundbasicexperimentviewdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_view_dialogs_outboundqcproducttable_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundBasicExperimentViewDialog.vue", "source_location": "L26", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_view_dialogs_outboundbasicexperimentviewdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_composables_useoutboundqcviewdialog", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundBasicExperimentViewDialog.vue", "source_location": "L27", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleaseviewdialog_vue", "label": "OutboundReleaseViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseViewDialog.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_view_dialogs_outboundpilotviewdialog_vue", "label": "OutboundPilotViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundPilotViewDialog.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_infusion_schedule_management_scheduleviewdialog_vue", "label": "ScheduleViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleViewDialog.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleasereviewcardlist_vue", "label": "OutboundReleaseReviewCardList.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue", "source_location": "L1"}, {"id": "outbound_release_review_outboundreleasereviewcardlist_isselected", "label": "isSelected()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue", "source_location": "L212"}, {"id": "outbound_release_review_outboundreleasereviewcardlist_cardindex", "label": "cardIndex()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue", "source_location": "L216"}, {"id": "outbound_release_review_outboundreleasereviewcardlist_cellproducts", "label": "cellProducts()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue", "source_location": "L220"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleasereviewcardlist_vue", "target": "outbound_release_review_outboundreleasereviewcardlist_isselected", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue", "source_location": "L212", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleasereviewcardlist_vue", "target": "outbound_release_review_outboundreleasereviewcardlist_cardindex", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue", "source_location": "L216", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleasereviewcardlist_vue", "target": "outbound_release_review_outboundreleasereviewcardlist_cellproducts", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue", "source_location": "L220", "weight": 1.0}], "raw_calls": [{"caller_nid": "outbound_release_review_outboundreleasereviewcardlist_isselected", "callee": "includes", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue", "source_location": "L213"}, {"caller_nid": "outbound_release_review_outboundreleasereviewcardlist_isselected", "callee": "rowId", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue", "source_location": "L213"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_view_dialogs_productionworkorderviewdialogframe_vue", "label": "ProductionWorkOrderViewDialogFrame.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/ProductionWorkOrderViewDialogFrame.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_view_dialogs_outboundclinicalviewdialog_vue", "label": "OutboundClinicalViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundClinicalViewDialog.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleasereviewdialog_vue", "label": "OutboundReleaseReviewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L1"}, {"id": "outbound_release_review_outboundreleasereviewdialog_normalizedisplayvalue", "label": "normalizeDisplayValue()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L291"}, {"id": "outbound_release_review_outboundreleasereviewdialog_uniquejoined", "label": "uniqueJoined()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L297"}, {"id": "outbound_release_review_outboundreleasereviewdialog_resolvereviewcelltype", "label": "resolveReviewCellType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L302"}, {"id": "outbound_release_review_outboundreleasereviewdialog_resolvereviewspectext", "label": "resolveReviewSpecText()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L316"}, {"id": "outbound_release_review_outboundreleasereviewdialog_builddetailfromlistrow", "label": "buildDetailFromListRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L330"}, {"id": "outbound_release_review_outboundreleasereviewdialog_resolvereviewquantity", "label": "resolveReviewQuantity()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L353"}, {"id": "outbound_release_review_outboundreleasereviewdialog_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L410"}, {"id": "outbound_release_review_outboundreleasereviewdialog_isimagefile", "label": "isImageFile()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L418"}, {"id": "outbound_release_review_outboundreleasereviewdialog_isvideofile", "label": "isVideoFile()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L428"}, {"id": "outbound_release_review_outboundreleasereviewdialog_removeattachment", "label": "removeAttachment()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L438"}, {"id": "outbound_release_review_outboundreleasereviewdialog_handlepreviewattachment", "label": "handlePreviewAttachment()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L442"}, {"id": "outbound_release_review_outboundreleasereviewdialog_handledownloadattachment", "label": "handleDownloadAttachment()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L449"}, {"id": "outbound_release_review_outboundreleasereviewdialog_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L512"}, {"id": "outbound_release_review_outboundreleasereviewdialog_handlesubmit", "label": "handleSubmit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L521"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleasereviewdialog_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue", "source_location": "L205", "weighLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_infusion_schedule_outbound_chain_view_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_infusion_schedule_outbound_chain_view_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L1"}, {"id": "infusion_schedule_outbound_chain_view_index_dash", "label": "dash()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L253"}, {"id": "infusion_schedule_outbound_chain_view_index_hasinfusionconfirm", "label": "hasInfusionConfirm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L258"}, {"id": "infusion_schedule_outbound_chain_view_index_attachmentfullurl", "label": "attachmentFullUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L262"}, {"id": "infusion_schedule_outbound_chain_view_index_handleattachmentpreview", "label": "handleAttachmentPreview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L269"}, {"id": "infusion_schedule_outbound_chain_view_index_handleattachmentdownload", "label": "handleAttachmentDownload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L274"}, {"id": "infusion_schedule_outbound_chain_view_index_loaddetail", "label": "loadDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L278"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_infusion_schedule_outbound_chain_view_index_vue", "target": "infusion_schedule_outbound_chain_view_index_dash", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L253", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_infusion_schedule_outbound_chain_view_index_vue", "target": "infusion_schedule_outbound_chain_view_index_hasinfusionconfirm", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L258", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_infusion_schedule_outbound_chain_view_index_vue", "target": "infusion_schedule_outbound_chain_view_index_attachmentfullurl", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L262", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_infusion_schedule_outbound_chain_view_index_vue", "target": "infusion_schedule_outbound_chain_view_index_handleattachmentpreview", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L269", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_infusion_schedule_outbound_chain_view_index_vue", "target": "infusion_schedule_outbound_chain_view_index_handleattachmentdownload", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L274", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_infusion_schedule_outbound_chain_view_index_vue", "target": "infusion_schedule_outbound_chain_view_index_loaddetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L278", "weight": 1.0}, {"source": "infusion_schedule_outbound_chain_view_index_handleattachmentpreview", "target": "infusion_schedule_outbound_chain_view_index_attachmentfullurl", "relation": "calls", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L270", "weight"Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_status_tag_registry_ts", "label": "status-tag-registry.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L1"}, {"id": "utils_status_tag_registry_createlabelgetter", "label": "createLabelGetter()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L29"}, {"id": "utils_status_tag_registry_createtagtypegetter", "label": "createTagTypeGetter()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L33"}, {"id": "utils_status_tag_registry_txntypelabel", "label": "txnTypeLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L401"}, {"id": "utils_status_tag_registry_txntypetagtype", "label": "txnTypeTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L412"}, {"id": "utils_status_tag_registry_txnstatuslabel", "label": "txnStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L424"}, {"id": "utils_status_tag_registry_txnstatustagtype", "label": "txnStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L434"}, {"id": "utils_status_tag_registry_applicationstatuslabel", "label": "applicationStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L445"}, {"id": "utils_status_tag_registry_applicationstatustagtype", "label": "applicationStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L449"}, {"id": "utils_status_tag_registry_checkupstatuslabel", "label": "checkupStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L462"}, {"id": "utils_status_tag_registry_checkupstatustagtype", "label": "checkupStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L470"}, {"id": "utils_status_tag_registry_feestatuslabel", "label": "feeStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L478"}, {"id": "utils_status_tag_registry_feestatustagtype", "label": "feeStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L486"}, {"id": "utils_status_tag_registry_schedulestatuslabel", "label": "scheduleStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L495"}, {"id": "utils_status_tag_registry_schedulestatustagtype", "label": "scheduleStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L504"}, {"id": "utils_status_tag_registry_infusionstatuslabel", "label": "infusionStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L515"}, {"id": "utils_status_tag_registry_infusionstatustagtype", "label": "infusionStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L524"}, {"id": "utils_status_tag_registry_infusionmethodlabel", "label": "infusionMethodLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L535"}, {"id": "utils_status_tag_registry_qcstatuslabel", "label": "qcStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L546"}, {"id": "utils_status_tag_registry_qcstatustagtype", "label": "qcStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L550"}, {"id": "utils_status_tag_registry_releasereviewconclusionlabel", "label": "releaseReviewConclusionLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts", "source_location": "L556"}, {"id": "utils_status_tag_registry_releasereviewconclusiontagtype", "label": "releaseReviewConclusionTagTypeLine truncated
+57 -2
View File
@@ -581,9 +581,10 @@ export function bizTypeTagType(type: string): string {
}
// ========== 中试服务 - 产品状态 ==========
export function productStatusLabel(status: string): string {
export function productStatusLabel(status: string, bizType?: string): string {
const isBasicExperiment = bizType === 'basic_experiment'
const map: Record<string, string> = {
dtz: '待输注',
dtz: isBasicExperiment ? '待交付' : '待输注',
yrqr: '已用户确认',
yqx: '已取消',
ywc: '已完成'
@@ -639,3 +640,57 @@ export function cellProductStatusTagType(status: string): string {
}
return map[status] || 'info'
}
/** 细胞产品库状态码(出库物料「出库细胞」台账快照) */
const CELL_PRODUCT_STATUS_CODES = new Set([
'frozen',
'in_production',
'sold',
'used',
'voided',
'thawed'
])
/** 输注/交付计划产品状态码 */
const SCHEDULE_PRODUCT_STATUS_CODES = new Set(['dtz', 'yrqr', 'yqx', 'ywc'])
const LEGACY_SCHEDULE_PRODUCT_STATUS: Record<string, string> = {
待输注: 'dtz',
已用户确认: 'yrqr',
已取消: 'yqx',
已完成: 'ywc'
}
function normalizeScheduleProductStatusCode(status: string): string {
const code = (status || '').trim()
return LEGACY_SCHEDULE_PRODUCT_STATUS[code] || code
}
/**
* 出库物料「出库细胞」状态展示:优先细胞产品库状态,兼容计划产品状态码与历史中文值。
*/
export function outboundMaterialCellStatusLabel(status: string, bizType?: string): string {
const code = (status || '').trim()
if (!code) return '—'
if (CELL_PRODUCT_STATUS_CODES.has(code)) {
return cellProductStatusLabel(code)
}
const normalized = normalizeScheduleProductStatusCode(code)
if (SCHEDULE_PRODUCT_STATUS_CODES.has(normalized)) {
return productStatusLabel(normalized, bizType)
}
return cellProductStatusLabel(code)
}
export function outboundMaterialCellStatusTagType(status: string, bizType?: string): TagType {
const code = (status || '').trim()
if (!code) return 'info'
if (CELL_PRODUCT_STATUS_CODES.has(code)) {
return cellProductStatusTagType(code) as TagType
}
const normalized = normalizeScheduleProductStatusCode(code)
if (SCHEDULE_PRODUCT_STATUS_CODES.has(normalized)) {
return productStatusTagType(normalized) as TagType
}
return cellProductStatusTagType(code) as TagType
}
@@ -59,121 +59,10 @@
</template>
<template #outbound-material>
<div class="view-section-slot outbound-material-view">
<div v-if="!hasOutboundMaterial" class="outbound-material-empty">暂无出库物料准备记录</div>
<template v-else>
<div v-if="outboundMaterialCells.length" class="outbound-material-block">
<h4 class="outbound-material-subtitle">出库细胞</h4>
<el-table :data="outboundMaterialCells" class="list-table inner-table" stripe size="small">
<el-table-column type="index" label="序号" min-width="56" align="center" />
<el-table-column prop="productCode" label="产品编码" min-width="150" show-overflow-tooltip />
<el-table-column prop="productName" label="产品名称" min-width="120" show-overflow-tooltip />
<el-table-column prop="productTypeName" label="类型" min-width="90" />
<el-table-column prop="specName" label="规格" min-width="90" />
<el-table-column prop="storageSlotName" label="储物格" min-width="130" show-overflow-tooltip />
<el-table-column label="状态" min-width="90" align="center">
<template #default="{ row }">
<el-tag
v-if="row.productStatus"
:type="cellProductStatusTagType(row.productStatus) as any"
size="small"
>
{{ cellProductStatusLabel(row.productStatus) }}
</el-tag>
<span v-else>—</span>
</template>
</el-table-column>
</el-table>
</div>
<div v-if="outboundMaterialQcRows.length" class="outbound-material-block">
<h4 class="outbound-material-subtitle">使用的物料</h4>
<el-table :data="outboundMaterialQcRows" class="list-table inner-table" stripe size="small">
<el-table-column type="index" label="序号" min-width="56" align="center" />
<el-table-column prop="materialName" label="物料名称" min-width="140" show-overflow-tooltip />
<el-table-column prop="specModel" label="规格型号" min-width="110" />
<el-table-column label="计划用量" min-width="100" align="center">
<template #default="{ row }">{{ row.qty ?? '—' }}</template>
</el-table-column>
<el-table-column prop="unit" label="单位" min-width="72" align="center" />
</el-table>
</div>
<div v-if="outboundPaperRows.length" class="outbound-material-block">
<h4 class="outbound-material-subtitle">其他纸质材料</h4>
<el-table :data="outboundPaperRows" class="list-table inner-table" stripe size="small">
<el-table-column type="index" label="序号" min-width="56" align="center" />
<el-table-column prop="paperName" label="名称" min-width="140" show-overflow-tooltip />
<el-table-column label="份数" min-width="80" align="center">
<template #default="{ row }">{{ row.copies ?? '—' }}</template>
</el-table-column>
<el-table-column label="附件" min-width="320">
<template #default="{ row }">
<div v-if="parsePaperAttachments(row.attachmentUrl).length" class="paper-att-cards">
<div
v-for="(att, attIdx) in parsePaperAttachments(row.attachmentUrl)"
:key="attIdx"
class="paper-att-card"
:class="{
'paper-att-card--image': isImageFile(att),
'paper-att-card--video': isVideoFile(att)
}"
:title="att.fileName"
>
<div
class="paper-att-card__preview"
:class="{
'is-clickable': isImageFile(att) || isVideoFile(att)
}"
@click="
(isImageFile(att) || isVideoFile(att)) &&
handlePreviewPaperAttachment(att)
"
>
<img
v-if="isImageFile(att)"
:src="attachmentFullUrl(att.attachmentUrl)"
:alt="att.fileName || '附件'"
/>
<template v-else-if="isVideoFile(att)">
<div class="paper-att-card__type-icon paper-att-card__type-icon--video">
<el-icon><VideoPlay /></el-icon>
</div>
</template>
<template v-else>
<el-icon class="paper-att-card__type-icon paper-att-card__type-icon--doc">
<Document />
</el-icon>
<span class="paper-att-card__name">{{ att.fileName || '附件' }}</span>
</template>
</div>
<div class="paper-att-card__actions">
<el-icon
v-if="isImageFile(att) || isVideoFile(att)"
class="paper-att-card__action"
title="预览"
@click.stop="handlePreviewPaperAttachment(att)"
>
<View />
</el-icon>
<el-icon
class="paper-att-card__action"
title="下载"
@click.stop="handleDownloadPaperAttachment(att)"
>
<Download />
</el-icon>
</div>
</div>
</div>
<span v-else>—</span>
</template>
</el-table-column>
</el-table>
</div>
<p v-if="outboundMaterialRemark" class="outbound-material-remark">
备注:{{ outboundMaterialRemark }}
</p>
</template>
</div>
<OutboundMaterialReadonlyPanel
:material="detail?.outboundMaterial"
:biz-type="scheduleBizType"
/>
</template>
<template #payment-info>
@@ -208,40 +97,16 @@
</div>
</template>
</SystemViewDialog>
<el-dialog
v-model="previewVisible"
title="文件预览"
width="800px"
align-center
destroy-on-close
append-to-body
style="backdrop-filter: none"
>
<div v-if="previewType === 'image'" class="preview-container">
<img
:src="previewUrl"
alt="预览"
style="max-width: 100%; max-height: 70vh; display: block; margin: 0 auto"
/>
</div>
<div v-else class="preview-container">
<video
:src="previewUrl"
controls
style="max-width: 100%; max-height: 70vh; display: block; margin: 0 auto"
/>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { Document, Download, View, VideoPlay } from '@element-plus/icons-vue'
import { Document } from '@element-plus/icons-vue'
import SystemViewDialog, {
type ViewSection,
type TagType
} from '@/components/business/system-view-dialog/index.vue'
import OutboundMaterialReadonlyPanel from '@/components/business/outbound-material-readonly-panel/index.vue'
import SampleProductionInfoCards from '@/components/business/sample-production-info-cards/index.vue'
import SampleQcInfoGroupedPanel from '@/components/business/sample-qc-info-grouped-panel/index.vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
@@ -261,14 +126,13 @@
qcStatusLabel,
qcStatusTagType,
infusionMethodLabel,
cellProductStatusLabel,
cellProductStatusTagType,
sexLabel
} from '@/utils/status-tag-registry'
import { formatMoneyDisplay } from '@/utils/money-format'
import { maskIdCard } from '@/utils/mask-sensitive'
import { downloadAttachmentFile } from '@/utils/download-attachment'
import { getPilotBizConfig } from '@/config/pilot-biz-type'
import { resolveOutboundViewVariant } from '@/utils/outbound-qc-pilot-view-sections'
defineOptions({ name: 'ScheduleViewDialog' })
@@ -285,16 +149,6 @@
const loading = ref(false)
const detail = ref<Record<string, any> | null>(null)
const previewVisible = ref(false)
const previewUrl = ref('')
const previewType = ref<'image' | 'video'>('image')
type PaperAttachmentView = {
fileName: string
attachmentUrl: string
fileUrl: string
fileType?: string
}
const minioBaseUrl = (import.meta.env.VITE_MINIO_BASE_URL || '').replace(/\/$/, '')
@@ -329,37 +183,8 @@
detail.value?.bizType === 'basic_experiment'
)
const outboundMaterial = computed(() => detail.value?.outboundMaterial || null)
const outboundMaterialCells = computed(() => outboundMaterial.value?.cells || [])
const outboundMaterialQcRows = computed(() => outboundMaterial.value?.qcMaterials || [])
const outboundMaterialRemark = computed(() => outboundMaterial.value?.remark || '')
const outboundPaperRows = computed(() => {
const materials = outboundMaterial.value?.paperMaterials || []
if (materials.length) {
return materials.map((p: Record<string, any>) => ({
paperName: p.paperName || '',
copies: p.copies,
attachmentUrl: p.attachmentUrl || ''
}))
}
const urls = outboundMaterial.value?.paperAttachments || ''
if (!urls.trim()) return []
return urls
.split(',')
.map((u: string) => u.trim())
.filter(Boolean)
.map((attachmentUrl: string) => ({
paperName: paperAttachmentName(attachmentUrl),
copies: 1,
attachmentUrl
}))
})
const hasOutboundMaterial = computed(
() =>
outboundMaterialCells.value.length > 0 ||
outboundMaterialQcRows.value.length > 0 ||
outboundPaperRows.value.length > 0 ||
!!outboundMaterialRemark.value.trim()
const scheduleBizType = computed(() =>
resolveOutboundViewVariant(detail.value?.application?.bizType || detail.value?.bizType)
)
const reviewAttachmentFiles = computed(() => {
@@ -678,65 +503,6 @@
]
})
function paperAttachmentName(url: string) {
return url.split('/').pop() || '附件'
}
function splitUrls(str: string): string[] {
if (!str?.trim()) return []
return str
.split(',')
.map((u) => u.trim())
.filter(Boolean)
}
function parsePaperAttachments(urlStr: string): PaperAttachmentView[] {
return splitUrls(urlStr).map((url) => ({
fileName: paperAttachmentName(url),
attachmentUrl: url,
fileUrl: url
}))
}
function isImageFile(file: PaperAttachmentView) {
const url = (file.fileUrl || file.attachmentUrl || '').toLowerCase()
const name = (file.fileName || '').toLowerCase()
return (
/\.(jpg|jpeg|png|gif|bmp|webp|svg)(\?|$)/.test(url) ||
/\.(jpg|jpeg|png|gif|bmp|webp|svg)$/.test(name) ||
(file.fileType || '').startsWith('image/')
)
}
function isVideoFile(file: PaperAttachmentView) {
const url = (file.fileUrl || file.attachmentUrl || '').toLowerCase()
const name = (file.fileName || '').toLowerCase()
return (
/\.(mp4|webm|ogg|mov|avi)(\?|$)/.test(url) ||
/\.(mp4|webm|ogg|mov|avi)$/.test(name) ||
(file.fileType || '').startsWith('video/')
)
}
function handlePreviewPaperAttachment(att: PaperAttachmentView) {
if (!att.attachmentUrl) return
previewUrl.value = attachmentFullUrl(att.attachmentUrl)
previewType.value = isVideoFile(att) ? 'video' : 'image'
previewVisible.value = true
}
function handleDownloadPaperAttachment(att: PaperAttachmentView) {
if (!att.attachmentUrl) return
downloadAttachmentFile(
{
fileName: att.fileName,
fileUrl: att.attachmentUrl,
fileType: att.fileType || ''
},
{ fullFileUrl: attachmentFullUrl }
)
}
function attachmentFullUrl(url: string) {
const u = String(url || '').trim()
if (!u) return ''
@@ -832,152 +598,4 @@
padding-top: 0;
border-top: none;
}
.outbound-material-view {
width: 100%;
}
.outbound-material-empty {
font-size: 13px;
color: var(--mint-text-muted, #334155);
}
.outbound-material-block {
margin-bottom: 16px;
&:last-child {
margin-bottom: 0;
}
}
.outbound-material-subtitle {
margin: 0 0 8px;
font-size: 13px;
font-weight: 600;
color: var(--mint-text-muted, #334155);
}
.outbound-material-remark {
margin: 12px 0 0;
font-size: 13px;
color: var(--mint-text-muted, #334155);
}
.paper-att-cards {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.paper-att-card {
width: 100px;
height: 72px;
border: 1px solid #e2e8f0;
border-radius: 6px;
background: #f8fafc;
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: center;
padding: 0;
position: relative;
overflow: hidden;
}
.paper-att-card__preview {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 6px 4px;
overflow: hidden;
&.is-clickable {
cursor: pointer;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
}
.paper-att-card--image,
.paper-att-card--video {
.paper-att-card__preview {
padding: 0;
}
}
.paper-att-card__type-icon {
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
margin-bottom: 2px;
&--doc {
color: #0284c7;
}
&--video {
width: 36px;
height: 36px;
border-radius: 8px;
background: #ede9fe;
color: #7c3aed;
font-size: 20px;
margin-bottom: 4px;
}
}
.paper-att-card__name {
width: 100%;
font-size: 11px;
color: #334155;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 1.2;
}
.paper-att-card__actions {
position: absolute;
top: 2px;
right: 2px;
display: flex;
gap: 2px;
opacity: 0;
transition: opacity 0.15s;
}
.paper-att-card:hover .paper-att-card__actions {
opacity: 1;
}
.paper-att-card__action {
width: 18px;
height: 18px;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
color: #fff;
background: rgba(0, 0, 0, 0.35);
cursor: pointer;
&:hover {
background: #047857;
}
}
.preview-container {
text-align: center;
}
</style>
@@ -42,10 +42,22 @@
<el-tag v-else type="info" size="small">待审核</el-tag>
</div>
<dl class="outbound-release-review-card__meta">
<div class="outbound-release-review-card__meta-item">
<dt>患者姓名</dt>
<dd>{{ row.patientName || '—' }}</dd>
</div>
<template v-if="showPatient">
<div class="outbound-release-review-card__meta-item">
<dt>患者姓名</dt>
<dd>{{ row.patientName || '—' }}</dd>
</div>
</template>
<template v-else>
<div class="outbound-release-review-card__meta-item">
<dt>课题名称</dt>
<dd>{{ row.projectTitle || '—' }}</dd>
</div>
<div class="outbound-release-review-card__meta-item">
<dt>客户名称</dt>
<dd>{{ row.customerName || '—' }}</dd>
</div>
</template>
<div class="outbound-release-review-card__meta-item">
<dt>{{ pickupTimeLabel }}</dt>
<dd>{{ row.infusionTime || '—' }}</dd>
@@ -97,7 +109,7 @@
:type="productStatusTagType(product.productStatus) as any"
size="small"
>
{{ productStatusLabel(product.productStatus) }}
{{ productStatusLabel(product.productStatus, bizType) }}
</el-tag>
<span v-else>—</span>
</dd>
@@ -175,8 +187,14 @@
total: number
selectedIds: string[]
pickupTimeLabel: string
/** 中试/临床展示患者;基础实验展示课题与客户 */
showPatient?: boolean
bizType?: string
}>()
const showPatient = computed(() => props.showPatient !== false)
const bizType = computed(() => props.bizType || '')
const emit = defineEmits<{
view: [row: OutboundReleaseReview]
material: [row: OutboundReleaseReview]
@@ -47,7 +47,10 @@
</el-tag>
</div>
</div>
<dl class="review-context-grid">
<dl
class="review-context-grid"
:class="{ 'review-context-grid--cols3': reviewBizType === 'basic_experiment' }"
>
<div
v-for="item in reviewContextItems"
:key="item.label"
@@ -216,6 +219,7 @@
fetchOutboundReleaseReviewDetail,
submitOutboundReleaseReview,
batchReviewOutboundRelease,
type OutboundReleaseReview,
type OutboundReleaseReviewDetail
} from '@/api/outbound-release-review'
import { getPilotBizConfig, resolvePilotBizType } from '@/config/pilot-biz-type'
@@ -241,6 +245,8 @@
const props = defineProps<{
modelValue: boolean
scheduleIds: string[]
/** 列表行数据,单条审核时用于弹窗打开瞬间展示上下文 */
contextRow?: OutboundReleaseReview | null
}>()
const emit = defineEmits<{
@@ -282,23 +288,76 @@
qcStatusTagType(singleDetail.value?.infusionSchedule?.qcStatus || '')
)
function normalizeDisplayValue(v?: string | null) {
const s = String(v ?? '').trim()
if (!s || s === '-' || s === '—') return ''
return s
}
function uniqueJoined(values: Array<string | undefined | null>) {
const items = [...new Set(values.map((v) => String(v || '').trim()).filter(Boolean))]
const items = [...new Set(values.map((v) => normalizeDisplayValue(v)).filter(Boolean))]
return items.length ? items.join('、') : '—'
}
function resolveReviewCellType(detail: OutboundReleaseReviewDetail | null) {
if (!detail) return '—'
const planType = detail.infusionPlan?.cellType?.trim()
const fromProducts = uniqueJoined((detail.products || []).map((p) => p.cellTypeName))
if (fromProducts !== '—') return fromProducts
const scheduleType = normalizeDisplayValue(detail.infusionSchedule?.cellType)
if (scheduleType) return scheduleType
const planType = normalizeDisplayValue(detail.infusionPlan?.cellType)
if (planType) return planType
return uniqueJoined((detail.products || []).map((p) => p.cellTypeName))
return '—'
}
function resolveReviewSpecText(detail: OutboundReleaseReviewDetail | null) {
if (!detail) return '—'
const planSpec = detail.infusionPlan?.specText?.trim()
const fromProducts = uniqueJoined((detail.products || []).map((p) => p.specText))
if (fromProducts !== '—') return fromProducts
const scheduleSpec = normalizeDisplayValue(detail.infusionSchedule?.specText)
if (scheduleSpec) return scheduleSpec
const planSpec = normalizeDisplayValue(detail.infusionPlan?.specText)
if (planSpec) return planSpec
return uniqueJoined((detail.products || []).map((p) => p.specText))
return '—'
}
function buildDetailFromListRow(row: OutboundReleaseReview): OutboundReleaseReviewDetail {
return {
application: {
applicationNo: row.applicationNo,
bizType: row.bizType,
bizTypeLabel: row.bizTypeLabel,
projectTitle: row.projectTitle,
customerName: row.customerName
},
patient: {
patientName: row.patientName
},
infusionSchedule: {
scheduleStatus: row.scheduleStatus,
qcStatus: row.qcStatus,
infusionTime: row.infusionTime,
cellType: row.cellType,
specText: row.specText
},
products: row.products
}
}
function resolveReviewQuantity(detail: OutboundReleaseReviewDetail | null) {
if (!detail) return '—'
const products = detail.products || []
if (!products.length) return '—'
if (products.length === 1 && products[0].quantity != null) {
return String(products[0].quantity)
}
return uniqueJoined(products.map((p) => (p.quantity != null ? String(p.quantity) : '')))
}
const reviewContextItems = computed(() => {
@@ -306,23 +365,28 @@
if (!d) return [] as Array<{ label: string; value: string; span?: boolean }>
const pickupLabel = reviewBizConfig.value.pickupTimeLabel
const isBasicExperiment = reviewBizType.value === 'basic_experiment'
if (isBasicExperiment) {
return [
{ label: '课题名称', value: d.application?.projectTitle || '—' },
{ label: '客户名称', value: d.application?.customerName || '—' },
{ label: '细胞类型', value: resolveReviewCellType(d) },
{ label: '规格', value: resolveReviewSpecText(d) },
{ label: '细胞数量', value: resolveReviewQuantity(d) },
{ label: pickupLabel, value: d.infusionSchedule?.infusionTime || '—' }
]
}
const items: Array<{ label: string; value: string; span?: boolean }> = [
{ label: '患者姓名', value: d.patient?.patientName || '—' },
{ label: '细胞类型', value: resolveReviewCellType(d) },
{ label: '规格', value: resolveReviewSpecText(d) },
{ label: pickupLabel, value: d.infusionSchedule?.infusionTime || '—' }
]
if (!isBasicExperiment) {
items.push(
{ label: '输注地点', value: d.infusionSchedule?.infusionLocation || '—' },
{ label: '渠道名称', value: d.application?.channelName || '—' }
)
} else {
items.push(
{ label: '课题名称', value: d.application?.projectTitle || '—', span: true },
{ label: '客户名称', value: d.application?.customerName || '—' }
)
}
items.push(
{ label: '输注地点', value: d.infusionSchedule?.infusionLocation || '—' },
{ label: '渠道名称', value: d.application?.channelName || '—' }
)
return items
})
@@ -423,18 +487,23 @@
}
watch(
() => [props.modelValue, props.scheduleIds] as const,
async ([vis, ids]) => {
() => [props.modelValue, props.scheduleIds, props.contextRow] as const,
async ([vis, ids, contextRow]) => {
if (!vis || !ids.length) {
singleDetail.value = null
return
}
if (ids.length === 1) {
if (contextRow) {
singleDetail.value = buildDetailFromListRow(contextRow)
}
try {
singleDetail.value = await fetchOutboundReleaseReviewDetail(ids[0])
} catch {
singleDetail.value = null
singleDetail.value = contextRow ? buildDetailFromListRow(contextRow) : null
}
} else {
singleDetail.value = null
}
},
{ immediate: true }
@@ -560,6 +629,10 @@
gap: 12px 20px;
margin: 0;
padding: 14px 16px 16px;
&--cols3 {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
.review-context-kv {
@@ -588,8 +661,15 @@
}
}
@media (max-width: 900px) {
.review-context-grid--cols3 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 640px) {
.review-context-grid {
.review-context-grid,
.review-context-grid--cols3 {
grid-template-columns: 1fr;
}
}
@@ -19,7 +19,7 @@
</template>
<template #product-table>
<OutboundQcProductTable :products="viewProducts" />
<OutboundQcProductTable :products="viewProducts" :biz-type="effectiveBizType" />
</template>
<template #production-info>
@@ -48,196 +48,19 @@
</template>
<template #outbound-material>
<div class="outbound-material-view">
<p v-if="!hasOutboundMaterial" class="view-empty-hint">暂无出库物料准备记录</p>
<template v-else>
<div v-if="outboundMaterialCells.length" class="outbound-material-block">
<div class="section-subtitle">出库细胞</div>
<div class="view-subtable-wrap">
<el-table
:data="outboundMaterialCells"
stripe
class="list-table view-subtable"
max-height="320"
>
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
/>
<el-table-column
prop="productCode"
label="产品编码"
min-width="150"
show-overflow-tooltip
/>
<el-table-column
prop="productName"
label="产品名称"
min-width="120"
show-overflow-tooltip
/>
<el-table-column prop="productTypeName" label="类型" min-width="90" />
<el-table-column prop="specName" label="规格" min-width="90" />
<el-table-column
prop="storageSlotName"
label="储物格"
min-width="130"
show-overflow-tooltip
/>
<el-table-column label="状态" min-width="90" align="center" header-align="center">
<template #default="{ row }">
<el-tag
v-if="row.productStatus"
:type="cellProductStatusTagType(row.productStatus) as any"
size="small"
>
{{ cellProductStatusLabel(row.productStatus) }}
</el-tag>
<span v-else>—</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div v-if="outboundMaterialQcRows.length" class="outbound-material-block">
<div class="section-subtitle">使用的物料</div>
<div class="view-subtable-wrap">
<el-table
:data="outboundMaterialQcRows"
stripe
class="list-table view-subtable"
max-height="320"
>
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
/>
<el-table-column
prop="materialName"
label="物料名称"
min-width="140"
show-overflow-tooltip
/>
<el-table-column prop="specModel" label="规格型号" min-width="110" />
<el-table-column label="计划用量" min-width="100" align="center" header-align="center">
<template #default="{ row }">{{ row.qty ?? '—' }}</template>
</el-table-column>
<el-table-column
prop="unit"
label="单位"
min-width="72"
align="center"
header-align="center"
/>
</el-table>
</div>
</div>
<div v-if="outboundPaperRows.length" class="outbound-material-block">
<div class="section-subtitle">其他纸质材料</div>
<div class="view-subtable-wrap">
<el-table
:data="outboundPaperRows"
stripe
class="list-table view-subtable"
max-height="320"
>
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
/>
<el-table-column
prop="paperName"
label="名称"
min-width="140"
show-overflow-tooltip
/>
<el-table-column label="份数" min-width="80" align="center" header-align="center">
<template #default="{ row }">{{ row.copies ?? '—' }}</template>
</el-table-column>
<el-table-column label="附件" min-width="320">
<template #default="{ row }">
<div v-if="parsePaperAttachments(row.attachmentUrl).length" class="paper-att-cards">
<div
v-for="(att, attIdx) in parsePaperAttachments(row.attachmentUrl)"
:key="attIdx"
class="paper-att-card"
>
<el-icon class="paper-att-card__icon"><Document /></el-icon>
<span class="paper-att-card__name" :title="att.fileName">{{
att.fileName || '附件'
}}</span>
<div class="paper-att-card__actions">
<el-icon
v-if="isImageFile(att)"
class="paper-att-card__action"
title="预览"
@click="handlePreviewPaperAttachment(att)"
>
<View />
</el-icon>
<el-icon
class="paper-att-card__action"
title="下载"
@click="handleDownloadPaperAttachment(att)"
>
<Download />
</el-icon>
</div>
</div>
</div>
<span v-else>—</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
<p v-if="outboundMaterialRemark" class="outbound-material-remark">
备注:{{ outboundMaterialRemark }}
</p>
</template>
</div>
<OutboundMaterialReadonlyPanel
:material="detail?.outboundMaterial"
:biz-type="effectiveBizType"
/>
</template>
</SystemViewDialog>
<el-dialog
v-model="previewVisible"
title="文件预览"
width="800px"
align-center
destroy-on-close
append-to-body
style="backdrop-filter: none"
>
<div v-if="previewType === 'image'" class="preview-container">
<img
:src="previewUrl"
alt="预览"
style="max-width: 100%; max-height: 70vh; display: block; margin: 0 auto"
/>
</div>
<div v-else class="preview-container">
<video
:src="previewUrl"
controls
style="max-width: 100%; max-height: 70vh; display: block; margin: 0 auto"
/>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import { CircleCheck, Document, Download, View } from '@element-plus/icons-vue'
import { CircleCheck } from '@element-plus/icons-vue'
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
import type { ViewSection } from '@/components/business/system-view-dialog/index.vue'
import OutboundMaterialReadonlyPanel from '@/components/business/outbound-material-readonly-panel/index.vue'
import SampleQcInfoGroupedPanel from '@/components/business/sample-qc-info-grouped-panel/index.vue'
import SampleProductionInfoCards from '@/components/business/sample-production-info-cards/index.vue'
import OutboundQcDiagnosisAttachments from '@/views/quality-inspection/qc-work-order/view-dialogs/OutboundQcDiagnosisAttachments.vue'
@@ -249,9 +72,7 @@
} from '@/api/outbound-release-review'
import {
storageReleaseConclusionLabel,
storageReleaseConclusionTagType,
cellProductStatusLabel,
cellProductStatusTagType
storageReleaseConclusionTagType
} from '@/utils/status-tag-registry'
import { downloadAttachmentFile } from '@/utils/download-attachment'
import {
@@ -278,16 +99,9 @@
const loading = ref(false)
const detail = ref<OutboundReleaseReviewDetail | null>(null)
const previewVisible = ref(false)
const previewUrl = ref('')
const previewType = ref<'image' | 'video'>('image')
type PaperAttachmentView = {
fileName: string
attachmentUrl: string
fileUrl: string
fileType?: string
}
const effectiveBizType = computed(() =>
resolveOutboundViewVariant(detail.value?.application?.bizType || props.bizType)
)
const minioBaseUrl = (import.meta.env.VITE_MINIO_BASE_URL || '').replace(/\/$/, '')
@@ -349,98 +163,6 @@
}))
})
const outboundMaterial = computed(() => detail.value?.outboundMaterial || null)
const outboundMaterialCells = computed(() => outboundMaterial.value?.cells || [])
const outboundMaterialQcRows = computed(() => outboundMaterial.value?.qcMaterials || [])
const outboundMaterialRemark = computed(() => outboundMaterial.value?.remark || '')
const outboundPaperRows = computed(() => {
const materials = outboundMaterial.value?.paperMaterials || []
if (materials.length) {
return materials.map((p) => ({
paperName: p.paperName || '',
copies: p.copies,
attachmentUrl: p.attachmentUrl || ''
}))
}
const urls = outboundMaterial.value?.paperAttachments || ''
if (!urls.trim()) return []
return urls
.split(',')
.map((u) => u.trim())
.filter(Boolean)
.map((attachmentUrl) => ({
paperName: paperAttachmentName(attachmentUrl),
copies: 1,
attachmentUrl
}))
})
const hasOutboundMaterial = computed(
() =>
outboundMaterialCells.value.length > 0 ||
outboundMaterialQcRows.value.length > 0 ||
outboundPaperRows.value.length > 0 ||
!!outboundMaterialRemark.value.trim()
)
function paperAttachmentName(url: string) {
return url.split('/').pop() || '附件'
}
function splitUrls(str: string): string[] {
if (!str?.trim()) return []
return str
.split(',')
.map((u) => u.trim())
.filter(Boolean)
}
function parsePaperAttachments(urlStr: string): PaperAttachmentView[] {
return splitUrls(urlStr).map((url) => ({
fileName: paperAttachmentName(url),
attachmentUrl: url,
fileUrl: url
}))
}
function isImageFile(file: PaperAttachmentView) {
const url = (file.fileUrl || file.attachmentUrl || '').toLowerCase()
const name = (file.fileName || '').toLowerCase()
return (
/\.(jpg|jpeg|png|gif|bmp|webp|svg)(\?|$)/.test(url) ||
/\.(jpg|jpeg|png|gif|bmp|webp|svg)$/.test(name) ||
(file.fileType || '').startsWith('image/')
)
}
function isVideoFile(file: PaperAttachmentView) {
const url = (file.fileUrl || file.attachmentUrl || '').toLowerCase()
const name = (file.fileName || '').toLowerCase()
return (
/\.(mp4|webm|ogg|mov|avi)(\?|$)/.test(url) ||
/\.(mp4|webm|ogg|mov|avi)$/.test(name) ||
(file.fileType || '').startsWith('video/')
)
}
function handlePreviewPaperAttachment(att: PaperAttachmentView) {
if (!att.attachmentUrl) return
previewUrl.value = attachmentFullUrl(att.attachmentUrl)
previewType.value = isVideoFile(att) ? 'video' : 'image'
previewVisible.value = true
}
function handleDownloadPaperAttachment(att: PaperAttachmentView) {
if (!att.attachmentUrl) return
downloadAttachmentFile(
{
fileName: att.fileName,
fileUrl: att.attachmentUrl,
fileType: att.fileType || ''
},
{ fullFileUrl: attachmentFullUrl }
)
}
/** 兼容旧版嵌套 pilotContext;新版详情已与 OutboundReleaseReviewDetail 展平一致 */
function resolvePilotDetail(d: OutboundReleaseReviewDetail) {
const nested = (d as { pilotContext?: OutboundReleaseReviewDetail }).pilotContext
@@ -531,114 +253,4 @@
padding-top: 0;
border-top: none;
}
.outbound-material-view {
width: 100%;
}
.outbound-material-block {
margin-bottom: 16px;
&:last-child {
margin-bottom: 0;
}
}
.section-subtitle {
display: flex;
align-items: center;
margin: 0 0 10px;
font-size: 13px;
font-weight: 600;
color: #334155;
&::before {
content: '';
width: 3px;
height: 14px;
margin-right: 8px;
flex-shrink: 0;
background: #047857;
border-radius: 2px;
}
}
.outbound-material-remark {
margin: 12px 0 0;
font-size: 13px;
color: var(--mint-text-muted, #334155);
}
.paper-att-cards {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.paper-att-card {
width: 100px;
height: 72px;
border: 1px solid #e2e8f0;
border-radius: 6px;
background: #f8fafc;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 6px 4px;
position: relative;
overflow: hidden;
}
.paper-att-card__icon {
color: #0284c7;
font-size: 18px;
margin-bottom: 2px;
}
.paper-att-card__name {
width: 100%;
font-size: 11px;
color: #334155;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 1.2;
}
.paper-att-card__actions {
position: absolute;
top: 2px;
right: 2px;
display: flex;
gap: 2px;
opacity: 0;
transition: opacity 0.15s;
}
.paper-att-card:hover .paper-att-card__actions {
opacity: 1;
}
.paper-att-card__action {
width: 18px;
height: 18px;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
color: #fff;
background: rgba(0, 0, 0, 0.35);
cursor: pointer;
&:hover {
background: #047857;
}
}
.preview-container {
text-align: center;
}
</style>
@@ -11,7 +11,7 @@
<el-form :model="searchForm" class="filter-form" @submit.prevent>
<div class="filter-grid">
<el-form-item label="关键词">
<el-input v-model="searchForm.keyword" placeholder="申请单号/患者姓名" clearable />
<el-input v-model="searchForm.keyword" :placeholder="keywordPlaceholder" clearable />
</el-form-item>
<el-form-item label="审核结论">
<el-select
@@ -42,9 +42,7 @@
</el-form-item>
</div>
<div class="filter-actions-row">
<span class="filter-hint"
>支持按申请单号、患者姓名搜索。</span
>
<span class="filter-hint">{{ filterHint }}</span>
<div class="filter-actions-end">
<el-button class="btn-ghost" @click="handleReset">
<el-icon><RefreshLeft /></el-icon>重置
@@ -82,6 +80,8 @@
:total="pagination.total"
:selected-ids="selectedIds"
:pickup-time-label="pickupTimeLabel"
:show-patient="bizConfig.showPatient"
:biz-type="effectiveBizType"
@toggle-select="handleToggleSelect"
@card-dblclick="handleView"
@view="handleView"
@@ -100,6 +100,7 @@
<OutboundReleaseReviewDialog
v-model="reviewDialogVisible"
:schedule-ids="reviewDialogIds"
:context-row="reviewContextRow"
@submitted="onReviewSubmitted"
/>
@@ -137,6 +138,15 @@
const effectiveBizType = computed(() => resolvePilotBizType(props.bizType))
const bizConfig = computed(() => getPilotBizConfig(effectiveBizType.value))
const pickupTimeLabel = computed(() => bizConfig.value.pickupTimeLabel)
const isBasicExperiment = computed(() => effectiveBizType.value === 'basic_experiment')
const keywordPlaceholder = computed(() =>
isBasicExperiment.value ? '申请单号/课题名称/客户名称' : '申请单号/患者姓名'
)
const filterHint = computed(() =>
isBasicExperiment.value
? '支持按申请单号、课题名称、客户名称搜索。'
: '支持按申请单号、患者姓名搜索。'
)
const reviewConclusionOptions = [
{ value: 'tg', label: '通过' },
@@ -216,6 +226,7 @@
const reviewDialogVisible = ref(false)
const reviewDialogIds = ref<string[]>([])
const reviewContextRow = ref<OutboundReleaseReview | null>(null)
function openReviewDialog(row?: OutboundReleaseReview) {
const rows = row ? [row] : selectedRows.value
@@ -224,6 +235,7 @@
return
}
reviewDialogIds.value = rows.map((r) => String(r.scheduleId || r.id))
reviewContextRow.value = rows.length === 1 ? rows[0] : null
reviewDialogVisible.value = true
}
@@ -195,7 +195,7 @@
<div class="product-lines-head">
<span class="product-lines-title">入库明细</span>
<span class="form-label-tip"
>请先选代次,编码自动生成「产品编码-代次-01、-02…」;同代次多份序号递增</span
>请先选代次,编码按「产品编码-代次-序号」生成;序号延续库中同前缀最大号</span
>
</div>
<el-table
@@ -220,7 +220,7 @@
placeholder="代次"
clearable
style="width: 100%"
@change="syncLineCodesFromBase"
@change="applyProductCodeToLines"
>
<el-option v-for="p in passageOptions" :key="p" :label="p" :value="p" />
</el-select>
@@ -316,6 +316,7 @@
import { Close, Check } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { fetchCellProductTypeList, fetchCellProductSpecList } from '@/api/admin'
import { fetchMaxPassageProductSeq } from '@/api/cell-product'
import {
remoteSearchStorageSlotSelectOptions,
ensureStorageSlotsInOptions,
@@ -473,6 +474,7 @@
const formRef = ref()
const submitLoading = ref(false)
const productLines = ref<ProductLine[]>([createEmptyProductLine()])
let lineCodeSyncToken = 0
const formData = reactive({
cellProductId: '',
@@ -564,13 +566,13 @@
])
await nextTick()
formRef.value?.clearValidate?.()
applyProductCodeToLines()
await applyProductCodeToLines()
}
/** 按入库份数同步明细行,并按「编码-代次-序号」重算产品编码 */
function applyProductCodeToLines() {
async function applyProductCodeToLines() {
syncProductLines()
syncLineCodesFromBase()
await syncLineCodesFromBase()
}
function onDialogOpened() {
@@ -589,8 +591,24 @@
return Math.min(n, 50)
}
function syncLineCodesFromBase() {
async function syncLineCodesFromBase() {
const token = ++lineCodeSyncToken
const base = formData.productCode.trim()
const passages = [
...new Set(
productLines.value.map((line) => (line.passage || '').trim()).filter(Boolean)
)
]
let maxSeqByPassage: Record<string, number> = {}
if (base && passages.length) {
try {
const res = await fetchMaxPassageProductSeq(base, passages)
if (token !== lineCodeSyncToken) return
maxSeqByPassage = res?.maxSeqByPassage || {}
} catch {
if (token !== lineCodeSyncToken) return
}
}
const passageCounters = new Map<string, number>()
productLines.value.forEach((line) => {
const passage = (line.passage || '').trim()
@@ -598,8 +616,9 @@
line.productCode = ''
return
}
const seq = (passageCounters.get(passage) || 0) + 1
passageCounters.set(passage, seq)
const localOffset = (passageCounters.get(passage) || 0) + 1
passageCounters.set(passage, localOffset)
const seq = (maxSeqByPassage[passage] ?? 0) + localOffset
line.productCode = `${base}-${passage}-${String(seq).padStart(2, '0')}`
})
}
@@ -623,13 +642,13 @@
function onCreateCountChange() {
if (!isEdit.value) {
applyProductCodeToLines()
void applyProductCodeToLines()
}
}
function onBaseProductCodeInput() {
if (!isEdit.value) {
applyProductCodeToLines()
void applyProductCodeToLines()
}
}
@@ -637,7 +656,7 @@
() => formData.quantity,
() => {
if (!isEdit.value && props.modelValue) {
applyProductCodeToLines()
void applyProductCodeToLines()
}
}
)
@@ -24,14 +24,21 @@
/>
</template>
<template #product-table>
<div v-if="detail?.products?.length" class="view-subtable-wrap">
<el-table :data="detail?.products || []" stripe class="list-table view-subtable">
<el-table-column type="index" label="序号" min-width="60" align="center" />
<div v-if="detail?.products?.length" class="list-body list-wrap view-inner-table-wrap">
<el-table :data="detail?.products || []" stripe class="list-table inner-table" max-height="320">
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
/>
<el-table-column
prop="projectCode"
label="项目编码"
min-width="120"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column
@@ -39,6 +46,7 @@
label="项目名称"
min-width="120"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column
@@ -46,6 +54,7 @@
label="细胞类型"
min-width="100"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column
@@ -53,13 +62,20 @@
label="规格"
min-width="100"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column prop="quantity" label="数量" min-width="70" align="center" />
<el-table-column label="产品状态" min-width="100" align="center">
<el-table-column
prop="quantity"
label="数量"
min-width="70"
align="center"
header-align="center"
/>
<el-table-column label="产品状态" min-width="100" align="center" header-align="center">
<template #default="{ row }">
<el-tag :type="productStatusTag(row.productStatus || '')" size="small">
{{ productStatusLabel(row.productStatus || '') }}
{{ productStatusLabel(row.productStatus || '', productBizType) }}
</el-tag>
</template>
</el-table-column>
@@ -93,6 +109,7 @@
import type { ProductionWorkOrderDetail } from '@/api/production-work-order'
import type { ViewSection } from '@/components/business/system-view-dialog/index.vue'
import { productStatusLabel, productStatusTagType } from '@/utils/status-tag-registry'
import { resolveOutboundViewVariant } from '@/utils/outbound-qc-pilot-view-sections'
import type { TagType } from '@/utils/status-tag-registry'
defineOptions({ name: 'ProductionWorkOrderViewDialogFrame' })
@@ -121,6 +138,12 @@
set: (v) => emit('update:visible', v)
})
const productBizType = computed(() =>
resolveOutboundViewVariant(
props.detail?.bizType || props.detail?.application?.bizType || ''
)
)
function productStatusTag(status: string): TagType {
return productStatusTagType(status) as TagType
}
@@ -133,3 +156,40 @@
emit('download', file)
}
</script>
<style scoped lang="scss">
.view-inner-table-wrap.list-body.list-wrap {
margin-top: 0;
border: 1px solid var(--mint-border, #e2e8f0);
border-radius: var(--mint-radius, 10px);
overflow: hidden;
background: #fff;
:deep(.el-table) {
--el-table-header-bg-color: var(--mint-table-head, #f8fafc);
--el-table-border-color: var(--mint-border, #e2e8f0);
--el-table-row-hover-bg-color: var(--mint-row-hover, #f0fdf4);
--el-table-text-color: var(--mint-text, #0f172a);
--el-table-header-text-color: var(--mint-text-muted, #64748b);
font-size: 14px;
}
:deep(.el-table th.el-table__cell) {
font-size: 12px;
font-weight: 600;
color: var(--mint-text-muted, #64748b);
}
:deep(.el-table td.el-table__cell) {
font-size: 14px;
font-weight: 500;
color: var(--mint-text, #0f172a);
}
}
.view-empty-hint {
margin: 0;
font-size: 13px;
color: var(--mint-text-muted, #334155);
}
</style>
@@ -15,7 +15,7 @@
:view-tasks="viewTasks"
>
<template #product-table>
<OutboundQcProductTable :products="detail?.products" />
<OutboundQcProductTable :products="detail?.products" biz-type="basic_experiment" />
</template>
</QcWorkOrderSystemViewDialog>
</template>
@@ -18,7 +18,7 @@
<OutboundQcDiagnosisAttachments :files="diagnosisAttachmentFiles" />
</template>
<template #product-table>
<OutboundQcProductTable :products="detail?.products" />
<OutboundQcProductTable :products="detail?.products" biz-type="clinical_application" />
</template>
</QcWorkOrderSystemViewDialog>
</template>
@@ -18,7 +18,7 @@
<OutboundQcDiagnosisAttachments :files="diagnosisAttachmentFiles" />
</template>
<template #product-table>
<OutboundQcProductTable :products="detail?.products" />
<OutboundQcProductTable :products="detail?.products" biz-type="pilot_service" />
</template>
</QcWorkOrderSystemViewDialog>
</template>
@@ -1,12 +1,19 @@
<template>
<div v-if="products?.length" class="view-subtable-wrap">
<el-table :data="products" stripe class="list-table view-subtable">
<el-table-column type="index" label="序号" min-width="60" align="center" />
<div v-if="products?.length" class="list-body list-wrap view-inner-table-wrap">
<el-table :data="products" stripe class="list-table inner-table" max-height="320">
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
/>
<el-table-column
prop="projectCode"
label="项目编码"
min-width="120"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column
@@ -14,6 +21,7 @@
label="项目名称"
min-width="120"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column
@@ -21,6 +29,7 @@
label="细胞类型"
min-width="100"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column
@@ -28,13 +37,20 @@
label="规格"
min-width="100"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column prop="quantity" label="数量" min-width="70" align="center" />
<el-table-column label="产品状态" min-width="100" align="center">
<el-table-column
prop="quantity"
label="数量"
min-width="70"
align="center"
header-align="center"
/>
<el-table-column label="产品状态" min-width="100" align="center" header-align="center">
<template #default="{ row }">
<el-tag :type="productStatusTagType(row.productStatus || '') as any" size="small">
{{ productStatusLabel(row.productStatus || '') }}
{{ productStatusLabel(row.productStatus || '', bizType) }}
</el-tag>
</template>
</el-table-column>
@@ -51,13 +67,39 @@
defineProps<{
products?: OutboundQcDetail['products']
/** 基础实验时产品状态 dtz 展示为「待交付」 */
bizType?: string
}>()
</script>
<style scoped lang="scss">
.view-subtable-wrap {
width: 100%;
overflow-x: auto;
.view-inner-table-wrap.list-body.list-wrap {
margin-top: 0;
border: 1px solid var(--mint-border, #e2e8f0);
border-radius: var(--mint-radius, 10px);
overflow: hidden;
background: #fff;
:deep(.el-table) {
--el-table-header-bg-color: var(--mint-table-head, #f8fafc);
--el-table-border-color: var(--mint-border, #e2e8f0);
--el-table-row-hover-bg-color: var(--mint-row-hover, #f0fdf4);
--el-table-text-color: var(--mint-text, #0f172a);
--el-table-header-text-color: var(--mint-text-muted, #64748b);
font-size: 14px;
}
:deep(.el-table th.el-table__cell) {
font-size: 12px;
font-weight: 600;
color: var(--mint-text-muted, #64748b);
}
:deep(.el-table td.el-table__cell) {
font-size: 14px;
font-weight: 500;
color: var(--mint-text, #0f172a);
}
}
.view-empty-hint {