This commit is contained in:
zlwu committed 2026-07-02 12:25:00 +08:00
1 parent 038a60b09e
commit 3740a7dd80
45 files changed
+10945 -6192

No files matched your search

-1
View File
@@ -1 +0,0 @@
59139
+5 -1
View File
@@ -716,7 +716,7 @@ def configure_work_order_batches(
create_dept_id: str = "",
) -> BizQcWorkOrder:
status = (wo.work_order_status or "").strip()
if status not in ("dpz", "ypz"):
if status not in ("dpz", "ypz", "ywc"):
raise ValueError("当前工单状态不可配置检测")
if not batches:
raise ValueError("请至少添加一个检测批次")
@@ -867,6 +867,10 @@ def configure_work_order_batches(
sync_schedule_from_qc_work_order(db, wo, user_id=user_id)
db.commit()
from app.crud.qc_work_order import try_complete_work_order
try_complete_work_order(db, wo.id, tenant_no)
db.refresh(wo)
return wo
+24 -2
View File
@@ -885,9 +885,8 @@ def delete_qc_task(db: Session, task_id: str, tenant_no: str, user_id: Optional[
).first()
if not task:
raise ValueError("任务不存在")
if task.task_status != "dzx":
raise ValueError("仅待执行的任务可以删除")
work_order_id = task.work_order_id
now = datetime.now()
# 软删除任务结果
@@ -906,4 +905,27 @@ def delete_qc_task(db: Session, task_id: str, tenant_no: str, user_id: Optional[
task.update_by = user_id
task.update_time = now
db.flush()
from app.crud.qc_work_order import get_work_order, try_complete_work_order
wo = get_work_order(db, work_order_id, tenant_no=tenant_no)
if wo and (wo.work_order_status or "").strip() == "ywc":
pending = (
db.query(BizQcTask)
.filter(
BizQcTask.work_order_id == work_order_id,
BizQcTask.tenant_no == tenant_no,
BizQcTask.del_flag == 0,
BizQcTask.task_status != "ywc",
)
.count()
)
if pending:
wo.work_order_status = "ypz"
wo.update_by = user_id
wo.update_time = now
db.add(wo)
db.commit()
try_complete_work_order(db, work_order_id, tenant_no)
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_inspection_batch_py", "label": "qc_inspection_batch.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L1"}, {"id": "crud_qc_inspection_batch_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L27"}, {"id": "crud_qc_inspection_batch_unique_ids", "label": "_unique_ids()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L33"}, {"id": "crud_qc_inspection_batch_validate_batch_payload", "label": "_validate_batch_payload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L45"}, {"id": "crud_qc_inspection_batch_order_source_for_wo", "label": "_order_source_for_wo()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L69"}, {"id": "crud_qc_inspection_batch_next_batch_no", "label": "_next_batch_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L78"}, {"id": "crud_qc_inspection_batch_allocate_batch_name", "label": "_allocate_batch_name()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L97"}, {"id": "crud_qc_inspection_batch_sync_batch_assignees", "label": "sync_batch_assignees()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L119"}, {"id": "crud_qc_inspection_batch_batch_assignee_user_ids", "label": "_batch_assignee_user_ids()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L168"}, {"id": "crud_qc_inspection_batch_assignee_names", "label": "_assignee_names()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L182"}, {"id": "crud_qc_inspection_batch_apply_assignees_to_batch_tasks", "label": "_apply_assignees_to_batch_tasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L194"}, {"id": "crud_qc_inspection_batch_batch_has_blocking_tasks", "label": "_batch_has_blocking_tasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L223"}, {"id": "crud_qc_inspection_batch_soft_delete_batch", "label": "_soft_delete_batch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L237"}, {"id": "crud_qc_inspection_batch_sync_batch_lab_items", "label": "_sync_batch_lab_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L285"}, {"id": "crud_qc_inspection_batch_sync_batch_third_items", "label": "_sync_batch_third_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L413"}, {"id": "crud_qc_inspection_batch_batch_item_ids", "label": "_batch_item_ids()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L557"}, {"id": "crud_qc_inspection_batch_batch_to_dict", "label": "_batch_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L578"}, {"id": "crud_qc_inspection_batch_build_inspection_batch_list", "label": "_build_inspection_batch_list()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L607"}, {"id": "crud_qc_inspection_batch_list_inspection_batches", "label": "list_inspection_batches()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L651"}, {"id": "crud_qc_inspection_batch_list_inspection_batches_by_work_order_ids", "label": "list_inspection_batches_by_work_order_ids()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L668"}, {"id": "crud_qc_inspection_batch_configure_work_order_batches", "label": "configure_work_order_batches()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L709"}, {"id": "crud_qc_inspection_batch_normalize_legacy_configure_to_batches", "label": "normalize_legacyLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_py", "label": "qc_task.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L1"}, {"id": "crud_qc_task_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L38"}, {"id": "crud_qc_task_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L44"}, {"id": "crud_qc_task_gen_task_no", "label": "_gen_task_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L48"}, {"id": "crud_qc_task_conclusion_label", "label": "_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L61"}, {"id": "crud_qc_task_task_to_dict", "label": "_task_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L66"}, {"id": "crud_qc_task_task_work_order_context", "label": "_task_work_order_context()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L100"}, {"id": "crud_qc_task_merge_work_order_summary_into_task", "label": "_merge_work_order_summary_into_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L176"}, {"id": "crud_qc_task_enrich_mine_tasks_with_work_order_summaries", "label": "_enrich_mine_tasks_with_work_order_summaries()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L200"}, {"id": "crud_qc_task_enrich_tasks_reception_fields", "label": "_enrich_tasks_reception_fields()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L220"}, {"id": "crud_qc_task_task_row_to_dict", "label": "_task_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L367"}, {"id": "crud_qc_task_create_task_for_line", "label": "create_task_for_line()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L378"}, {"id": "crud_qc_task_list_tasks", "label": "list_tasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L425"}, {"id": "crud_qc_task_list_mine_tasks", "label": "list_mine_tasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L506"}, {"id": "crud_qc_task_assert_task_assignee", "label": "assert_task_assignee()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L598"}, {"id": "crud_qc_task_list_tasks_by_work_order", "label": "list_tasks_by_work_order()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L605"}, {"id": "crud_qc_task_list_tasks_by_work_order_ids", "label": "list_tasks_by_work_order_ids()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L612"}, {"id": "crud_qc_task_get_task", "label": "get_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L642"}, {"id": "crud_qc_task_get_task_detail", "label": "get_task_detail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L651"}, {"id": "crud_qc_task_start_task", "label": "start_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L684"}, {"id": "crud_qc_task_set_task_remark", "label": "_set_task_remark()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L701"}, {"id": "crud_qc_task_complete_task", "label": "complete_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L705"}, {"id": "crud_qc_task_apply_task_result", "label": "apply_task_result()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L746"}, {"id": "crud_qc_task_update_task_attachments", "label": "update_task_attachments()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L798"}, {"id": "crud_qc_task_create_qc_task_manual", "label": "create_qc_task_manual()", "file_type": "code"Line truncated
+272 -266
View File
@@ -813,7 +813,6 @@
"crud_base_crudbase_get",
"crud_cleanroom_garment_get_garment_detail",
"crud_clinical_payment_apply_submit_receipt",
"crud_clinical_payment_auto_create_payment",
"crud_clinical_payment_batch_submit_receipt",
"crud_clinical_payment_batch_submit_refund",
"crud_clinical_payment_confirm_receipt",
@@ -901,7 +900,6 @@
"crud_sample_production_reception_update_production_reception",
"crud_sample_production_reception_validate_handler_user_id",
"crud_sample_production_reception_validate_payload",
"crud_workflow_get_all_tasks_for_business",
"schemas_order_adjust_adjuststatus",
"schemas_order_adjust_adjusttype",
"schemas_order_adjust_py",
@@ -1571,6 +1569,21 @@
"crud_clean_room_update_clean_room",
"crud_clean_room_update_uv_disinfect_log",
"crud_clean_room_uv_disinfect_log_to_dict",
"crud_collection_region_create_collection_region",
"crud_collection_region_create_hospital",
"crud_collection_region_get_collection_region",
"crud_collection_region_get_hospital",
"crud_collection_region_hospital_names_by_region_ids",
"crud_collection_region_hospital_to_dict",
"crud_collection_region_list_collection_regions",
"crud_collection_region_list_hospitals",
"crud_collection_region_py",
"crud_collection_region_search_hospitals_by_keyword",
"crud_collection_region_soft_delete_collection_region",
"crud_collection_region_soft_delete_hospital",
"crud_collection_region_total_pages",
"crud_collection_region_update_collection_region",
"crud_collection_region_update_hospital",
"crud_consumable_batch_stock_in",
"crud_consumable_batch_stock_out",
"crud_consumable_build_manual_out_remark",
@@ -1648,16 +1661,6 @@
"crud_material_usage_unit_price_for_row",
"crud_material_usage_usage_unit_label",
"crud_material_usage_user_nick_name_map",
"crud_output_type_create_output_type",
"crud_output_type_get_output_type",
"crud_output_type_list_output_types",
"crud_output_type_py",
"crud_output_type_rationale_1",
"crud_output_type_row_to_dict",
"crud_output_type_soft_delete_output_type",
"crud_output_type_total_pages",
"crud_output_type_type_code_exists",
"crud_output_type_update_output_type",
"crud_pilot_service_activate_channel_agreement",
"crud_pilot_service_apply_gmcp_order_quotas",
"crud_pilot_service_apply_purchase_txn_holdings",
@@ -1987,37 +1990,26 @@
"crud_reagent_stock_out",
"crud_reagent_total_pages",
"crud_reagent_update_reagent",
"crud_site_create_site",
"crud_site_get_site",
"crud_site_list_sites",
"crud_site_py",
"crud_site_row_to_dict",
"crud_site_site_code_exists",
"crud_site_soft_delete_site",
"crud_site_total_pages",
"crud_site_update_site",
"crud_sop_document_create_sop_document",
"crud_sop_document_get_sop_document",
"crud_sop_document_list_sop_documents",
"crud_sop_document_py",
"crud_sop_document_rationale_1",
"crud_sop_document_row_to_dict",
"crud_sop_document_soft_delete_sop_document",
"crud_sop_document_sop_code_exists",
"crud_sop_document_total_pages",
"crud_sop_document_update_sop_document",
"crud_tenant_create_tenant",
"crud_tenant_get_tenant",
"crud_tenant_list_tenants",
"crud_tenant_py",
"crud_tenant_row_to_dict",
"crud_tenant_soft_delete_tenant",
"crud_tenant_tenant_no_exists",
"crud_tenant_total_pages",
"crud_tenant_update_tenant",
"crud_sample_code_batch_generate_sample_codes",
"crud_sample_code_batch_issue_sample_codes",
"crud_sample_code_batch_revoke_sample_codes",
"crud_sample_code_create_sample_code",
"crud_sample_code_get_sample_code",
"crud_sample_code_list_sample_codes",
"crud_sample_code_parse_issued_time",
"crud_sample_code_py",
"crud_sample_code_rationale_1",
"crud_sample_code_rationale_261",
"crud_sample_code_resolve_issued_user_display_name",
"crud_sample_code_row_to_dict",
"crud_sample_code_sample_code_exists",
"crud_sample_code_soft_delete_sample_code",
"crud_sample_code_total_pages",
"crud_sample_code_update_sample_code",
"crud_workflow_create_instance",
"crud_workflow_create_process_def",
"crud_workflow_create_task",
"crud_workflow_get_all_tasks_for_business",
"crud_workflow_get_instance",
"crud_workflow_get_latest_version",
"crud_workflow_get_nodes_by_version",
@@ -2516,7 +2508,6 @@
"crud_collection_protocol_detail_query_with_protocol",
"crud_collection_protocol_detail_to_dict",
"crud_collection_protocol_fmt_dt",
"crud_collection_protocol_format_attachment_file_size",
"crud_collection_protocol_format_newborn_info",
"crud_collection_protocol_format_sample_collect_summary",
"crud_collection_protocol_format_storage_cert_sample_info",
@@ -2557,6 +2548,23 @@
"crud_collection_protocol_load_unit_name_map",
"crud_collection_protocol_lookup_attachment_by_url",
"crud_collection_protocol_migrate_sample_child_refs_on_replace",
"crud_collection_protocol_no_batch_generate_protocol_nos",
"crud_collection_protocol_no_batch_issue_protocol_nos",
"crud_collection_protocol_no_batch_revoke_protocol_nos",
"crud_collection_protocol_no_create_protocol_no",
"crud_collection_protocol_no_get_protocol_no",
"crud_collection_protocol_no_list_protocol_nos",
"crud_collection_protocol_no_parse_issued_time",
"crud_collection_protocol_no_protocol_no_exists",
"crud_collection_protocol_no_py",
"crud_collection_protocol_no_rationale_1",
"crud_collection_protocol_no_rationale_20",
"crud_collection_protocol_no_rationale_256",
"crud_collection_protocol_no_resolve_issued_user_display_name",
"crud_collection_protocol_no_row_to_dict",
"crud_collection_protocol_no_soft_delete_protocol_no",
"crud_collection_protocol_no_total_pages",
"crud_collection_protocol_no_update_protocol_no",
"crud_collection_protocol_normalize_attachment_url_key",
"crud_collection_protocol_normalize_date_bound",
"crud_collection_protocol_normalize_fields",
@@ -2597,7 +2605,6 @@
"crud_collection_protocol_upsert_party_customer",
"crud_collection_protocol_upsert_payment",
"crud_collection_protocol_upsert_storage_cert",
"crud_collection_protocol_urls_to_attachment_list",
"crud_collection_protocol_user_nick_name_map",
"crud_collection_protocol_validate_receipt_finance_submit_ready",
"crud_collection_protocol_validate_sample_codes_not_used",
@@ -2641,14 +2648,7 @@
"crud_pre_transit_sample_sort_key_pre_delivery",
"crud_pre_transit_sample_summarize_in_transit_items",
"crud_pre_transit_sample_summarize_pre_delivery",
"crud_protocol_donation_convert_active_link_query",
"crud_protocol_donation_convert_assert_biz_no_available",
"crud_protocol_donation_convert_create_convert_link",
"crud_protocol_donation_convert_get_convert_partner",
"crud_protocol_donation_convert_get_partner_sample_codes",
"crud_protocol_donation_convert_has_active_convert_link",
"crud_protocol_donation_convert_py",
"crud_protocol_donation_convert_upsert_convert_link_for_to_storage",
"crud_protocol_sample_collection_apply_sample_status_filter",
"crud_protocol_sample_collection_base_query",
"crud_protocol_sample_collection_fmt_dt",
@@ -2724,89 +2724,7 @@
"crud_research_donation_transport_to_dict",
"crud_research_donation_update_donation",
"crud_research_donation_user_nick_name_map",
"crud_sample_production_reception_get_map_by_reception_ids",
"crud_sample_reception_attach_production_reception",
"crud_sample_reception_can_edit_sample_reception",
"crud_sample_reception_check_result_get_check_results_for_reception",
"crud_sample_reception_check_result_legacy_results_from_reception",
"crud_sample_reception_check_result_list_results_by_reception_ids",
"crud_sample_reception_check_result_py",
"crud_sample_reception_check_result_result_to_dict",
"crud_sample_reception_check_result_save_reception_check_results",
"crud_sample_reception_check_result_soft_delete_reception_check_results",
"crud_sample_reception_check_result_sync_legacy_columns_from_results",
"crud_sample_reception_create_sample_reception",
"crud_sample_reception_dec",
"crud_sample_reception_donation_ids_matching_lab_storage_keyword",
"crud_sample_reception_donation_rows_to_sample_list_items",
"crud_sample_reception_donation_sample_detail_rows_query",
"crud_sample_reception_donation_sample_id_col",
"crud_sample_reception_donation_sample_pending_query",
"crud_sample_reception_finalize_reception_detail",
"crud_sample_reception_fmt_dt",
"crud_sample_reception_format_lab_storage_codes_csv",
"crud_sample_reception_get_lab_storage_code_map_by_sample_codes",
"crud_sample_reception_get_reception_by_id",
"crud_sample_reception_get_reception_by_sample_code",
"crud_sample_reception_get_receptions_map_for_donation_samples",
"crud_sample_reception_get_receptions_map_for_samples",
"crud_sample_reception_lab_code_allocate_lab_storage_codes",
"crud_sample_reception_lab_code_allocate_one_seq",
"crud_sample_reception_lab_code_assert_lab_storage_code_available",
"crud_sample_reception_lab_code_format_lab_storage_code",
"crud_sample_reception_lab_code_max_existing_seq",
"crud_sample_reception_lab_code_parse_reception_date",
"crud_sample_reception_lab_code_py",
"crud_sample_reception_lab_code_rationale_1",
"crud_sample_reception_lab_code_rationale_172",
"crud_sample_reception_lab_code_reception_time_date_str",
"crud_sample_reception_lab_code_sync_lab_storage_seq_after_use",
"crud_sample_reception_lab_code_sync_sequence_from_existing",
"crud_sample_reception_lab_code_validate_and_parse_lab_storage_code",
"crud_sample_reception_lab_storage_keyword_like",
"crud_sample_reception_list_pending_protocol_samples",
"crud_sample_reception_list_received_protocol_samples",
"crud_sample_reception_normalize_date_bound",
"crud_sample_reception_protocol_ids_matching_lab_storage_keyword",
"crud_sample_reception_py",
"crud_sample_reception_reception_detail_item",
"crud_sample_reception_reception_detail_item_with_production",
"crud_sample_reception_reception_ids_matching_lab_storage_keyword",
"crud_sample_reception_reception_sample_code",
"crud_sample_reception_reception_to_dict",
"crud_sample_reception_rows_to_sample_list_items",
"crud_sample_reception_sample_codes_matching_lab_storage_keyword",
"crud_sample_reception_sample_detail_rows_query",
"crud_sample_reception_sample_pending_query",
"crud_sample_reception_update_sample_reception",
"crud_sample_sms_notification_accept_conclusion_label",
"crud_sample_sms_notification_base_query",
"crud_sample_sms_notification_ensure_notification",
"crud_sample_sms_notification_fetch_sample_type_name",
"crud_sample_sms_notification_fmt_dt",
"crud_sample_sms_notification_generate_sms_content",
"crud_sample_sms_notification_list_notifications",
"crud_sample_sms_notification_normalize_date_bound",
"crud_sample_sms_notification_py",
"crud_sample_sms_notification_resolve_notification",
"crud_sample_sms_notification_row_to_dict",
"crud_sample_sms_notification_toggle_notification_status",
"crud_sample_sms_notification_total_pages",
"crud_sample_sms_notification_unicode_ci",
"crud_storage_entry_sms_notification_base_query",
"crud_storage_entry_sms_notification_ensure_notification",
"crud_storage_entry_sms_notification_fetch_sample_type_name",
"crud_storage_entry_sms_notification_fmt_dt",
"crud_storage_entry_sms_notification_generate_sms_content",
"crud_storage_entry_sms_notification_list_notifications",
"crud_storage_entry_sms_notification_normalize_date_bound",
"crud_storage_entry_sms_notification_py",
"crud_storage_entry_sms_notification_resolve_notification",
"crud_storage_entry_sms_notification_row_to_dict",
"crud_storage_entry_sms_notification_storage_status_label",
"crud_storage_entry_sms_notification_toggle_notification_status",
"crud_storage_entry_sms_notification_total_pages",
"crud_storage_entry_sms_notification_unicode_ci",
"services_protocol_payment_installment_add_days_yyyymmdd",
"services_protocol_payment_installment_add_interval_months_yyyymmdd",
"services_protocol_payment_installment_add_months_yyyymmdd",
@@ -2936,15 +2854,22 @@
"crud_production_work_order_rationale_788",
"crud_production_work_order_rationale_839",
"crud_production_work_order_rationale_865",
"crud_protocol_donation_convert_active_link_query",
"crud_protocol_donation_convert_create_convert_link",
"crud_protocol_donation_convert_get_convert_partner",
"crud_protocol_donation_convert_get_partner_sample_codes",
"crud_protocol_donation_convert_has_active_convert_link",
"crud_protocol_donation_convert_py",
"crud_protocol_donation_convert_rationale_1",
"crud_protocol_donation_convert_rationale_132",
"crud_protocol_donation_convert_rationale_198",
"crud_protocol_donation_convert_rationale_273",
"crud_protocol_donation_convert_rationale_35",
"crud_protocol_donation_convert_rationale_84",
"crud_protocol_donation_convert_upsert_convert_link_for_to_storage",
"crud_protocol_sample_collection_rationale_1",
"crud_qc_inspection_batch_rationale_675",
"crud_qc_inspection_batch_rationale_875",
"crud_qc_inspection_batch_rationale_879",
"crud_qc_inspection_batch_sync_batch_lab_items",
"crud_qc_inspection_batch_sync_batch_third_items",
"crud_qc_sms_notification_rationale_32",
@@ -3345,24 +3270,6 @@
"services_qc_work_order_fee_summary_sort_payment_details"
],
"7": [
"crud_material_code_exists",
"crud_material_create_material",
"crud_material_dec",
"crud_material_fmt_dt",
"crud_material_get_material",
"crud_material_get_material_entity",
"crud_material_get_my_usages",
"crud_material_is_enabled_status",
"crud_material_list_materials",
"crud_material_mine_usage_receiver_filter",
"crud_material_my_usage_batch_map",
"crud_material_my_usage_row_to_dict",
"crud_material_my_usage_user_nick_name_map",
"crud_material_norm_status",
"crud_material_options_list",
"crud_material_py",
"crud_material_row_to_dict",
"crud_material_soft_delete_material",
"crud_material_stock_batch_batch_discard",
"crud_material_stock_batch_batch_options",
"crud_material_stock_batch_batch_row_to_dict",
@@ -3408,8 +3315,6 @@
"crud_material_stock_check_unused_amount",
"crud_material_stock_check_unused_line_to_dict",
"crud_material_stock_check_user_nick_name_map",
"crud_material_update_material",
"crud_material_update_material_fields",
"crud_outbound_handover_inventory_apply_handover_inventory",
"crud_outbound_handover_inventory_deduct_market_material_for_handover",
"crud_outbound_handover_inventory_get_cell_product_locked",
@@ -3979,6 +3884,102 @@
"tasks_init_shutdown_scheduler"
],
"11": [
"crud_collection_protocol_format_attachment_file_size",
"crud_collection_protocol_urls_to_attachment_list",
"crud_sample_production_reception_get_map_by_reception_ids",
"crud_sample_reception_attach_production_reception",
"crud_sample_reception_can_edit_sample_reception",
"crud_sample_reception_check_result_get_check_results_for_reception",
"crud_sample_reception_check_result_legacy_results_from_reception",
"crud_sample_reception_check_result_list_results_by_reception_ids",
"crud_sample_reception_check_result_py",
"crud_sample_reception_check_result_result_to_dict",
"crud_sample_reception_check_result_save_reception_check_results",
"crud_sample_reception_check_result_soft_delete_reception_check_results",
"crud_sample_reception_check_result_sync_legacy_columns_from_results",
"crud_sample_reception_create_sample_reception",
"crud_sample_reception_dec",
"crud_sample_reception_donation_ids_matching_lab_storage_keyword",
"crud_sample_reception_donation_rows_to_sample_list_items",
"crud_sample_reception_donation_sample_detail_rows_query",
"crud_sample_reception_donation_sample_id_col",
"crud_sample_reception_donation_sample_pending_query",
"crud_sample_reception_finalize_reception_detail",
"crud_sample_reception_fmt_dt",
"crud_sample_reception_format_lab_storage_codes_csv",
"crud_sample_reception_get_reception_by_id",
"crud_sample_reception_get_reception_by_sample_code",
"crud_sample_reception_get_receptions_map_for_donation_samples",
"crud_sample_reception_get_receptions_map_for_samples",
"crud_sample_reception_lab_code_allocate_lab_storage_codes",
"crud_sample_reception_lab_code_allocate_one_seq",
"crud_sample_reception_lab_code_assert_lab_storage_code_available",
"crud_sample_reception_lab_code_format_lab_storage_code",
"crud_sample_reception_lab_code_max_existing_seq",
"crud_sample_reception_lab_code_parse_reception_date",
"crud_sample_reception_lab_code_py",
"crud_sample_reception_lab_code_rationale_1",
"crud_sample_reception_lab_code_rationale_172",
"crud_sample_reception_lab_code_reception_time_date_str",
"crud_sample_reception_lab_code_sync_lab_storage_seq_after_use",
"crud_sample_reception_lab_code_sync_sequence_from_existing",
"crud_sample_reception_lab_code_validate_and_parse_lab_storage_code",
"crud_sample_reception_lab_storage_keyword_like",
"crud_sample_reception_list_pending_protocol_samples",
"crud_sample_reception_list_received_protocol_samples",
"crud_sample_reception_normalize_date_bound",
"crud_sample_reception_protocol_ids_matching_lab_storage_keyword",
"crud_sample_reception_py",
"crud_sample_reception_reception_detail_item",
"crud_sample_reception_reception_detail_item_with_production",
"crud_sample_reception_reception_ids_matching_lab_storage_keyword",
"crud_sample_reception_reception_sample_code",
"crud_sample_reception_reception_to_dict",
"crud_sample_reception_rows_to_sample_list_items",
"crud_sample_reception_sample_codes_matching_lab_storage_keyword",
"crud_sample_reception_sample_detail_rows_query",
"crud_sample_reception_sample_pending_query",
"crud_sample_reception_update_sample_reception",
"crud_sample_sms_notification_accept_conclusion_label",
"crud_sample_sms_notification_base_query",
"crud_sample_sms_notification_ensure_notification",
"crud_sample_sms_notification_fetch_sample_type_name",
"crud_sample_sms_notification_fmt_dt",
"crud_sample_sms_notification_generate_sms_content",
"crud_sample_sms_notification_list_notifications",
"crud_sample_sms_notification_normalize_date_bound",
"crud_sample_sms_notification_py",
"crud_sample_sms_notification_resolve_notification",
"crud_sample_sms_notification_row_to_dict",
"crud_sample_sms_notification_toggle_notification_status",
"crud_sample_sms_notification_total_pages",
"crud_sample_sms_notification_unicode_ci",
"crud_sop_document_create_sop_document",
"crud_sop_document_get_sop_document",
"crud_sop_document_list_sop_documents",
"crud_sop_document_py",
"crud_sop_document_rationale_1",
"crud_sop_document_row_to_dict",
"crud_sop_document_soft_delete_sop_document",
"crud_sop_document_sop_code_exists",
"crud_sop_document_total_pages",
"crud_sop_document_update_sop_document",
"crud_storage_entry_sms_notification_base_query",
"crud_storage_entry_sms_notification_ensure_notification",
"crud_storage_entry_sms_notification_fetch_sample_type_name",
"crud_storage_entry_sms_notification_fmt_dt",
"crud_storage_entry_sms_notification_generate_sms_content",
"crud_storage_entry_sms_notification_list_notifications",
"crud_storage_entry_sms_notification_normalize_date_bound",
"crud_storage_entry_sms_notification_py",
"crud_storage_entry_sms_notification_resolve_notification",
"crud_storage_entry_sms_notification_row_to_dict",
"crud_storage_entry_sms_notification_storage_status_label",
"crud_storage_entry_sms_notification_toggle_notification_status",
"crud_storage_entry_sms_notification_total_pages",
"crud_storage_entry_sms_notification_unicode_ci"
],
"12": [
"api_production_batchstockinbody",
"api_production_batchstockinitem",
"api_production_batchstockoutbody",
@@ -4062,7 +4063,8 @@
"schemas_production_work_order_py",
"schemas_qc_work_order_productionqcworkordercreatebody"
],
"12": [
"13": [
"crud_clinical_payment_auto_create_payment",
"crud_pilot_application_complete_application",
"crud_pilot_application_create_basic_experiment_sale_schedules",
"crud_pilot_application_create_infusion_plan",
@@ -4130,7 +4132,7 @@
"crud_pilot_outbound_status_sync_sync_schedule_from_qc_work_order",
"crud_pilot_outbound_status_sync_touch"
],
"13": [
"14": [
"crud_storage_facility_aggregate_slot_stats_by_facility",
"crud_storage_facility_apply_slot_select_base_filters",
"crud_storage_facility_apply_slot_select_query_filters",
@@ -4192,7 +4194,7 @@
"services_storage_facility_code_refresh_outbound_release_cell_slot_names",
"services_storage_facility_code_validate_node_code"
],
"14": [
"15": [
"crud_cleanroom_garment_batch_create_sterilize_logs",
"crud_cleanroom_garment_batch_create_wash_logs",
"crud_cleanroom_garment_batch_discard_garments",
@@ -4232,7 +4234,7 @@
"models_cleanroom_garment_rationale_54",
"models_cleanroom_garment_rationale_9"
],
"15": [
"16": [
"core_wechat_pay_get_wechat_pay_client",
"core_wechat_pay_get_wechat_pay_v2",
"core_wechat_pay_py",
@@ -4263,7 +4265,29 @@
"core_wechat_pay_wechatpayv2client_unified_order",
"core_wechat_pay_wechatpayv2client_xml_to_dict"
],
"16": [
"17": [
"crud_material_code_exists",
"crud_material_create_material",
"crud_material_dec",
"crud_material_fmt_dt",
"crud_material_get_material",
"crud_material_get_material_entity",
"crud_material_get_my_usages",
"crud_material_is_enabled_status",
"crud_material_list_materials",
"crud_material_mine_usage_receiver_filter",
"crud_material_my_usage_batch_map",
"crud_material_my_usage_row_to_dict",
"crud_material_my_usage_user_nick_name_map",
"crud_material_norm_status",
"crud_material_options_list",
"crud_material_py",
"crud_material_row_to_dict",
"crud_material_soft_delete_material",
"crud_material_update_material",
"crud_material_update_material_fields"
],
"18": [
"crud_qc_third_party_company_company_code_exists",
"crud_qc_third_party_company_create_company",
"crud_qc_third_party_company_get_company",
@@ -4285,61 +4309,7 @@
"crud_qc_third_party_item_soft_delete_item",
"crud_qc_third_party_item_update_item"
],
"17": [
"crud_collection_protocol_no_batch_generate_protocol_nos",
"crud_collection_protocol_no_batch_issue_protocol_nos",
"crud_collection_protocol_no_batch_revoke_protocol_nos",
"crud_collection_protocol_no_create_protocol_no",
"crud_collection_protocol_no_get_protocol_no",
"crud_collection_protocol_no_list_protocol_nos",
"crud_collection_protocol_no_parse_issued_time",
"crud_collection_protocol_no_protocol_no_exists",
"crud_collection_protocol_no_py",
"crud_collection_protocol_no_rationale_1",
"crud_collection_protocol_no_rationale_20",
"crud_collection_protocol_no_rationale_256",
"crud_collection_protocol_no_resolve_issued_user_display_name",
"crud_collection_protocol_no_row_to_dict",
"crud_collection_protocol_no_soft_delete_protocol_no",
"crud_collection_protocol_no_total_pages",
"crud_collection_protocol_no_update_protocol_no"
],
"18": [
"crud_sample_code_batch_generate_sample_codes",
"crud_sample_code_batch_issue_sample_codes",
"crud_sample_code_batch_revoke_sample_codes",
"crud_sample_code_create_sample_code",
"crud_sample_code_get_sample_code",
"crud_sample_code_list_sample_codes",
"crud_sample_code_parse_issued_time",
"crud_sample_code_py",
"crud_sample_code_rationale_1",
"crud_sample_code_rationale_261",
"crud_sample_code_resolve_issued_user_display_name",
"crud_sample_code_row_to_dict",
"crud_sample_code_sample_code_exists",
"crud_sample_code_soft_delete_sample_code",
"crud_sample_code_total_pages",
"crud_sample_code_update_sample_code"
],
"19": [
"crud_collection_region_create_collection_region",
"crud_collection_region_create_hospital",
"crud_collection_region_get_collection_region",
"crud_collection_region_get_hospital",
"crud_collection_region_hospital_names_by_region_ids",
"crud_collection_region_hospital_to_dict",
"crud_collection_region_list_collection_regions",
"crud_collection_region_list_hospitals",
"crud_collection_region_py",
"crud_collection_region_search_hospitals_by_keyword",
"crud_collection_region_soft_delete_collection_region",
"crud_collection_region_soft_delete_hospital",
"crud_collection_region_total_pages",
"crud_collection_region_update_collection_region",
"crud_collection_region_update_hospital"
],
"20": [
"crud_equipment_create_equipment",
"crud_equipment_dec",
"crud_equipment_equipment_code_exists",
@@ -4355,7 +4325,7 @@
"crud_equipment_total_pages",
"crud_equipment_update_equipment"
],
"21": [
"20": [
"core_wechat_message_py",
"core_wechat_message_rationale_1",
"core_wechat_message_rationale_86",
@@ -4370,7 +4340,7 @@
"core_wechat_message_wechatmessageservice_init",
"core_wechat_message_wechatmessageservice_send_template_message"
],
"22": [
"21": [
"crud_exhibition_appointment_appointment_no_exists",
"crud_exhibition_appointment_create_exhibition_appointment",
"crud_exhibition_appointment_format_visit_date",
@@ -4385,7 +4355,7 @@
"crud_exhibition_appointment_soft_delete_exhibition_appointment",
"crud_exhibition_appointment_update_exhibition_appointment"
],
"23": [
"22": [
"crud_reagent_stock_log_deduct_for_step",
"crud_reagent_stock_log_display_remark",
"crud_reagent_stock_log_list_stock_logs",
@@ -4399,7 +4369,7 @@
"crud_reagent_stock_log_row_to_dict",
"crud_reagent_stock_log_user_nick_name_map"
],
"24": [
"23": [
"crud_env_detect_record_create_env_detect_record",
"crud_env_detect_record_generate_record_no",
"crud_env_detect_record_get_env_detect_record",
@@ -4413,7 +4383,7 @@
"crud_env_detect_record_split_csv",
"crud_env_detect_record_update_env_detect_record"
],
"25": [
"24": [
"crud_consumable_stock_log_deduct_for_step",
"crud_consumable_stock_log_display_remark",
"crud_consumable_stock_log_list_stock_logs",
@@ -4427,7 +4397,7 @@
"crud_consumable_stock_log_row_to_dict",
"crud_consumable_stock_log_user_nick_name_map"
],
"26": [
"25": [
"crud_dept_build_tree",
"crud_dept_cascade_soft_delete",
"crud_dept_collect_with_ancestors",
@@ -4441,7 +4411,7 @@
"crud_dept_soft_delete_dept",
"crud_dept_update_dept"
],
"27": [
"26": [
"crud_menu_build_tree",
"crud_menu_cascade_soft_delete",
"crud_menu_create_menu",
@@ -4454,7 +4424,7 @@
"crud_menu_soft_delete_menu",
"crud_menu_update_menu"
],
"28": [
"27": [
"crud_customer_create_customer",
"crud_customer_get_customer",
"crud_customer_id_card_taken",
@@ -4467,7 +4437,7 @@
"crud_customer_total_pages",
"crud_customer_update_customer"
],
"29": [
"28": [
"crud_sample_reception_check_item_create_check_item",
"crud_sample_reception_check_item_get_check_item",
"crud_sample_reception_check_item_item_code_exists",
@@ -4479,7 +4449,7 @@
"crud_sample_reception_check_item_soft_delete_check_item",
"crud_sample_reception_check_item_update_check_item"
],
"30": [
"29": [
"crud_env_detect_item_create_env_detect_item",
"crud_env_detect_item_get_env_detect_item",
"crud_env_detect_item_item_code_exists",
@@ -4491,7 +4461,7 @@
"crud_env_detect_item_soft_delete_env_detect_item",
"crud_env_detect_item_update_env_detect_item"
],
"31": [
"30": [
"crud_item_unit_create_item_unit",
"crud_item_unit_get_item_unit",
"crud_item_unit_list_item_units",
@@ -4503,7 +4473,41 @@
"crud_item_unit_unit_code_exists",
"crud_item_unit_update_item_unit"
],
"31": [
"crud_output_type_create_output_type",
"crud_output_type_get_output_type",
"crud_output_type_list_output_types",
"crud_output_type_py",
"crud_output_type_rationale_1",
"crud_output_type_row_to_dict",
"crud_output_type_soft_delete_output_type",
"crud_output_type_total_pages",
"crud_output_type_type_code_exists",
"crud_output_type_update_output_type"
],
"32": [
"crud_tenant_create_tenant",
"crud_tenant_get_tenant",
"crud_tenant_list_tenants",
"crud_tenant_py",
"crud_tenant_row_to_dict",
"crud_tenant_soft_delete_tenant",
"crud_tenant_tenant_no_exists",
"crud_tenant_total_pages",
"crud_tenant_update_tenant"
],
"33": [
"crud_site_create_site",
"crud_site_get_site",
"crud_site_list_sites",
"crud_site_py",
"crud_site_row_to_dict",
"crud_site_site_code_exists",
"crud_site_soft_delete_site",
"crud_site_total_pages",
"crud_site_update_site"
],
"34": [
"models_base_basemodel",
"models_base_basemodel_to_dict",
"models_base_get_active",
@@ -4513,7 +4517,7 @@
"models_base_softdeletemodel_soft_delete",
"models_base_tablename"
],
"33": [
"35": [
"core_order_status_compat_derive_legacy_status_from_three",
"core_order_status_compat_derive_three_status_from_legacy",
"core_order_status_compat_py",
@@ -4522,65 +4526,65 @@
"core_order_status_compat_threestatus",
"core_order_status_compat_to_decimal"
],
"34": [
"36": [
"basesettings",
"core_config_config",
"core_config_py",
"core_config_settings"
],
"35": [
"37": [
"core_database_auto_fill_create_dept_id",
"core_database_get_db",
"core_database_py",
"core_database_rationale_31"
],
"36": [
"38": [
"api_menu_get_menu_list",
"api_menu_py",
"api_menu_rationale_1"
],
"37": [
"39": [
"core_context_py",
"core_context_rationale_1"
],
"38": [
"40": [
"api_init_py",
"api_init_rationale_1"
],
"39": [
"41": [
"init_py"
],
"40": [
"42": [
"core_init_py"
],
"41": [
"43": [
"core_wechat_message_rationale_143"
],
"42": [
"44": [
"core_wechat_message_rationale_179"
],
"43": [
"45": [
"core_wechat_message_rationale_215"
],
"44": [
"46": [
"core_wechat_message_rationale_251"
],
"45": [
"47": [
"core_wechat_message_rationale_289"
],
"46": [
"48": [
"core_wechat_message_rationale_325"
],
"47": [
"49": [
"models_init_py"
],
"48": [
"50": [
"schemas_init_py"
],
"49": [
"51": [
"crud_init_py"
],
"50": [
"52": [
"ws_init_py"
]
},
@@ -4592,38 +4596,38 @@
"4": 0.01,
"5": 0.07,
"6": 0.02,
"7": 0.02,
"7": 0.03,
"8": 0.03,
"9": 0.03,
"10": 0.03,
"11": 0.34,
"12": 0.06,
"13": 0.07,
"14": 0.11,
"15": 0.12,
"16": 0.18,
"17": 0.21,
"18": 0.22,
"19": 0.22,
"20": 0.27,
"11": 0.05,
"12": 0.34,
"13": 0.06,
"14": 0.07,
"15": 0.11,
"16": 0.12,
"17": 0.2,
"18": 0.18,
"19": 0.27,
"20": 0.24,
"21": 0.24,
"22": 0.24,
"23": 0.24,
"24": 0.32,
"25": 0.24,
"26": 0.27,
"27": 0.29,
"28": 0.27,
"23": 0.32,
"24": 0.24,
"25": 0.27,
"26": 0.29,
"27": 0.27,
"28": 0.38,
"29": 0.38,
"30": 0.38,
"30": 0.31,
"31": 0.31,
"32": 0.29,
"33": 0.38,
"34": 0.5,
"35": 0.5,
"36": 0.67,
"37": 1.0,
"38": 1.0,
"32": 0.36,
"33": 0.36,
"34": 0.29,
"35": 0.38,
"36": 0.5,
"37": 0.5,
"38": 0.67,
"39": 1.0,
"40": 1.0,
"41": 1.0,
@@ -4635,7 +4639,9 @@
"47": 1.0,
"48": 1.0,
"49": 1.0,
"50": 1.0
"50": 1.0,
"51": 1.0,
"52": 1.0
},
"gods": [
{
+56 -16
View File
@@ -20858,7 +20858,7 @@
"label": "normalize_legacy_configure_to_batches()",
"file_type": "code",
"source_file": "crud/qc_inspection_batch.py",
"source_location": "L874"
"source_location": "L878"
},
{
"id": "crud_qc_inspection_batch_rationale_675",
@@ -20868,11 +20868,11 @@
"source_location": "L675"
},
{
"id": "crud_qc_inspection_batch_rationale_875",
"id": "crud_qc_inspection_batch_rationale_879",
"label": "\u5c06\u6241\u5e73 labItemIds \u914d\u7f6e\u8f6c\u4e3a\u5355\u6279\u6b21\u7ed3\u6784\u3002",
"file_type": "rationale",
"source_file": "crud/qc_inspection_batch.py",
"source_location": "L875"
"source_location": "L879"
},
{
"id": "crud_production_material_prep_py",
@@ -86106,7 +86106,7 @@
"relation": "contains",
"confidence": "EXTRACTED",
"source_file": "crud/qc_inspection_batch.py",
"source_location": "L874",
"source_location": "L878",
"weight": 1.0
},
{
@@ -86281,12 +86281,12 @@
"weight": 1.0
},
{
"source": "crud_qc_inspection_batch_rationale_875",
"source": "crud_qc_inspection_batch_rationale_879",
"target": "crud_qc_inspection_batch_normalize_legacy_configure_to_batches",
"relation": "rationale_for",
"confidence": "EXTRACTED",
"source_file": "crud/qc_inspection_batch.py",
"source_location": "L875",
"source_location": "L879",
"weight": 1.0
},
{
@@ -163020,7 +163020,7 @@
"relation": "uses",
"confidence": "INFERRED",
"source_file": "crud/qc_task.py",
"source_location": "L894",
"source_location": "L893",
"weight": 0.8
},
{
@@ -163029,7 +163029,7 @@
"relation": "uses",
"confidence": "INFERRED",
"source_file": "crud/qc_task.py",
"source_location": "L894",
"source_location": "L893",
"weight": 0.8
},
{
@@ -200500,7 +200500,7 @@
"weight": 0.8
},
{
"source": "crud_qc_inspection_batch_rationale_875",
"source": "crud_qc_inspection_batch_rationale_879",
"target": "models_models_bizqcbatchassignee",
"relation": "uses",
"confidence": "INFERRED",
@@ -200518,7 +200518,7 @@
"weight": 0.8
},
{
"source": "crud_qc_inspection_batch_rationale_875",
"source": "crud_qc_inspection_batch_rationale_879",
"target": "models_models_bizqctask",
"relation": "uses",
"confidence": "INFERRED",
@@ -200536,7 +200536,7 @@
"weight": 0.8
},
{
"source": "crud_qc_inspection_batch_rationale_875",
"source": "crud_qc_inspection_batch_rationale_879",
"target": "models_models_bizqcworkorder",
"relation": "uses",
"confidence": "INFERRED",
@@ -200554,7 +200554,7 @@
"weight": 0.8
},
{
"source": "crud_qc_inspection_batch_rationale_875",
"source": "crud_qc_inspection_batch_rationale_879",
"target": "models_models_bizqcworkorderinspectionbatch",
"relation": "uses",
"confidence": "INFERRED",
@@ -200572,7 +200572,7 @@
"weight": 0.8
},
{
"source": "crud_qc_inspection_batch_rationale_875",
"source": "crud_qc_inspection_batch_rationale_879",
"target": "models_models_bizqcworkorderlabitem",
"relation": "uses",
"confidence": "INFERRED",
@@ -200590,7 +200590,7 @@
"weight": 0.8
},
{
"source": "crud_qc_inspection_batch_rationale_875",
"source": "crud_qc_inspection_batch_rationale_879",
"target": "models_models_bizqcworkorderthirditem",
"relation": "uses",
"confidence": "INFERRED",
@@ -200608,7 +200608,7 @@
"weight": 0.8
},
{
"source": "crud_qc_inspection_batch_rationale_875",
"source": "crud_qc_inspection_batch_rationale_879",
"target": "models_models_sysuser",
"relation": "uses",
"confidence": "INFERRED",
@@ -222031,6 +222031,36 @@
"source_location": "L855",
"weight": 1.0
},
{
"source": "crud_qc_task_delete_qc_task",
"target": "crud_qc_work_order_get_work_order",
"relation": "calls",
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "crud/qc_task.py",
"source_location": "L912",
"weight": 1.0
},
{
"source": "crud_qc_task_delete_qc_task",
"target": "crud_base_crudbase_count",
"relation": "calls",
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "crud/qc_task.py",
"source_location": "L915",
"weight": 1.0
},
{
"source": "crud_qc_task_delete_qc_task",
"target": "crud_qc_work_order_try_complete_work_order",
"relation": "calls",
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "crud/qc_task.py",
"source_location": "L931",
"weight": 1.0
},
{
"source": "crud_process_route_list_routes",
"target": "crud_base_crudbase_count",
@@ -236641,6 +236671,16 @@
"source_location": "L868",
"weight": 1.0
},
{
"source": "crud_qc_inspection_batch_configure_work_order_batches",
"target": "crud_qc_work_order_try_complete_work_order",
"relation": "calls",
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "crud/qc_inspection_batch.py",
"source_location": "L873",
"weight": 1.0
},
{
"source": "crud_qc_inspection_batch_normalize_legacy_configure_to_batches",
"target": "crud_base_crudbase_get",
@@ -236648,7 +236688,7 @@
"confidence": "INFERRED",
"confidence_score": 0.8,
"source_file": "crud/qc_inspection_batch.py",
"source_location": "L876",
"source_location": "L880",
"weight": 1.0
},
{
+78 -68
View File
@@ -1,11 +1,11 @@
# Graph Report - app (2026-07-01)
# Graph Report - app (2026-07-02)
## Corpus Check
- Large corpus: 217 files · ~262,549 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
- Large corpus: 217 files · ~262,608 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
## Summary
- 4481 nodes · 24087 edges · 45 communities detected
- Extraction: 32% EXTRACTED · 68% INFERRED · 0% AMBIGUOUS · INFERRED: 16400 edges (avg confidence: 0.59)
- 4481 nodes · 24091 edges · 47 communities detected
- Extraction: 32% EXTRACTED · 68% INFERRED · 0% AMBIGUOUS · INFERRED: 16404 edges (avg confidence: 0.59)
- Token cost: 0 input · 0 output
## Community Hubs (Navigation)
@@ -48,12 +48,14 @@
- [[_COMMUNITY_Community 36|Community 36]]
- [[_COMMUNITY_Community 37|Community 37]]
- [[_COMMUNITY_Community 38|Community 38]]
- [[_COMMUNITY_Community 41|Community 41]]
- [[_COMMUNITY_Community 42|Community 42]]
- [[_COMMUNITY_Community 39|Community 39]]
- [[_COMMUNITY_Community 40|Community 40]]
- [[_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]]
## God Nodes (most connected - your core abstractions)
1. `success_response()` - 670 edges
@@ -83,7 +85,7 @@
### Community 0 - "Community 0"
Cohesion: 0.01
Nodes (869): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+861 more)
Nodes (867): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+859 more)
### Community 1 - "Community 1"
Cohesion: 0.01
@@ -91,7 +93,7 @@ Nodes (573): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictData
### Community 2 - "Community 2"
Cohesion: 0.01
Nodes (469): list_ethnics_for_select(), get_designer_data(), apply_data_scope(), _get_child_dept_ids(), get_user_dept_id(), _resolve_user_role_scopes(), generate_uuid(), ApiRequestLogCRUD (+461 more)
Nodes (467): list_ethnics_for_select(), get_designer_data(), apply_data_scope(), _get_child_dept_ids(), get_user_dept_id(), _resolve_user_role_scopes(), generate_uuid(), ApiRequestLogCRUD (+459 more)
### Community 3 - "Community 3"
Cohesion: 0.08
@@ -99,19 +101,19 @@ Nodes (385): 环境检测 — 检测项维护 + 登记管理 API, 保险公司
### Community 4 - "Community 4"
Cohesion: 0.01
Nodes (333): _normalize_date_bound(), _persist_protocol_sub_resources(), batch_delete_research_donations(), change_donation_status(), convert_from_storage(), convert_to_storage(), create_research_donation(), delete_research_donation() (+325 more)
Nodes (267): _normalize_date_bound(), _persist_protocol_sub_resources(), batch_delete_research_donations(), change_donation_status(), convert_from_storage(), convert_to_storage(), create_research_donation(), delete_research_donation() (+259 more)
### Community 5 - "Community 5"
Cohesion: 0.07
Nodes (262): CellSampleTypeCreateBody, CellSampleTypeUpdateBody, CollectionRegionCreateBody, CollectionRegionUpdateBody, CustomerCreateBody, CustomerUpdateBody, HospitalCreateBody, HospitalUpdateBody (+254 more)
Nodes (268): CellSampleTypeCreateBody, CellSampleTypeUpdateBody, CollectionRegionCreateBody, CollectionRegionUpdateBody, CustomerCreateBody, CustomerUpdateBody, HospitalCreateBody, HospitalUpdateBody (+260 more)
### Community 6 - "Community 6"
Cohesion: 0.02
Nodes (230): eq_unicode(), like_unicode(), MySQL 字符串比较/模糊匹配时统一排序规则,避免 Illegal mix of collations。, 跨表字符串等值比较(JOIN / WHERE)时统一为 utf8mb4_unicode_ci。, 将列显式设为 utf8mb4_unicode_ci。, unicode_ci(), build_void_type_label_map(), format_protocol_status_label() (+222 more)
### Community 7 - "Community 7"
Cohesion: 0.02
Nodes (199): _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), get_material_entity(), get_my_usages(), _is_enabled_status() (+191 more)
Cohesion: 0.03
Nodes (180): batch_discard(), batch_options(), _batch_row_to_dict(), batch_stock_in(), batch_stock_out(), _create_batch_and_usage(), delete_batch(), _discard_batch() (+172 more)
### Community 8 - "Community 8"
Cohesion: 0.03
@@ -126,175 +128,183 @@ Cohesion: 0.03
Nodes (73): _error_json(), lifespan(), 数据库异常:返回 JSON 并保留 CORS 头,避免浏览器只报跨域错误, 未捕获异常:统一 JSON 500,确保跨域场景下仍有 Access-Control-Allow-Origin, sqlalchemy_exception_handler(), unhandled_exception_handler(), BaseHTTPMiddleware, ApiCryptoError (+65 more)
### Community 11 - "Community 11"
Cohesion: 0.05
Nodes (83): _format_attachment_file_size(), urls_to_attachment_list(), get_map_by_reception_ids(), _attach_production_reception(), _can_edit_sample_reception(), get_check_results_for_reception(), _legacy_results_from_reception(), list_results_by_reception_ids() (+75 more)
### Community 12 - "Community 12"
Cohesion: 0.34
Nodes (73): BatchStockInBody, BatchStockInItem, BatchStockOutBody, BatchStockOutItem, ConsumableCreateBody, ConsumablePackCreateBody, ConsumablePackUpdateBody, ConsumableUpdateBody (+65 more)
### Community 12 - "Community 12"
Cohesion: 0.06
Nodes (62): complete_application(), create_basic_experiment_sale_schedules(), create_infusion_plan(), create_schedule(), _create_schedule_products(), _format_yyyy_mm_dd(), _generate_application_no(), get_application() (+54 more)
### Community 13 - "Community 13"
Cohesion: 0.06
Nodes (63): auto_create_payment(), complete_application(), create_basic_experiment_sale_schedules(), create_infusion_plan(), create_schedule(), _create_schedule_products(), _format_yyyy_mm_dd(), _generate_application_no() (+55 more)
### Community 14 - "Community 14"
Cohesion: 0.07
Nodes (58): aggregate_slot_stats_by_facility(), _apply_slot_select_base_filters(), _apply_slot_select_query_filters(), batch_create_slots(), _build_node_path_cache(), _build_slot_keyword_sql_filters(), collect_descendant_ids(), _collect_slot_host_node_ids() (+50 more)
### Community 14 - "Community 14"
### Community 15 - "Community 15"
Cohesion: 0.11
Nodes (35): 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() (+27 more)
### Community 15 - "Community 15"
### 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"
### Community 17 - "Community 17"
Cohesion: 0.2
Nodes (19): _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), get_material_entity(), get_my_usages(), _is_enabled_status() (+11 more)
### Community 18 - "Community 18"
Cohesion: 0.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 17 - "Community 17"
Cohesion: 0.21
Nodes (15): batch_generate_protocol_nos(), batch_issue_protocol_nos(), batch_revoke_protocol_nos(), create_protocol_no(), get_protocol_no(), list_protocol_nos(), _parse_issued_time(), protocol_no_exists() (+7 more)
### Community 18 - "Community 18"
Cohesion: 0.22
Nodes (14): batch_generate_sample_codes(), batch_issue_sample_codes(), batch_revoke_sample_codes(), create_sample_code(), get_sample_code(), list_sample_codes(), _parse_issued_time(), 样本编码池 CRUD(biz_sample_code) (+6 more)
### Community 19 - "Community 19"
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 20 - "Community 20"
Cohesion: 0.27
Nodes (12): create_equipment(), _dec(), equipment_code_exists(), equipment_is_referenced(), get_equipment(), list_equipments(), _norm_status(), _parse_date() (+4 more)
### Community 21 - "Community 21"
### Community 20 - "Community 20"
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 22 - "Community 22"
### Community 21 - "Community 21"
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 23 - "Community 23"
### Community 22 - "Community 22"
Cohesion: 0.24
Nodes (11): deduct_for_step(), _display_remark(), list_stock_logs(), _parse_receiver_purpose_from_remark(), 试剂变动记录 CRUD(biz_reagent_stock_log), 撤销步骤此前 step_save 扣减,便于重新填报。, 扣减试剂库存并生成变动记录。调用方控制事务,本函数不 commit。, _resolve_receiver_purpose() (+3 more)
### Community 24 - "Community 24"
### Community 23 - "Community 23"
Cohesion: 0.32
Nodes (11): create_env_detect_record(), _generate_record_no(), get_env_detect_record(), _join_csv(), list_env_detect_records(), _resolve_inspector_snapshots(), _resolve_item_snapshot(), _row_to_dict() (+3 more)
### Community 25 - "Community 25"
### Community 24 - "Community 24"
Cohesion: 0.24
Nodes (11): deduct_for_step(), _display_remark(), list_stock_logs(), _parse_receiver_purpose_from_remark(), 耗材变动记录 CRUD(biz_consumable_stock_log), 撤销步骤此前 step_save 扣减,便于重新填报。, 扣减耗材库存并生成变动记录。调用方控制事务,本函数不 commit。, _resolve_receiver_purpose() (+3 more)
### Community 26 - "Community 26"
### Community 25 - "Community 25"
Cohesion: 0.27
Nodes (11): _build_tree(), _cascade_soft_delete(), _collect_with_ancestors(), create_dept(), get_dept(), list_depts(), list_depts_tree(), 保留匹配节点及其全部上级,供关键词检索后仍能正确组树。 (+3 more)
### Community 27 - "Community 27"
### Community 26 - "Community 26"
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 28 - "Community 28"
### Community 27 - "Community 27"
Cohesion: 0.27
Nodes (8): create_customer(), get_customer(), id_card_taken(), list_customers(), 客户 CRUD(biz_customer), _row_to_dict(), soft_delete_customer(), update_customer()
### Community 29 - "Community 29"
### Community 28 - "Community 28"
Cohesion: 0.38
Nodes (9): create_check_item(), get_check_item(), item_code_exists(), list_active_check_items(), list_check_items(), _order_query(), _row_to_dict(), soft_delete_check_item() (+1 more)
### Community 30 - "Community 30"
### Community 29 - "Community 29"
Cohesion: 0.38
Nodes (9): create_env_detect_item(), get_env_detect_item(), item_code_exists(), list_active_env_detect_items(), list_env_detect_items(), _order_query(), _row_to_dict(), soft_delete_env_detect_item() (+1 more)
### Community 31 - "Community 31"
### Community 30 - "Community 30"
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 31 - "Community 31"
Cohesion: 0.31
Nodes (8): create_output_type(), get_output_type(), list_output_types(), 工艺产出物类型 CRUD(biz_output_type), _row_to_dict(), soft_delete_output_type(), type_code_exists(), update_output_type()
### Community 32 - "Community 32"
Cohesion: 0.36
Nodes (7): create_tenant(), get_tenant(), list_tenants(), _row_to_dict(), soft_delete_tenant(), tenant_no_exists(), update_tenant()
### Community 33 - "Community 33"
Cohesion: 0.36
Nodes (7): create_site(), get_site(), list_sites(), _row_to_dict(), site_code_exists(), soft_delete_site(), update_site()
### Community 34 - "Community 34"
Cohesion: 0.29
Nodes (2): BaseModel, SoftDeleteModel
### Community 33 - "Community 33"
### Community 35 - "Community 35"
Cohesion: 0.38
Nodes (6): derive_legacy_status_from_three(), derive_three_status_from_legacy(), 阶段A兼容:从旧 status 推导三字段。 约束:旧 status 本身混合了支付/配送/订单生命周期,因此只能尽力推断; 若业务侧已有更精确, 阶段A兼容:从三字段反推旧 status(用于旧前端/旧筛选参数兼容)。, ThreeStatus, _to_decimal()
### Community 34 - "Community 34"
### Community 36 - "Community 36"
Cohesion: 0.5
Nodes (3): BaseSettings, Config, Settings
### Community 35 - "Community 35"
### Community 37 - "Community 37"
Cohesion: 0.5
Nodes (2): _auto_fill_create_dept_id(), ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID
### Community 36 - "Community 36"
### Community 38 - "Community 38"
Cohesion: 0.67
Nodes (2): get_menu_list(), 运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,5 个一级菜单分组)
### Community 37 - "Community 37"
### Community 39 - "Community 39"
Cohesion: 1.0
Nodes (1): 请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传
### Community 38 - "Community 38"
### Community 40 - "Community 40"
Cohesion: 1.0
Nodes (1): API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)
### Community 41 - "Community 41"
### Community 43 - "Community 43"
Cohesion: 1.0
Nodes (1): 发送订单状态通知 Args: openid: 用户openid ord
### Community 42 - "Community 42"
### Community 44 - "Community 44"
Cohesion: 1.0
Nodes (1): 发送支付成功通知 Args: openid: 用户openid ord
### Community 43 - "Community 43"
### Community 45 - "Community 45"
Cohesion: 1.0
Nodes (1): 发送配送通知 Args: openid: 配送员openid task
### Community 44 - "Community 44"
### Community 46 - "Community 46"
Cohesion: 1.0
Nodes (1): 发送配送时效预警 Args: openid: 配送员openid ta
### Community 45 - "Community 45"
### Community 47 - "Community 47"
Cohesion: 1.0
Nodes (1): 发送退款结果通知 Args: openid: 用户openid ord
### Community 46 - "Community 46"
### Community 48 - "Community 48"
Cohesion: 1.0
Nodes (1): 发送催单通知给配送员 Args: deliver_openid: 配送员openid
## Knowledge Gaps
- **130 isolated node(s):** `刷新会话 TTL(refreshToken 续期;已登录用户每次 API 校验通过后滑动续期)`, `写入 refreshToken(用于 one-time 使用/吊销)`, `根据 token 获取当前用户(包含 Redis 会话校验;会话滑动续期)`, `登录凭据 RSA 解密(与前端 JSEncrypt PKCS#1 v1.5 兼容)。`, `加载 RSA 密钥对:优先环境变量,否则使用内置固定默认密钥。` (+125 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **Thin community `Community 32`** (8 nodes): `BaseModel`, `.to_dict()`, `get_active()`, `base.py`, `SoftDeleteModel`, `.restore()`, `.soft_delete()`, `__tablename__()`
- **Thin community `Community 34`** (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 35`** (4 nodes): `_auto_fill_create_dept_id()`, `get_db()`, `database.py`, `ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID`
- **Thin community `Community 37`** (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 36`** (3 nodes): `get_menu_list()`, `menu.py`, `运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,5 个一级菜单分组)`
- **Thin community `Community 38`** (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 37`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
- **Thin community `Community 39`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 38`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
- **Thin community `Community 40`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 41`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord`
- **Thin community `Community 43`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 42`** (1 nodes): `发送支付成功通知 Args: openid: 用户openid ord`
- **Thin community `Community 44`** (1 nodes): `发送支付成功通知 Args: openid: 用户openid ord`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 43`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task`
- **Thin community `Community 45`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 44`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta`
- **Thin community `Community 46`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 45`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord`
- **Thin community `Community 47`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 46`** (1 nodes): `发送催单通知给配送员 Args: deliver_openid: 配送员openid`
- **Thin community `Community 48`** (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 2`, `Community 3`, `Community 4`, `Community 5`, `Community 7`, `Community 8`, `Community 11`, `Community 17`, `Community 18`, `Community 23`, `Community 25`?**
- **Why does `SysUser` connect `Community 1` to `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 7`, `Community 8`, `Community 12`, `Community 22`, `Community 24`?**
_High betweenness centrality (0.108) - this node is a cross-community bridge._
- **Why does `generate_uuid()` connect `Community 2` to `Community 0`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 13`, `Community 14`, `Community 16`, `Community 17`, `Community 18`, `Community 19`, `Community 20`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`?**
- **Why does `generate_uuid()` connect `Community 2` to `Community 0`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 11`, `Community 14`, `Community 15`, `Community 17`, `Community 18`, `Community 19`, `Community 21`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 33`?**
_High betweenness centrality (0.059) - this node is a cross-community bridge._
- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 2`, `Community 36`, `Community 4`, `Community 8`, `Community 9`?**
- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 2`, `Community 4`, `Community 38`, `Community 8`, `Community 9`?**
_High betweenness centrality (0.047) - this node is a cross-community bridge._
- **Are the 737 inferred relationships involving `str` (e.g. with `unhandled_exception_handler()` and `get_current_user_by_token()`) actually correct?**
_`str` has 737 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">4481 nodes &middot; 24087 edges &middot; 51 communities</div>
<div id="stats">4481 nodes &middot; 24091 edges &middot; 53 communities</div>
</div>
<script>
const RAW_NODES = [{"id": "init_py", "label": "__init__.py", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 39, "community_name": "Community 39", "source_file": "__init__.py", "file_type": "code", "degree": 0}, {"id": "main_py", "label": "main.py", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "main.py", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 7}, {"id": "app_main_lifespan", "label": "lifespan()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_error_json", "label": "_error_json()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "_error_json()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 3}, {"id": "app_main_sqlalchemy_exception_handler", "label": "sqlalchemy_exception_handler()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "sqlalchemy_exception_handler()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_unhandled_exception_handler", "label": "unhandled_exception_handler()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "unhandled_exception_handler()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 5}, {"id": "app_main_mask_secret", "label": "_mask_secret()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "_mask_secret()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_root", "label": "root()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "root()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_health_check", "label": "health_check()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "health_check()", "community": 10, "community_name": "Community 10", "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": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "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": 10, "community_name": "Community 10", "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": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "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": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "rationale", "degree": 3}, {"id": "tasks_init_py", "label": "__init__.py", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 10, "community_name": "Community 10", "source_file": "tasks/__init__.py", "fiLine 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": 906}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 612}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 536}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 390}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 378}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 263}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 245}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 213}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 147}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 136}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 130}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 82}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 66}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 60}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 38}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 29}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 20}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 17}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 16}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 15}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 14}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 13}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 13}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 12}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 12}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 12}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 12}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 11}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 11}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 10}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 10}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 10}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 8}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 7}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 4}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 4}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 3}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 2}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 2}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 1}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 1}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 1}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 1}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 1}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 1}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 1}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 1}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 1}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 1}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 1}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 1}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 0}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 0}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 0}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 0}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 0}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 0}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 0}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 0}];
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": 41, "community_name": "Community 41", "source_file": "__init__.py", "file_type": "code", "degree": 0}, {"id": "main_py", "label": "main.py", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "main.py", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 7}, {"id": "app_main_lifespan", "label": "lifespan()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_error_json", "label": "_error_json()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "_error_json()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 3}, {"id": "app_main_sqlalchemy_exception_handler", "label": "sqlalchemy_exception_handler()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "sqlalchemy_exception_handler()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_unhandled_exception_handler", "label": "unhandled_exception_handler()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "unhandled_exception_handler()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 5}, {"id": "app_main_mask_secret", "label": "_mask_secret()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "_mask_secret()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_root", "label": "root()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "root()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_health_check", "label": "health_check()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "health_check()", "community": 10, "community_name": "Community 10", "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": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "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": 10, "community_name": "Community 10", "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": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "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": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "rationale", "degree": 3}, {"id": "tasks_init_py", "label": "__init__.py", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 10, "community_name": "Community 10", "source_file": "tasks/__init__.py", "fiLine 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": 904}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 612}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 530}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 390}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 304}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 270}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 245}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 193}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 147}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 136}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 130}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 94}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 82}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 67}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 60}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 38}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 29}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 20}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 20}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 14}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 13}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 13}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 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": 12}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 11}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 11}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 10}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 10}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 10}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 10}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 9}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 9}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 8}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 7}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 4}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 4}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 3}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 2}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 2}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 1}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 1}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 1}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 1}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 1}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 1}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 1}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 1}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 1}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 1}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 1}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 1}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 0}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 0}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 0}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 0}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 0}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 0}];
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
function esc(s) {
File diff suppressed because it is too large. Load diff
+11 -11
View File
@@ -27,13 +27,13 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/core/api_crypto_middleware.py": 1778581508.2309763,
"/Users/wuzilong/work/00code/zkxw/backend/app/core/wechat_message.py": 1778578258.0458734,
"/Users/wuzilong/work/00code/zkxw/backend/app/utils/sample_special.py": 1782890474.0661302,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/material.py": 1782894464.7972596,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/material.py": 1782894693.6389399,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py": 1782404882.9262497,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py": 1782379593.174925,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py": 1782893591.4107118,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/cleanroom_garment.py": 1781347080.6165943,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/__init__.py": 1781344070.5899634,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/research_donation.py": 1782893591.5829172,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/research_donation.py": 1782894734.5364213,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_material.py": 1781690312.7245836,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/base.py": 1778578258.0821667,
"/Users/wuzilong/work/00code/zkxw/backend/app/models/clinical_payment.py": 1779834956.9588954,
@@ -74,15 +74,15 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/outbound_handover.py": 1780455571.0749218,
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/category.py": 1778578258.0941947,
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/leave.py": 1778666088.7680702,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/storage_release_review.py": 1782893695.3771026,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/storage_release_review.py": 1782894735.4362206,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/equipment.py": 1782717312.9816003,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py": 1782893715.9240513,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py": 1782961153.677056,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/process_route.py": 1782717483.0699635,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py": 1782709076.5173395,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py": 1782379630.9640372,
"/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": 1782894546.3479118,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/material_stock_batch.py": 1782894693.7810533,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/post.py": 1779265648.38155,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_check_result.py": 1779255909.8554008,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py": 1782404955.550011,
@@ -96,10 +96,10 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/material_stock_log.py": 1779281903.0942652,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/tenant.py": 1779265611.0532296,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable.py": 1779512620.86979,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/material_usage.py": 1782894641.0272896,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/material_usage.py": 1782894693.7808309,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_usage.py": 1781513732.7796721,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sop_document.py": 1779265721.9928973,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py": 1782893738.0315711,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py": 1782894736.1688397,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/inbound_sample_special.py": 1782890475.769446,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_third_party_item.py": 1779265661.482352,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_production_reception.py": 1782722028.9202535,
@@ -135,14 +135,14 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/site.py": 1781401290.6845422,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/api_request_log.py": 1778578258.0614743,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/dict_data.py": 1782893595.9312406,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/research_donation.py": 1782893608.9059234,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/research_donation.py": 1782894734.7683048,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/ethnic.py": 1779265849.547566,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_formula.py": 1781344175.5871844,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_checkup.py": 1779935785.233911,
"/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": 1782893677.4257812,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py": 1782894735.0364947,
"/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": 1782376492.2365673,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_material.py": 1781612877.0137436,
@@ -153,7 +153,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_sms_notification.py": 1781063495.0317714,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py": 1782891223.4996026,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_pack.py": 1779265715.416005,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py": 1782569255.0879426,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py": 1782961156.502022,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_prep.py": 1781514953.3551314,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material.py": 1779284415.64655,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/collection_protocol_no.py": 1779882001.753651,
@@ -175,7 +175,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/api/storage_release_review.py": 1779526635.1455016,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/outbound_release_review.py": 1779968232.5759368,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/public.py": 1782122639.96012,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/material.py": 1782894532.006265,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/material.py": 1782894693.6582327,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py": 1782404982.2474263,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py": 1782889888.587752,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/market.py": 1781522283.6823432,
@@ -0,0 +1,42 @@
# 科研捐赠一键导入多样本增强 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 扩展捐赠协议单一键导入,支持单/多样本、运输方式映射、中文胎次与「点」时间格式。
**Architecture:** 解析逻辑集中在 `donation-standard-import-parse.ts`(输出 `sampleHints` + `transportType`);`DonationFormDialog.handleStandardImport` 按 hints 创建多样本行并应用运输;协议级采集时间取 hints 最早值。不改后端。
**Tech Stack:** Vue 3、TypeScript、现有 `chinese-datetime-parse` / `sample-production-reception-fields` 常量
**Spec:** `docs/superpowers/specs/2026-07-02-donation-import-multi-sample-design.md`
---
### Task 1: 中文数字与 datetime「点」
**Files:**
- Create: `web-admin/src/utils/chinese-numeral-parse.ts`
- Modify: `web-admin/src/utils/chinese-datetime-parse.ts`
- [ ] 新增 `parseChineseNumeral` / `parseBirthOrder`
- [ ] datetime 正则支持 `[时点::]`
### Task 2: 解析器多样本 + 运输 + 胎次
**Files:**
- Modify: `web-admin/src/utils/donation-standard-import-parse.ts`
- [ ] 扩展 `DonationStandardImportParsed`(`sampleHints`, `transportType`, `transportModeText`)
- [ ] 采集时间字段 pattern → hints;`resolveTransportType`;`matchSampleTypeByExactName`
### Task 3: 填充逻辑
**Files:**
- Modify: `web-admin/src/views/research-donation/list/DonationFormDialog.vue`
- [ ] 重构 `handleStandardImport`:多样本行、运输 kdys/ryxd、最早采集时间
### Task 4: 验证
- [ ] 用 Node 脚本或手工验证 §2.1 / §2.2 样例解析结果
- [ ] `./scripts/update-graph.sh frontend`
@@ -0,0 +1,293 @@
# 科研捐赠协议单 · 一键导入增强(单样本 / 多样本)
> 日期:2026-07-02
> 状态:已确认 / 已实现
> 关联模块:`web-admin` 捐赠协议单新增弹窗(`DonationFormDialog.vue`)
> 关联常量:`SAMPLE_TYPE_PERINATAL_HSC`、`SAMPLE_TYPE_UC_MSC`(`sample-production-reception-fields.ts`)
---
## 1. 背景与目标
### 1.1 业务诉求
科研捐赠协议单新增时,左侧「一键导入」支持粘贴客户提供的标准文本,解析后自动填充右侧表单。客户文本存在两种典型场景:
1. **单样本**:如围产期造血干细胞捐献,仅一种样本类型。
2. **多样本**:如同一产妇同时采集「围产期造血干细胞」与「脐带间充质干细胞」,文本中含多条不同样本的采集时间字段。
当前实现仅支持**首行标题推断一个样本类型**、**固定快递运输**、**胎次仅识别阿拉伯数字**、**时间格式不支持「点」**,无法正确导入多样本数据。
### 1.2 目标
1. 根据**采集时间字段名**推断应创建的样本类型与行数(1 行或 N 行)。
2. 正确映射运输方式:快递 → `kdys`,顺风车等 → `ryxd`(人员携带)。
3. 胎次支持中文数字(如「二胎」→ `2`)。
4. 中文时间支持 `18点05分` 格式(与 `12时17分` 等价)。
5. 保持「仅填充空白字段、不覆盖已有值」策略。
6. **不改后端表结构**;协议级 `sampleCollectTime` 取各样本采集时间中的**最早值**(已确认:选项 A)。
### 1.3 非目标(本期不做)
- 样本表增加独立 `sample_collect_time` 字段(方案 B,后续若产品要求再立项)。
- 配置化规则引擎(JSON/YAML 运营可改规则)。
- 细胞存储协议单一键导入(本模块无此功能)。
- 一键导入 UI 布局变更(仍为新增弹窗左侧粘贴区 + 右侧表单)。
---
## 2. 客户文本样例
### 2.1 单样本(捐献)
```
围产期干细胞(捐献)
产妇姓名:李会
新生儿性别:男
新生儿体重:3900g
新生儿评分: 9
分娩时间:2026年6月22日12时17分
造血干细胞采集时间:2026年6月22日12时18分
母血采集时间:未采集
分娩方式:顺产
胎次:3
采集医护:王天琪
采集医院:利辛县人民医院
运输方式:顺丰快递
销售人员:赵文静
采集医院:利辛县人民医院
```
**期望结果**:1 条样本(围产期造血干细胞);运输 `kdys` + 顺丰;胎次 `3`。
### 2.2 多样本(科研脐带)
```
围产期干细胞(科研脐带)
产妇姓名:陆玲
新生儿性别:男孩
新生儿体重:3700g
分娩时间:2026年3月14日 18点05分
造血干细胞样本采集时间:2026年3月14日 18点06分
脐带采集时间:2026年3月14日 18点08分
母血采集时间:2026年3月14日 19点40分
分娩方式:顺产
胎次:二胎
运输方式:顺风车
销售人员:张慧茹
采集医院:涡阳县中医院
```
**期望结果**:2 条样本(围产期造血干细胞、脐带间充质干细胞);协议级 `sampleCollectTime` = `2026-03-14 18:06`(最早);运输 `ryxd`,不填快递公司;胎次 `2`。
---
## 3. 业务规则
### 3.1 样本类型推断(优先级)
| 优先级 | 规则 | 说明 |
|--------|------|------|
| 1 | **采集时间字段** | 存在且值可解析 → 创建对应样本行(可多条) |
| 2 | **首行标题** | 无采集时间字段时,回退现有 `matchCellSampleType(header)` 逻辑 |
**采集时间字段 → 样本类型映射**:
| 字段名(含别名) | 目标类型名 | typeKey |
|------------------|------------|---------|
| `造血干细胞样本采集时间`、`造血干细胞采集时间`、`样本采集时间` | 围产期造血干细胞 | `hsc` |
| `脐带采集时间` | 脐带间充质干细胞 | `uc_msc` |
- 同一 typeKey 在文本中多次出现:以**首次有效时间**为准。
- 字段值为空或「未采集」等占位:不创建该样本行。
- 多样本场景下,**首行标题不参与**样本类型决定(避免「围产期干细胞(科研脐带)」歧义)。
### 3.2 协议级样本采集时间(已确认)
- 存储位置:`formData.sampleCollectTime` → `biz_research_donation_collection.sample_collect_time`。
- **多样本**:取所有已识别样本采集时间中的**最早时间**(minute 精度 `YYYY-MM-DD HH:mm`)。
- **单样本**:该样本采集时间写入协议级字段(与现逻辑一致)。
- 若协议级字段已有值:不覆盖(空白才填)。
### 3.3 运输方式映射
客户文本字段仍为 `运输方式`;解析结果区分 **模式** 与 **原始标签**:
| 客户文本特征 | `transportType` | 后续处理 |
|--------------|-----------------|----------|
| 含「快递」「顺丰」「圆通」「中通」「韵达」「EMS」等 | `kdys` | 匹配 `expressCompanyId`(现有 `matchExpressCompany`) |
| 含「顺风车」「顺丰车」(后者为笔误)、「自行」「人员携带」「自带」「自送」等 | `ryxd` | **不**填 `expressCompanyId`;可选后续人工填携带人 |
| 无法识别 | — | warning,不填运输 |
- 多样本时:各样本行复制**同一套**运输配置(客户数据中通常一致)。
- 仅当样本行 `transport.transportType` 为空时写入。
### 3.4 胎次
| 输入示例 | 解析结果 |
|----------|----------|
| `3` | `3` |
| `二胎`、`三胎` | `2`、`3` |
| `第二胎` | `2` |
| 无法解析 | warning,不填 |
实现:`parseBirthOrder(text)` — 先 `extractNumericPart`;若无阿拉伯数字,再解析中文数字(一~十及「N胎」模式)。
### 3.5 其他字段(保持 / 微调)
| 字段 | 规则 |
|------|------|
| 新生儿性别 | 扩展识别 `男孩`→`1`、`女孩`→`0` |
| 母血采集时间 | 「未采集」等 → 清空(已有) |
| 采集医院重复行 | 首次有效值为准(已有) |
| 母亲 / 医院 / 销售 | 远程匹配(已有) |
| 样本编码 | 每行样本 `assignDonationSampleCodeIfMissing`(已有) |
### 3.6 填充策略(不变)
- **仅填空**:目标字段为空才写入。
- **样本行**:若 `formData.samples` 已有同类型样本且 `sampleTypeId` 非空,不重复添加;若为空行可复用。
- 导入完成后:`ElMessage.success` 列出已填充项;`ElMessage.warning` 列出未匹配项。
---
## 4. 技术设计
### 4.1 解析层结构变更
**文件**:`web-admin/src/utils/donation-standard-import-parse.ts`
扩展 `DonationStandardImportParsed`(或新增子类型):
```typescript
export type DonationSampleImportHint = {
typeKey: 'hsc' | 'uc_msc'
typeName: string
collectTime?: string // 已解析为标准 datetime-minute
}
export type DonationStandardImportParsed = {
sampleTypeHeader: string
sampleHints: DonationSampleImportHint[] // 新增:0..N
transportModeText?: string // 原始运输方式文本
transportType?: 'kdys' | 'ryxd' // 新增:解析后的系统码
// ... 现有 common 字段保持不变
}
```
**新增 / 导出函数**:
| 函数 | 职责 |
|------|------|
| `parseBirthOrder(text)` | 阿拉伯 + 中文胎次 |
| `resolveTransportType(text)` | 运输文本 → `kdys` \| `ryxd` \| null |
| `matchSampleTypeByExactName(name, types)` | 按 `typeName` 精确匹配(优先于 segment 评分) |
**采集时间字段识别**:在 `KEY_ALIASES` 之外,对 key 做 pattern 匹配(支持「造血干细胞**样本**采集时间」等变体),命中后写入 `sampleHints` 而非单一 `sampleCollectTime`。
**回退**:`sampleHints.length === 0` 时,保留现有 `sampleCollectTime` + 首行 `matchCellSampleType` 行为。
### 4.2 时间解析增强
**文件**:`web-admin/src/utils/chinese-datetime-parse.ts`
- 正则扩展:`[时::点]` 均视为小时分隔符。
- 例:`2026年3月14日 18点06分` → `2026-03-14 18:06`。
**可选新文件**:`web-admin/src/utils/chinese-numeral-parse.ts`
- `parseChineseNumeral(text: string): number | null` — 支持「二」「二胎」「三胎」等;供 `parseBirthOrder` 调用。
### 4.3 填充层变更
**文件**:`web-admin/src/views/research-donation/list/DonationFormDialog.vue` — `handleStandardImport()`
```
1. parseDonationStandardImportText(text)
2. 并行:母亲 / 医院 / 销售 / 字典预加载(现有)
3. common 字段填空(性别、体重、评分、分娩时间、母血、分娩方式、胎次、医护…)
4. 样本行:
if sampleHints.length > 0:
for each hint:
matchSampleTypeByExactName(hint.typeName)
获取或创建对应样本行
assignDonationSampleCodeIfMissing
sampleCollectTime = min(hint.collectTime) // 最早
else:
现有单样本逻辑(首行 + 一行样本)
5. 运输:
if parsed.transportType === 'kdys': 匹配快递公司
if parsed.transportType === 'ryxd': transportType=ryxd,跳过 expressCompanyId
6. hydrateSampleLookupOptions + 消息反馈
```
### 4.4 数据模型(无变更)
| 实体 | 字段 | 说明 |
|------|------|------|
| `biz_research_donation_collection` | `sample_collect_time` | 协议级;多样本取最早采集时间 |
| `biz_research_donation_sample` | — | 无 per-sample 采集时间;本期不加 |
| `biz_research_donation_sample_transport` | `transport_type` | `kdys` / `ryxd` |
---
## 5. 测试
**新建**:`web-admin/src/utils/donation-standard-import-parse.test.ts`(或项目现有 vitest 路径)
| 用例 | 断言 |
|------|------|
| 单样本完整文本(§2.1) | 1 个 hint(hsc);transportType=kdys;birthOrder=3 |
| 多样本完整文本(§2.2) | 2 个 hint(hsc+uc_msc);最早时间 18:06;transportType=ryxd;birthOrder=2 |
| 胎次「二胎」「3」 | 2、3 |
| 时间「18点06分」「12时18分」 | 等价解析 |
| 仅首行无采集时间 | sampleHints 空,回退首行匹配 |
| 运输「顺风车」「顺丰快递」 | ryxd / kdys |
**手工验收**(`/#/market/research-donation/audit` 或 list 页新增):
1. 粘贴 §2.1 → 1 样本、顺丰、胎次 3。
2. 粘贴 §2.2 → 2 样本、人员携带、协议采集时间 18:06、胎次 2。
3. 先手动填部分字段再导入 → 已填字段不被覆盖。
---
## 6. 改动文件清单
| 文件 | 改动类型 |
|------|----------|
| `web-admin/src/utils/donation-standard-import-parse.ts` | 扩展解析:多样本 hints、运输、胎次 |
| `web-admin/src/utils/chinese-datetime-parse.ts` | 支持「点」 |
| `web-admin/src/utils/chinese-numeral-parse.ts` | 新建(可选,也可内联于 parse 文件) |
| `web-admin/src/views/research-donation/list/DonationFormDialog.vue` | `handleStandardImport` 多样本 + 运输 |
| `web-admin/src/utils/donation-standard-import-parse.test.ts` | 新建单元测试 |
**不改**:`backend/`、`docs/sql/`、OpenSpec(除非评审要求补充 ui-conventions 条目)。
---
## 7. 风险与限制
1. **协议级采集时间**:多样本各时间不同,列表/采集信息页仅展示一个时间;业务接受「最早时间」代表协议(已确认)。
2. **运输携带人**:`ryxd` 模式下客户文本通常不含携带人姓名;导入后可能需人工补全。
3. **未知样本类型**:若未来出现第三种采集时间字段,需扩展 `SAMPLE_COLLECT_TIME_RULES`;本期仅 hsc / uc_msc。
---
## 8. 验收标准
- [ ] §2.1 单样本文本一键导入后,样本 Tab 有 1 行「围产期造血干细胞」,运输为快递运输 + 顺丰。
- [ ] §2.2 多样本文本一键导入后,样本 Tab 有 2 行(造血 + 脐带),运输为人员携带,协议采集时间为 18:06。
- [ ] 胎次「二胎」解析为 2;「3」解析为 3。
- [ ] `18点06分` 时间正确解析。
- [ ] 已有字段不被覆盖;单元测试通过。
---
## 9. 决策记录
| 日期 | 决策 | 理由 |
|------|------|------|
| 2026-07-02 | 方案 A:纯前端增强,不改表 | 最小改动、与现架构一致 |
| 2026-07-02 | 协议级 `sampleCollectTime` 取**最早**采集时间 | 用户确认选项 A |
| 2026-07-02 | 多样本以采集时间字段为准,首行标题仅作回退 | 避免标题歧义 |
@@ -0,0 +1,287 @@
# 采集协议单 · 一键导入标准信息
> 日期:2026-07-02
> 状态:已实现
> 关联:`ProtocolFormDialog.vue`、捐赠单 `DonationFormDialog.vue` + `donation-standard-import-parse.ts`
> 参考样例:客户提供的标准信息1(单样本趸交)、标准信息2(双存部分缴费)
---
## 1. 背景与目标
采集协议单**新增**弹窗需支持「一键导入」:粘贴客户标准文本,解析后填充各 Tab 字段。交互与捐赠协议单一致(左侧粘贴区 + 右侧基本信息,仅新增模式展示)。
### 1.1 已确认业务规则
| 规则 | 决策 |
|------|------|
| **金额** | **以标准信息中的金额为准**(合同金额、转账金额等),不以样本优惠价自动合计覆盖导入结果 |
| **缴费方式** | 文本为「微信 / 支付宝 / 银行卡 / 现金」等时,**默认趸交 `dj`**;仅当明确出现「分期」时设为 `fq` |
| **转账方式** | 「转账方式:微信」或「缴费方式:微信」(非分期语义)→ 映射字典 `zzfs`(如微信→`wxzz`) |
| **导入策略** | 点击一键导入时**先清空**可覆盖字段,再按当前粘贴内容填充(与捐赠单一致) |
| **协议级采集时间** | 多样本时取各样本采集时间中的**最早值** |
### 1.2 非目标
- 后端新 API(纯前端解析 + 既有 lookup 接口)
- 编辑模式下一键导入
- 附件、协议号自动生成规则变更
---
## 2. 标准文本格式
### 2.1 标准信息1(单样本 · 趸交 · 两笔转账)
```
围产期干细胞储存
造血干细胞:ZKZX34000870
产妇姓名:刘晓艳
…
缴费方式:趸交
转账方式:微信
合同金额:22880元
转账金额:22880元
转账时间:2026年6月17日13时09分05秒2000元,6月18日15:50:12付20880元
孕妇电话:13966850002
运输方式:顺丰快递
预计送达时间:
```
### 2.2 标准信息2(双存 · 部分缴费 · 人员携带)
```
围产期干细胞储存(双存)
造血干细胞:ZKZX34000922
脐带间充质干细胞:ZKQD34000839
…
缴费方式:微信
合同金额:37000元
转账金额:2000元
转账时间:2026年3月10日11:34:40
运输方式:露露帮助到医院取样本送到实验室
备注:剩余尾款两天内交清
```
---
## 3. 字段映射
### 3.1 公共字段(与捐赠类似)
| 客户 key / 模式 | 目标字段 | 备注 |
|-----------------|----------|------|
| 产妇姓名 | 母亲姓名 / 关联客户 | 远程匹配 |
| 孕妇电话 | `motherPhone` | 去空格 |
| 新生儿性别 | `newbornSex` | 男孩/女孩 |
| 新生儿体重 | `newbornWeightGram` | |
| 新生儿评分 | `apgar1min` | |
| 分娩时间 | `newbornDeliveryTime` | |
| 母血采集时间 | `maternalBloodCollectTime` | 未采集→清空 |
| 分娩方式 | `deliveryMode` | 含「刨宫产」→ `pgc` |
| 胎次 | `birthOrder` | 中文数字 |
| 采集医护 | `medicalStaff` | |
| 采集医院 | `regionId` + `hospitalId` | |
| 销售人员 | `salesUserId` | **仅销售,不改采集专员** |
| 备注 | `remark` | |
| 运输方式 | 样本 `transport` | 见 §3.4 |
| 预计送达时间 | `transport.etaTime` | 空则跳过 |
### 3.2 样本:编码行 + 采集时间行
**编码行**(优先识别样本行):
```
造血干细胞:ZKZX34000870
脐带间充质干细胞:ZKQD34000839
```
| 类型关键词 | 系统类型名 | typeKey |
|------------|------------|---------|
| 造血干细胞(非间充质) | 围产期造血干细胞 | `hsc` |
| 脐带间充质干细胞 | 脐带间充质干细胞 | `uc_msc` |
**采集时间行**(与编码行按 typeKey 合并):
| 字段名(含别名) | typeKey |
|------------------|---------|
| 造血干细胞采集时间、造血干细胞样本采集时间 | `hsc` |
| 脐带间充质干细胞采集时间、脐带采集时间 | `uc_msc` |
- 首行标题(围产期干细胞储存…)仅作**无编码/无时间行**时的兜底类型匹配。
- 协议级 `sampleCollectTime` = 各 hint 已解析 `collectTime` 的**最早值**。
**样本编码**:按文本中的 `ZK…` 编码远程查 `fetchSampleCodeList`,写入 `sampleCodeId` + `sampleCode`;找不到则 warning。
**样本价格**:匹配样本类型后带出 `storagePrice` 作为原价/优惠价初始值;**合同金额仍以文本「合同金额」为准**(§3.3)。
### 3.3 缴费(金额以标准信息为准)
| 客户字段 | 解析 | 写入 |
|----------|------|------|
| 缴费方式:趸交 | `payMode = dj` | 缴费主表 |
| 缴费方式:分期 | `payMode = fq` | 缴费主表 + 分期默认参数 |
| 缴费方式:微信/支付宝/… | **`payMode = dj`**(非分期) | 同时作为转账方式 hint |
| 转账方式:微信 | `transferType` | 字典匹配 `zzfs` |
| 合同金额:22880元 | `22880` | **`formData.contractAmount`**(权威,覆盖自动合计) |
| 转账金额 | 单值或明细金额 | 缴费明细 `transferAmount` |
| 转账时间 | 见 §3.3.1 | 缴费明细 `transferTime` |
**趸交 + 部分已转**(标准2):`payMode=dj`,合同 37000,明细 1 条 transfer 2000;`syncPaymentDueAmounts()` 计算待缴应缴额。
**趸交 + 多笔转账**(标准1):解析 2 条明细(2000 + 20880),转账方式均为微信;合计应等于合同金额,不等则 warning。
#### 3.3.1 转账时间复杂格式
支持拆段,例如:
`2026年6月17日13时09分05秒2000元,6月18日15:50:12付20880元`
→ 两条 `{ transferTime, transferAmount }`。
单段格式:`2026年3月10日11:34:40` + 全局「转账金额」字段。
### 3.4 运输
复用 `resolveTransportType`(含顺丰快递→`kdys`、顺丰车→`ryxd`、顺风车/露露帮助…→`ryxd`)。
- `kdys`:匹配快递公司,填 `expressCompanyId`
- `ryxd`:不填快递;可选从文本提取人名(如「露露」)→ `carrierName`
---
## 4. 技术设计
### 4.1 新建解析器
**文件**:`web-admin/src/utils/protocol-standard-import-parse.ts`
```typescript
export type ProtocolSampleImportHint = {
typeKey: 'hsc' | 'uc_msc'
typeName: string
sampleCode?: string
collectTime?: string
}
export type ProtocolPaymentTransferHint = {
transferAmount: number
transferTime: string // YYYY-MM-DD HH:mm:ss
}
export type ProtocolStandardImportParsed = {
sampleTypeHeader: string
sampleHints: ProtocolSampleImportHint[]
motherName?: string
motherPhone?: string
newbornSex?: '1' | '0'
newbornWeightGram?: number | null
apgarScore?: number | null
newbornDeliveryTime?: string
sampleCollectTime?: string
maternalBloodCollectTime?: string
maternalBloodExplicitEmpty?: boolean
deliveryMode?: string
birthOrder?: number | null
medicalStaff?: string
hospitalName?: string
salesUserName?: string
payMode?: 'dj' | 'fq'
contractAmount?: number | null
transferTypeLabel?: string // 原始「微信」等,填充时查字典
paymentTransfers: ProtocolPaymentTransferHint[]
transportModeText?: string
transportType?: 'kdys' | 'ryxd'
etaTime?: string
remark?: string
}
```
**复用**(import from 已有模块):
- `parseChineseDatetimeText` / `formatDatetimeToMinute`
- `parseBirthOrder`
- `resolveTransportType`
- `matchSampleTypeByExactName` / `matchCellSampleType`
- `isBlankString` / `extractNumericPart`
**新增**:
- `parsePayMode(text)`:`分期`→`fq`,否则 `dj`(趸交、微信、空均默认 dj)
- `parseSampleCodeLine(key, value)`:类型名 + ZK 编码
- `parsePaymentTransferSegments(text)`:多笔转账时间行
- `resolveTransferTypeCode(label, dictOptions)`:label→`wxzz` 等
### 4.2 UI
**文件**:`ProtocolFormDialog.vue`
- 新增模式 Tab「基本信息」:左侧 `section-card--import`(与捐赠同布局类名,见 `DonationFormDialog` SCSS)
- `standardImportText` + `handleStandardImport`
- `clearFormBeforeStandardImport()`:清空导入覆盖范围(含 samples、paymentDetails、缴费主表金额字段、客户/采集字段;**保留**协议状态、登记日期、采集专员、附件)
- `handleStandardImport` 流程见 §4.3
### 4.3 填充流程
```
1. parseProtocolStandardImportText(text)
2. clearFormBeforeStandardImport()
3. 预加载:样本类型、站点、快递、转账字典 zzfs
4. 并行:母亲(by name/phone)、医院、销售用户
5. 写入采集/客户/新生儿字段
6. 按 sampleHints 创建样本行(类型+编码 lookup+运输)
7. formData.contractAmount = parsed.contractAmount(来自标准信息)
8. formData.payMode = parsed.payMode ?? 'dj'
9. 重建 paymentDetails from paymentTransfers + transferType
10. syncFormSamplesAfterImport()
11. syncPaymentDueAmounts()(不调用 syncContractAmount 覆盖合同额)
12. 若样本价合计与合同金额差异 > 0.01 → warning(提示人工核对样本优惠价)
13. ElMessage success/warning
```
### 4.4 与捐赠差异摘要
| 项 | 捐赠 | 采集协议 |
|----|------|----------|
| 样本编码 | 自动生成 | 文本指定 + API 匹配 |
| 合同金额 | 无 | **标准信息为准** |
| 缴费 | 无 | 主表 + 明细 |
| 销售导入 | 同时写采集专员 | **仅 salesUserId** |
| 孕妇电话 | 无 | 有 |
---
## 5. 测试用例
| 用例 | 断言 |
|------|------|
| 标准信息1 全文 | 1 样本 ZKZX…;contract=22880;payMode=dj;2 条明细 2000+20880;运输 kdys |
| 标准信息2 全文 | 2 样本;contract=37000;payMode=dj;1 明细 2000;运输 ryxd;remark 有值 |
| 缴费方式:微信 | payMode=dj,transferType 匹配微信 |
| 缴费方式:分期 | payMode=fq |
| 刨宫产 / 头胎 | deliveryMode=pgc,birthOrder=1 |
| 重复点击导入 | 旧数据清空,仅保留新粘贴结果 |
---
## 6. 改动文件清单
| 文件 | 改动 |
|------|------|
| `utils/protocol-standard-import-parse.ts` | 新建 |
| `views/cell-storage/protocol/ProtocolFormDialog.vue` | UI + 导入逻辑 + SCSS |
| `utils/donation-standard-import-parse.ts` | 可选:导出共享函数,避免重复 |
| `utils/chinese-datetime-parse.ts` | 如需支持「付20880元」段内金额,扩展解析 |
**不改**:后端、DB。
---
## 7. 决策记录
| 日期 | 决策 |
|------|------|
| 2026-07-02 | 金额以标准信息为准,不用样本价自动合计覆盖合同金额 |
| 2026-07-02 | 缴费方式「微信」等默认趸交,仅明确「分期」时分期 |
| 2026-07-02 | 协议级 sampleCollectTime 取最早采集时间 |
| 2026-07-02 | 导入前清空可覆盖字段 |
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+110 -106
View File
@@ -1,11 +1,11 @@
# Graph Report - src (2026-07-01)
# Graph Report - src (2026-07-02)
## Corpus Check
- Large corpus: 845 files · ~556,744 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
- Large corpus: 847 files · ~560,353 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
## Summary
- 2767 nodes · 3805 edges · 61 communities detected
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 848 edges (avg confidence: 0.8)
- 2811 nodes · 3906 edges · 61 communities detected
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 866 edges (avg confidence: 0.8)
- Token cost: 0 input · 0 output
## Community Hubs (Navigation)
@@ -48,7 +48,7 @@
- [[_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 44|Community 44]]
@@ -73,198 +73,198 @@
## God Nodes (most connected - your core abstractions)
1. `get()` - 278 edges
2. `push()` - 70 edges
2. `push()` - 74 edges
3. `WebSocketClient` - 26 edges
4. `emit()` - 21 edges
5. `set()` - 19 edges
6. `handleDynamicRoutes()` - 18 edges
7. `MenuProcessor` - 16 edges
8. `scopeQuery()` - 15 edges
9. `TableCache` - 14 edges
10. `withFullscreenLoading()` - 13 edges
7. `parseProtocolStandardImportText()` - 17 edges
8. `MenuProcessor` - 16 edges
9. `scopeQuery()` - 15 edges
10. `TableCache` - 14 edges
## Surprising Connections (you probably didn't know these)
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
views/basic-info/customer/index.vue → utils/fullscreen-loading.ts
- `buildInboundMetaFields()` --calls--> `push()` [INFERRED]
utils/production-work-order-card-meta.ts → views/operations/storage-facility/index.vue
- `dash()` --calls--> `formatDisplayOrDash()` [INFERRED]
components/business/clinical-schedule-payment-detail/index.vue → utils/datetime-display.ts
- `resolveBatchSectionTasks()` --calls--> `set()` [INFERRED]
utils/qc-inspection-batch.ts → views/production/process/ProcessRouteTab.vue
- `fmtMoney()` --calls--> `formatMoneyDisplay()` [INFERRED]
components/business/clinical-schedule-payment-detail/index.vue → utils/money-format.ts
- `defaultInstallmentRatios()` --calls--> `push()` [INFERRED]
utils/protocol-payment-installment.ts → views/operations/storage-facility/index.vue
- `calcUnpaidAmountsByRatios()` --calls--> `push()` [INFERRED]
utils/protocol-payment-installment.ts → views/operations/storage-facility/index.vue
- `handleAttachmentDownload()` --calls--> `downloadAttachmentFile()` [INFERRED]
components/business/infusion-schedule-outbound-chain-view/index.vue → utils/download-attachment.ts
## Communities
### Community 0 - "Community 0"
Cohesion: 0.01
Nodes (152): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchChannelAccount() (+144 more)
Nodes (156): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchChannelAccount() (+148 more)
### Community 1 - "Community 1"
Cohesion: 0.02
Nodes (73): fetchUploadAttachment(), FireworkSystem, collectIds(), handleReportUpload(), handleReportUpload(), walk(), buildTemporaryViewSections(), if() (+65 more)
Nodes (119): fetchUploadAttachment(), fetchMyProductionTasks(), fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), handleReportUpload(), handleReportUpload(), walk() (+111 more)
### Community 2 - "Community 2"
Cohesion: 0.03
Nodes (83): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchPilotCheckupDetail(), markPilotCheckupChecked(), savePilotCheckup(), savePilotCheckupActualItems() (+75 more)
Cohesion: 0.02
Nodes (92): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionList(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchPilotCheckupDetail(), fetchPilotCheckupList(), markPilotCheckupChecked() (+84 more)
### Community 3 - "Community 3"
Cohesion: 0.03
Nodes (60): fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionProjects(), fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchCreateCheckupInstitutionProject(), fetchUpdateCheckupInstitution(), fetchUpdateCheckupInstitutionInvoice(), fetchUpdateCheckupInstitutionProject() (+52 more)
Nodes (66): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList(), fetchCreateProtocolInvoiceRequest(), fetchInvoiceEligiblePayments(), fetchPaymentDetailList() (+58 more)
### Community 4 - "Community 4"
Cohesion: 0.03
Nodes (34): fetchGetMenuList(), ComponentLoader, IframeRouteManager, MenuProcessor, RoutePermissionValidator, RouteRegistry, RouteTransformer, useAppMode() (+26 more)
Nodes (33): fetchGetMenuList(), ComponentLoader, IframeRouteManager, MenuProcessor, RouteRegistry, RouteTransformer, useAppMode(), useAuth() (+25 more)
### Community 5 - "Community 5"
Cohesion: 0.03
Nodes (58): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList(), fetchCreateProtocolInvoiceRequest(), fetchInvoiceEligiblePayments(), fetchPaymentDetailList() (+50 more)
### Community 6 - "Community 6"
Cohesion: 0.02
Nodes (28): fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllConsumableStockLogs(), fetchAllEquipments(), fetchAllOutputTypes(), fetchAllProcessCategories(), fetchAllProcesses(), fetchAllReagents() (+20 more)
### Community 7 - "Community 7"
### Community 6 - "Community 6"
Cohesion: 0.04
Nodes (50): fetchMyProductionTasks(), fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), shouldApplyTriggerSourceFilter(), buildMineTableRows(), buildPresetTasksMap(), buildWorkOrderFromTasks() (+42 more)
Nodes (50): fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionProjects(), fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchCreateCheckupInstitutionProject(), fetchUpdateCheckupInstitution(), fetchUpdateCheckupInstitutionInvoice(), fetchUpdateCheckupInstitutionProject() (+42 more)
### Community 7 - "Community 7"
Cohesion: 0.05
Nodes (42): buildBaseFields(), buildFeeSection(), buildInboundBasicSection(), buildInboundCellStorageProductionViewSections(), buildInboundResearchDonationProductionViewSections(), buildOutboundBasicExperimentProductionViewSections(), buildOutboundClinicalProductionViewSections(), buildOutboundDetail() (+34 more)
### Community 8 - "Community 8"
Cohesion: 0.03
Nodes (26): handleBlur(), handleFocus(), handleInput(), fetchQcMaterialBatchList(), fetchQcMaterialBatchOptions(), fetchQcMaterialList(), fetchQcMaterialOptions(), fetchUpdateQcMaterialBatch() (+18 more)
Cohesion: 0.04
Nodes (35): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), if(), walk() (+27 more)
### Community 9 - "Community 9"
Cohesion: 0.04
Nodes (45): buildBaseFields(), buildInboundBasicSection(), buildInboundCellStorageProductionViewSections(), buildInboundResearchDonationProductionViewSections(), buildOutboundBasicExperimentProductionViewSections(), buildOutboundClinicalProductionViewSections(), buildOutboundDetail(), buildOutboundPilotProductionViewSections() (+37 more)
Nodes (14): fetchProductionWorkOrderQcInfo(), dash(), fmtMoney(), auditorDisplay(), dash(), ensureUnitsInOptions(), expressName(), formatYm() (+6 more)
### Community 10 - "Community 10"
Cohesion: 0.04
Nodes (40): fetchRoleOptions(), buildInboundBasicSection(), buildInboundCellStorageViewSections(), buildInboundResearchDonationViewSections(), buildReceptionSection(), buildTransportSection(), resolveInboundProtocolStatus(), appendTaskResultSections() (+32 more)
Cohesion: 0.05
Nodes (26): handleBlur(), handleFocus(), handleInput(), fetchClinicalRefundConfirmed(), formatAmount(), buildConfirmedParams(), buildPendingParams(), formatAmount() (+18 more)
### Community 11 - "Community 11"
Cohesion: 0.05
Nodes (40): fetchCheckupInstitutionList(), fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchPilotCheckupList(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), handleAdd() (+32 more)
Nodes (29): fetchEthnicList(), formatNowDatetime(), applyDonationBundleToForm(), createEmptyTransport(), ensureEthnicOptionInList(), handleOpenForAdd(), if(), loadEthnicOptions() (+21 more)
### Community 12 - "Community 12"
Cohesion: 0.04
Nodes (34): fetchEthnicList(), applyDonationBundleToForm(), createEmptyTransport(), ensureEthnicOptionInList(), handleOpenForAdd(), loadEthnicOptions(), normalizeSampleRow(), resetForm() (+26 more)
Cohesion: 0.05
Nodes (26): fetchUserList(), fetchProductionReceptionBySampleCode(), fetchProductionReceptionSubmit(), fetchProductionReceptionUpdate(), formatHandoverUserLabel(), formatNowDatetime(), fullFileUrl(), handlePreviewAttachment() (+18 more)
### Community 13 - "Community 13"
Cohesion: 0.05
Nodes (34): fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed(), fetchClinicalRefundPending(), fetchOrderAdjusts(), fetchOrderDetail() (+26 more)
Cohesion: 0.04
Nodes (21): fetchAvailableMaterialBatches(), fetchMyProductionMaterialConsumptions(), fetchMyProductionMaterialUsageList(), fetchProductionMaterialBatchList(), fetchProductionMaterialBatchOptions(), fetchProductionMaterialConsumptions(), fetchProductionMaterialFormula(), fetchProductionMaterialLinkedStepUsages() (+13 more)
### Community 14 - "Community 14"
Cohesion: 0.06
Nodes (37): fetchUserList(), fetchAddTaskStep(), fetchCopyTaskStep(), fetchDeleteTaskStep(), fetchDispatchProductionTaskSteps(), fetchForwardProductionTask(), fetchProductionTaskDetail(), fetchProductionTaskEditorInit() (+29 more)
Cohesion: 0.08
Nodes (37): formatDatetimeToMinute(), handleChineseDatetimePaste(), parseChineseDatetimeText(), parseBirthOrder(), parseChineseNumeral(), addSampleHint(), earliestCollectTime(), isMaternalBloodEmpty() (+29 more)
### Community 15 - "Community 15"
Cohesion: 0.09
Nodes (41): applyFqParamsChange(), buildFqAmounts(), countByStatus(), evaluateFqParamsChange(), formatMoneySummary(), generateInitialFqDetails(), getPaidInstallmentRows(), isSameFqParams() (+33 more)
### Community 16 - "Community 16"
Cohesion: 0.09
Nodes (36): attachmentFullUrl(), dash(), handleAttachmentDownload(), handleAttachmentPreview(), buildPaymentFlowSteps(), dash(), formatAmount(), hasFinanceReceipt() (+28 more)
### Community 17 - "Community 17"
Cohesion: 0.06
Nodes (22): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchRoleOptions(), fetchUpdateMenu(), collectIds(), postorder(), preorder() (+14 more)
### Community 18 - "Community 18"
Cohesion: 0.1
Nodes (2): WebSocketClient, TableCache
### Community 17 - "Community 17"
Cohesion: 0.08
Nodes (32): toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes() (+24 more)
### Community 18 - "Community 18"
Cohesion: 0.07
Nodes (24): fetchMineProductionWorkOrderTabStepCounts(), fetchMineProductionWorkOrderTabStepCountsDeduped(), fetchProductionWorkOrderCellProductOptions(), fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList(), fetchProductionWorkOrderQcDispatchOptions(), fetchProductionWorkOrderQcInfo(), fetchProductionWorkOrderTabStepCounts() (+16 more)
### Community 19 - "Community 19"
Cohesion: 0.09
Nodes (8): getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager, validateStorageData()
Cohesion: 0.06
Nodes (20): fetchQcMaterialBatchList(), fetchQcMaterialBatchOptions(), fetchQcMaterialList(), fetchQcMaterialOptions(), fetchUpdateQcMaterialBatch(), fetchMarkQcMaterialUsageFullyUsed(), financeAttachmentsToUrlString(), ensureTabMounted() (+12 more)
### Community 20 - "Community 20"
Cohesion: 0.08
Nodes (18): fetchProductionReceptionBySampleCode(), fetchProductionReceptionSubmit(), fetchProductionReceptionUpdate(), onUserSelectVisible(), remoteSearchUsers(), buildPayload(), ensureDefaultHandler(), initDialog() (+10 more)
Nodes (33): fetchRefreshToken(), toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url() (+25 more)
### Community 21 - "Community 21"
Cohesion: 0.07
Nodes (16): fetchDeleteMaterialBatch(), fetchMaterialBatchList(), fetchMaterialBatchOptions(), fetchMaterialList(), fetchMaterialOptions(), fetchUpdateMaterialBatch(), fetchMaterialUsageList(), fetchMyMaterialUsageList() (+8 more)
Cohesion: 0.09
Nodes (8): getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager, validateStorageData()
### Community 22 - "Community 22"
Cohesion: 0.08
Nodes (18): createEmptySnapshots(), normalizeConfiguredReagents(), normalizeConsumables(), normalizeDataCollections(), normalizeReagents(), normalizeStepOutputs(), serializeAttachments(), serializeEquipmentIds() (+10 more)
Cohesion: 0.09
Nodes (28): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), handleAdd(), handleDelete(), handleDropdownCommand() (+20 more)
### Community 23 - "Community 23"
Cohesion: 0.07
Nodes (11): gateWorkOrder(), sampleTabStatusLabel(), sampleTabStatusTagType(), sampleTypeLabel(), workOrderStatusTagType(), canEditInboundSampleSpecialMark(), resolveInboundSampleSpecialMarkTarget(), resolveInboundSampleSpecialMarkTargetFromRow() (+3 more)
Nodes (19): fetchDeleteMaterialBatch(), fetchMaterialBatchList(), fetchMaterialBatchOptions(), fetchMaterialList(), fetchMaterialOptions(), fetchUpdateMaterialBatch(), fetchMaterialUsageList(), fetchMyMaterialUsageList() (+11 more)
### Community 24 - "Community 24"
Cohesion: 0.11
Nodes (21): fetchGetMenuCodes(), fetchGetUserInfo(), fetchLogin(), fetchRefreshToken(), fetchUpdateProfile(), fetchUploadProfileAvatar(), fetchUserInfo(), buildWebEncryptedLoginBody() (+13 more)
Cohesion: 0.09
Nodes (28): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), clearTableSelection(), handleBatchComplete(), handleBatchStart() (+20 more)
### Community 25 - "Community 25"
Cohesion: 0.11
Nodes (24): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), handleBatchComplete(), handleBatchStart(), handleBatchVoid() (+16 more)
Cohesion: 0.09
Nodes (29): fetchAddTaskStep(), fetchCopyTaskStep(), fetchDeleteTaskStep(), fetchDispatchProductionTaskSteps(), fetchForwardProductionTask(), fetchProductionTaskDetail(), fetchProductionTaskEditorInit(), fetchProductionTaskList() (+21 more)
### Community 26 - "Community 26"
Cohesion: 0.13
Nodes (19): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), postorder(), preorder(), applyTreeExpand(), handleAdd() (+11 more)
Cohesion: 0.08
Nodes (18): createEmptySnapshots(), normalizeConfiguredReagents(), normalizeConsumables(), normalizeDataCollections(), normalizeReagents(), normalizeStepOutputs(), serializeAttachments(), serializeEquipmentIds() (+10 more)
### Community 27 - "Community 27"
Cohesion: 0.09
Nodes (11): fetchMineQcWorkOrderTabUnfinishedCounts(), fetchOutboundQcDetail(), fetchQcWorkOrderDetail(), fetchQcWorkOrderList(), fetchQcWorkOrderTabUnfinishedCounts(), reload(), reloadTabCounts(), handleMenuJump() (+3 more)
Nodes (22): fetchMineProductionWorkOrderTabStepCounts(), fetchMineProductionWorkOrderTabStepCountsDeduped(), fetchProductionWorkOrderCellProductOptions(), fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList(), fetchProductionWorkOrderQcDispatchOptions(), fetchProductionWorkOrderTabStepCounts(), fetchProductionWorkOrderTabStepCountsDeduped() (+14 more)
### Community 28 - "Community 28"
Cohesion: 0.12
Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
Nodes (20): fetchGetMenuCodes(), fetchGetUserInfo(), fetchLogin(), fetchUpdateProfile(), fetchUploadProfileAvatar(), fetchUserInfo(), buildWebEncryptedLoginBody(), defaultAvatarPathByRole() (+12 more)
### Community 29 - "Community 29"
Cohesion: 0.09
Nodes (11): fetchMineQcWorkOrderTabUnfinishedCounts(), fetchOutboundQcDetail(), fetchQcWorkOrderDetail(), fetchQcWorkOrderList(), fetchQcWorkOrderTabUnfinishedCounts(), reload(), reloadTabCounts(), handleMenuJump() (+3 more)
### Community 30 - "Community 30"
Cohesion: 0.12
Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
### Community 31 - "Community 31"
Cohesion: 0.11
Nodes (11): fetchOutboundReleaseMaterial(), fetchOutboundReleaseReviewDetail(), fetchOutboundReleaseReviewList(), fetchReleaseReviewList(), handleReset(), handleSearch(), handleToggleSelect(), loadData() (+3 more)
### Community 32 - "Community 32"
Cohesion: 0.13
Nodes (18): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchDeleteCellSampleType(), fetchUpdateCellSampleType(), handleAdd(), handleDelete(), handleDropdownCommand(), handleEdit() (+10 more)
### Community 30 - "Community 30"
### Community 33 - "Community 33"
Cohesion: 0.16
Nodes (14): fetchCreateEnvDetectItem(), fetchDeleteEnvDetectItem(), fetchEnvDetectItemDetail(), fetchEnvDetectItemList(), fetchEnvDetectItemsActive(), fetchUpdateEnvDetectItem(), handleAdd(), handleBatchDelete() (+6 more)
### Community 31 - "Community 31"
Cohesion: 0.12
Nodes (12): fetchApproveTask(), fetchBusinessAllTasks(), fetchCompletedTasks(), fetchDesignerData(), fetchInstanceDetail(), fetchMyInstances(), fetchPendingTasks(), fetchProcessDefList() (+4 more)
### Community 32 - "Community 32"
### Community 34 - "Community 34"
Cohesion: 0.19
Nodes (13): fetchAttachmentDownloadUrl(), attachmentFullUrl(), ensureUniqueZipEntryName(), fetchAttachmentBlob(), getAttachmentExtension(), resolveAttachmentFileName(), sanitizeZipPathSegment(), batchFolderName() (+5 more)
### Community 33 - "Community 33"
Cohesion: 0.2
Nodes (11): fetchMarkQcMaterialUsageFullyUsed(), canMarkFullyUsed(), displayPurpose(), displayReceiver(), displayUseTime(), getChangeTypeLabel(), getChangeTypeTagType(), handleMarkFullyUsed() (+3 more)
### Community 34 - "Community 34"
### Community 35 - "Community 35"
Cohesion: 0.16
Nodes (10): useTable(), useTableImpl(), getColumnChecks(), useTableColumns(), createErrorHandler(), createSmartDebounce(), defaultResponseAdapter(), extractPagination() (+2 more)
### Community 35 - "Community 35"
### Community 36 - "Community 36"
Cohesion: 0.18
Nodes (10): fetchClinicalReceiptConfirmed(), buildConfirmedParams(), buildPendingParams(), handleConfirmedReset(), handleConfirmedSearch(), handlePendingReset(), handlePendingSearch(), loadAll() (+2 more)
### Community 37 - "Community 37"
Cohesion: 0.27
Nodes (14): useChart(), useChartComponent(), useChartOps(), colourBlend(), getCssVar(), getDarkColor(), getLightColor(), handleElementThemeColor() (+6 more)
### Community 36 - "Community 36"
Cohesion: 0.14
Nodes (8): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), useCeremony(), useTheme(), themeAnimation(), toggleTheme(), toggleTransition()
### Community 37 - "Community 37"
Cohesion: 0.33
Nodes (13): buildProtocolPaymentFlowSteps(), dash(), financeReceiptTime(), formatAmount(), hasFinanceReceipt(), hasFinanceRefund(), hasReceiptSubmit(), hasRefundSubmit() (+5 more)
### Community 38 - "Community 38"
Cohesion: 0.22
Nodes (9): fullFileUrl(), handleDownloadAttachment(), handlePreviewAttachment(), isVideoFile(), normalizeDisplayValue(), resolveReviewCellType(), resolveReviewQuantity(), resolveReviewSpecText() (+1 more)
### Community 39 - "Community 39"
Cohesion: 0.19
Nodes (6): fetchServiceOrderTxnList(), handleReset(), handleSearch(), handleTabChange(), loadData(), switchTab()
### Community 41 - "Community 41"
### Community 40 - "Community 40"
Cohesion: 0.15
Nodes (4): fetchNextDonationSampleCode(), fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList()
### Community 42 - "Community 42"
### Community 41 - "Community 41"
Cohesion: 0.25
Nodes (2): handleTouchEnd(), setTransition()
### Community 42 - "Community 42"
Cohesion: 0.28
Nodes (1): FireworkSystem
### Community 44 - "Community 44"
Cohesion: 0.31
Nodes (4): annotateForkEdges(), chainApiToElements(), walkAncestorBranch(), walkAncestorParents()
@@ -286,8 +286,8 @@ Cohesion: 0.38
Nodes (4): handleFocus(), handleInput(), parseDecimalToNumber(), sanitizeDecimalInput()
### Community 52 - "Community 52"
Cohesion: 0.48
Nodes (5): buildPrefilledLabStorageCode(), formatYear(), formatYm(), normalizeSampleTypeName(), normalizeSourceType()
Cohesion: 0.29
Nodes (2): fetchLeaveDetail(), fetchLeaveList()
### Community 53 - "Community 53"
Cohesion: 0.4
@@ -315,11 +315,11 @@ Nodes (2): if(), logSidebarMenu()
### Community 63 - "Community 63"
Cohesion: 0.5
Nodes (1): fetchStorageEntrySmsList()
Nodes (1): fetchSampleSmsNotificationList()
### Community 64 - "Community 64"
Cohesion: 0.5
Nodes (1): fetchSampleSmsNotificationList()
Nodes (1): fetchQcSmsList()
### Community 67 - "Community 67"
Cohesion: 1.0
@@ -342,14 +342,18 @@ Cohesion: 1.0
Nodes (2): emptyTabCounts(), useQcWorkOrderTabUnfinishedCounts()
## Knowledge Gaps
- **Thin community `Community 16`** (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 42`** (9 nodes): `cleanupEventListeners()`, `handleTouchEnd()`, `handleTouchMove()`, `handleTouchStart()`, `handleWheelScroll()`, `if()`, `setTransition()`, `setupEventListeners()`, `index.vue`
- **Thin community `Community 41`** (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 42`** (9 nodes): `FireworkSystem`, `.constructor()`, `.createFirework()`, `.createParticle()`, `.getAvailableParticle()`, `.initializePool()`, `.preloadAllImages()`, `.preloadImage()`, `index.vue`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 48`** (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`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 52`** (7 nodes): `fetchCreateLeave()`, `fetchDeleteLeave()`, `fetchLeaveDetail()`, `fetchLeaveList()`, `fetchSubmitLeave()`, `fetchUpdateLeave()`, `leave.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 53`** (6 nodes): `formatQcWorkOrderUnfinishedBadgeCount()`, `isUnfinishedQcWorkOrder()`, `qcWorkOrderUnfinishedBadgeTitle()`, `resolveQcWorkOrderUnfinishedBadgeCount()`, `sumQcWorkOrderGroupUnfinishedBadgeCount()`, `qc-work-order-unfinished-badge.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 55`** (5 nodes): `formatProtocolDocBatchDeleteConfirm()`, `formatProtocolDocDeleteConfirm()`, `formatProtocolDocSubject()`, `getProtocolDocTypeLabel()`, `protocol-doc-label.ts`
@@ -360,9 +364,9 @@ Nodes (2): emptyTabCounts(), useQcWorkOrderTabUnfinishedCounts()
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 61`** (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`** (4 nodes): `fetchGenerateStorageEntrySms()`, `fetchStorageEntrySmsList()`, `fetchToggleStorageEntrySmsNotified()`, `storage-entry-sms-notification.ts`
- **Thin community `Community 63`** (4 nodes): `fetchGenerateSms()`, `fetchSampleSmsNotificationList()`, `fetchToggleSmsNotified()`, `sample-sms-notification.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 64`** (4 nodes): `fetchGenerateSms()`, `fetchSampleSmsNotificationList()`, `fetchToggleSmsNotified()`, `sample-sms-notification.ts`
- **Thin community `Community 64`** (4 nodes): `fetchGenerateQcSms()`, `fetchQcSmsList()`, `fetchToggleQcSmsNotified()`, `qc-sms-notification.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 67`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
@@ -378,16 +382,16 @@ Nodes (2): emptyTabCounts(), useQcWorkOrderTabUnfinishedCounts()
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 18`, `Community 20`, `Community 21`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 29`, `Community 30`, `Community 31`, `Community 39`, `Community 41`, `Community 44`, `Community 63`, `Community 64`?**
_High betweenness centrality (0.303) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 1` to `Community 32`, `Community 0`, `Community 2`, `Community 3`, `Community 5`, `Community 7`, `Community 9`, `Community 10`, `Community 12`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 18`, `Community 27`?**
_High betweenness centrality (0.179) - this node is a cross-community bridge._
- **Why does `handleDynamicRoutes()` connect `Community 4` to `Community 24`, `Community 18`, `Community 27`?**
_High betweenness centrality (0.031) - this node is a cross-community bridge._
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 5`, `Community 6`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 15`, `Community 17`, `Community 19`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 27`, `Community 28`, `Community 29`, `Community 31`, `Community 32`, `Community 33`, `Community 36`, `Community 38`, `Community 40`, `Community 44`, `Community 52`, `Community 63`, `Community 64`?**
_High betweenness centrality (0.295) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 11`, `Community 12`, `Community 14`, `Community 15`, `Community 16`, `Community 18`, `Community 20`, `Community 24`, `Community 25`, `Community 27`, `Community 29`, `Community 34`, `Community 42`?**
_High betweenness centrality (0.211) - this node is a cross-community bridge._
- **Why does `handleDynamicRoutes()` connect `Community 4` to `Community 8`, `Community 27`, `Community 28`, `Community 29`?**
_High betweenness centrality (0.033) - this node is a cross-community bridge._
- **Are the 277 inferred relationships involving `get()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
_`get()` has 277 INFERRED edges - model-reasoned connections that need verification._
- **Are the 69 inferred relationships involving `push()` (e.g. with `refreshQcMenuBadges()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
_`push()` has 69 INFERRED edges - model-reasoned connections that need verification._
- **Are the 73 inferred relationships involving `push()` (e.g. with `refreshQcMenuBadges()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
_`push()` has 73 INFERRED edges - model-reasoned connections that need verification._
- **Are the 20 inferred relationships involving `emit()` (e.g. with `handleSubmit()` and `handleDialogClose()`) actually correct?**
_`emit()` has 20 INFERRED edges - model-reasoned connections that need verification._
- **Are the 18 inferred relationships involving `set()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
+4 -4
View File
@@ -57,12 +57,12 @@
</div>
<div id="legend"></div>
</div>
<div id="stats">2767 nodes &middot; 3805 edges &middot; 342 communities</div>
<div id="stats">2811 nodes &middot; 3906 edges &middot; 338 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": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 116, "community_name": "Community 116", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 117, "community_name": "Community 117", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 28, "community_name": "Community 28", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 28, "community_name": "Community 28", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 28, "community_name": "Community 28", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 28, "community_name": "Community 28", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 28, "community_name": "Community 28", "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": 421}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 130}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 120}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 103}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 102}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 89}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 88}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 79}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 78}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 77}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 71}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 62}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 61}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 61}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 50}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 47}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 42}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 40}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 38}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 37}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 36}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 34}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 34}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 33}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 29}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 29}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 24}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 24}, {"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": 19}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 19}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 18}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 18}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 17}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 16}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 15}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 14}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 14}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 14}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 13}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 13}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 9}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 9}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 9}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 9}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 9}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 8}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 8}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 8}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 7}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 7}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 7}, {"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": 5}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 5}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 4}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 4}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 4}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 4}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 4}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 4}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 4}, {"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",Line truncated
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": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 115, "community_name": "Community 115", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 116, "community_name": "Community 116", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 30, "community_name": "Community 30", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 30, "community_name": "Community 30", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 30, "community_name": "Community 30", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 30, "community_name": "Community 30", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 30, "community_name": "Community 30", "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": 419}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 192}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 139}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 102}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 94}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 88}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 82}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 71}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 65}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 58}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 54}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 53}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 51}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 48}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 47}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 47}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 43}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 43}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 42}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 42}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 41}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 37}, {"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": 35}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 35}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 34}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 34}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 28}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 24}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 22}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 22}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 22}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 19}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 18}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 17}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 17}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 16}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 14}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 13}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 13}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 9}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 9}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 9}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 9}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 9}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 9}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 8}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 8}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 8}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 7}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 7}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 7}, {"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": 5}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 5}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 4}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 4}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 4}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 4}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 4}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 4}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 4}, {"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", "Line 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
+47 -45
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": 1782894443.0741875,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1782894408.0549,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1782959452.5384347,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1782959443.3488367,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/store/index.ts": 1781272556.364766,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/router/index.ts": 1782394569.8806834,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentDropZone.ts": 1782873161.9839864,
@@ -47,23 +47,24 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-doc-label.ts": 1781272556.3840382,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/user-avatar.ts": 1781403605.517818,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/fullscreen-loading.ts": 1781272556.3849921,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts": 1782958232.9874876,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/sample-production-reception-fields.ts": 1782806741.4880455,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-material-ui.ts": 1781525352.6976836,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-tabs.ts": 1782802260.7327676,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-unfinished-badge.ts": 1782878267.729195,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts": 1782893963.9922342,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts": 1782894738.569876,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-category.ts": 1782393809.3917818,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts": 1781272556.3875713,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-mine-task-groups.ts": 1782703027.2893605,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-mine-task-groups.ts": 1782888808.4986835,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/expected-cell-count.ts": 1782705039.2515786,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-payment-labels.ts": 1782893910.9937537,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts": 1782893988.0240471,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts": 1782894736.648977,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts": 1782894000.6502283,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/fetch-paged-list.ts": 1781272556.3903377,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/decimal-input-format.ts": 1782807247.117702,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/sort-order.ts": 1781272556.3913012,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts": 1782893754.3565452,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts": 1782894802.0460823,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-attachment-export.ts": 1782875352.75266,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/datetime-display.ts": 1782806208.3904786,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/sample-reception-lab-storage-code.ts": 1782378453.1031013,
@@ -74,7 +75,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-item-param-options.ts": 1782446792.147386,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/clinical-payment-flow-steps.ts": 1782806499.3105526,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-step-badge.ts": 1782881450.5731556,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts": 1782564663.323319,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts": 1782960400.9073825,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/copy-text.ts": 1781272556.4018052,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/tree-path.ts": 1781272556.402468,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/mask-sensitive.ts": 1781272556.4029639,
@@ -90,6 +91,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts": 1782807264.1686463,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/category-path-display.ts": 1781272556.411347,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/transfer-type-dict.ts": 1782713881.7742825,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts": 1782960412.1034682,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/cell-product-spec.ts": 1782709946.3419836,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-labels.ts": 1781272556.4115942,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-step-assignee.ts": 1782472559.244021,
@@ -97,7 +99,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-fq-params-change.ts": 1781687645.2065177,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-payment-flow-steps.ts": 1782806499.3099828,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/loginRsa.ts": 1781272556.4129546,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts": 1782564652.8063576,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts": 1782958233.483039,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-task-editor-cache.ts": 1782602746.754815,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-pay-mode-switch.ts": 1781431995.482862,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-payment-installment.ts": 1781432316.9136086,
@@ -219,16 +221,16 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-transport-form-section/index.vue": 1782893852.3610222,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/protocol-finance-confirm-fields/index.vue": 1782893852.350682,
"/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": 1782893852.3308268,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/qc-task-view-dialog/index.vue": 1782894734.8201208,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-payment-confirm-timeline/index.vue": 1782893888.54253,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue": 1782893852.2706735,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-reception-dual-readonly-panel/index.vue": 1782893852.235278,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-reception-dual-readonly-panel/index.vue": 1782894734.989395,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/dialog-form-body/index.vue": 1782893852.1647537,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-payment-submit-readonly/index.vue": 1782893852.1397598,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-cards/index.vue": 1782893852.4513032,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/special-sample-display/index.vue": 1782893852.3469865,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/order-operate-local-dialog/index.vue": 1782893852.4089837,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/product-view-dialog/index.vue": 1782893852.3441794,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/product-view-dialog/index.vue": 1782894734.7548196,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-production-info-cards/index.vue": 1782893852.297569,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-storage-release-info/index.vue": 1782893852.266822,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue": 1782893852.19879,
@@ -242,7 +244,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-code-with-special-display/index.vue": 1782893851.6283524,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/qc-item-param-select-editor/index.vue": 1782893851.5957565,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/system-view-dialog/index.vue": 1782893851.578115,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue": 1782893851.5322437,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue": 1782894735.276092,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/order-operate-dialog-bridge/index.vue": 1782893851.5162861,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-special-mark-dialog/index.vue": 1782893851.5019739,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/list-datetime-column.vue": 1782893851.4989195,
@@ -276,7 +278,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-production-reception.ts": 1782719155.415783,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-task-result.ts": 1782379634.2324347,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/protocol-sample-collection.ts": 1781272556.659353,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material-usage.ts": 1782894613.493449,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material-usage.ts": 1782894693.658203,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/pre-transit-sample.ts": 1782204427.8344586,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-third-party-company.ts": 1781415389.1483624,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/collection-protocol.ts": 1781750452.7497737,
@@ -301,18 +303,18 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts": 1781690334.9639037,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-sms-notification.ts": 1781272556.670129,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/system.ts": 1782802585.0325377,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material.ts": 1782894613.4934483,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material.ts": 1782894693.658258,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts": 1782719389.581961,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/auth.ts": 1782122651.4628098,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts": 1782886679.6424742,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/auth/login/index.vue": 1782893854.347133,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/refund-confirm/index.vue": 1782893854.3402505,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/my-material-usage/index.vue": 1782893854.311591,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/index.vue": 1782893888.5451498,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue": 1782893854.4271934,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue": 1782894143.3529377,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/index.vue": 1782894711.5623844,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue": 1782894806.0188534,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue": 1782894754.993778,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue": 1782893854.403395,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue": 1782893854.4430473,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue": 1782960540.857623,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolAuditDialog.vue": 1782893854.3675368,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-info/index.vue": 1782893854.321358,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-reception-info/index.vue": 1782893854.265202,
@@ -325,10 +327,10 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/SampleReceptionInfoTab.vue": 1782893888.547302,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/StorageCertTab.vue": 1782893888.5475702,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/FullmoonTodoTab.vue": 1782893888.5482585,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/ProtocolAuditTab.vue": 1782893888.5485528,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/ProtocolAuditTab.vue": 1782894728.486781,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/PaymentInfoTab.vue": 1782893920.0282564,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue": 1782894640.107094,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/MaterialUsageTab.vue": 1782894623.5755792,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue": 1782896158.127473,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/MaterialUsageTab.vue": 1782895661.1992,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/MaterialStockCheckTab.vue": 1782893854.1554854,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue": 1782893854.0469422,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/storage-entry-info/index.vue": 1782893854.0034747,
@@ -341,17 +343,17 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/operations/clean-room/index.vue": 1782893853.8198242,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/operations/storage-facility/index.vue": 1782893853.715029,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/operations/exhibition-appointment/index.vue": 1782893853.5207253,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/audit/index.vue": 1782893913.7167647,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/audit/index.vue": 1782894737.8470433,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/sample-info/index.vue": 1782893854.018205,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/sample-info/DonationSampleCollectionInfoTab.vue": 1782893918.3749776,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/index.vue": 1782893912.746235,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/index.vue": 1782894737.435639,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationAuditDialog.vue": 1782893853.885547,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue": 1782894167.3038042,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue": 1782893853.7512953,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue": 1782893853.688078,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue": 1782894737.847069,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue": 1782959415.9363396,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue": 1782894808.1240149,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/dashboard/console/index.vue": 1782893853.5152776,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/tenant/index.vue": 1782893853.6602998,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/order/index.vue": 1782893853.5040941,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/order/index.vue": 1782894735.0365336,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/unit/index.vue": 1782893853.4396129,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/role/index.vue": 1782893854.095696,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/post/index.vue": 1782893854.0815024,
@@ -375,7 +377,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/dict/index.vue": 1782893853.0456495,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/leave/index.vue": 1782893852.9582078,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/output-type/index.vue": 1782893852.8585393,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/index.vue": 1782893852.8117232,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/index.vue": 1782894735.4350092,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/SourceChainGraph.vue": 1782893852.699336,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/source-chain/ChainLinkEdge.vue": 1782893852.6166403,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/source-chain/chainInject.ts": 1781272556.806028,
@@ -422,7 +424,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/tabs/tab-registry.ts": 1781583377.0075235,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/tabs/OutboundClinicalTab.vue": 1782893853.4355772,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/production-view-sections.ts": 1782894016.9828084,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/useProductionViewDialog.ts": 1782893377.8080904,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/useProductionViewDialog.ts": 1782894735.182986,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/useProductionWorkOrderTabStepCounts.ts": 1782703040.673378,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/useProductionWorkOrderTabPage.ts": 1782881469.5639377,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/InboundResearchDonationProductionViewDialog.vue": 1782893853.8921535,
@@ -435,12 +437,12 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/TemporaryProductionViewDialog.vue": 1782893853.8400733,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable-pack/index.vue": 1782893852.5431323,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable/index.vue": 1782893852.7799647,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable/ConsumablePackTab.vue": 1782893852.689723,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable/ConsumablePackTab.vue": 1782894737.21965,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cleanroom-garment/index.vue": 1782893852.58252,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/index.vue": 1782893852.391863,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/index.vue": 1782894736.1945877,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/MaterialConsumptionTab.vue": 1782893852.3221345,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/ProductionMaterialConfiguredCatalogDialog.vue": 1782893852.288642,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/ProductionMaterialUsageTab.vue": 1782893852.263329,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/ProductionMaterialUsageTab.vue": 1782894736.9178555,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/ProductionMaterialStockCheckTab.vue": 1782893852.1908164,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/ProductionMaterialPrepTab.vue": 1782893852.1329908,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/sample-reception-completion/index.vue": 1782893851.986683,
@@ -460,7 +462,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSampleGroup.vue": 1782893854.1439548,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderBatchResultTabs.vue": 1782893854.2285423,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcUnfinishedBadge.vue": 1782893854.1479301,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue": 1782894082.652902,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue": 1782894751.6504838,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTabBar.vue": 1782893854.0314786,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderBatchSubList.vue": 1782893854.0134735,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderCardList.vue": 1782893853.9724226,
@@ -481,7 +483,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useInboundQcViewDialog.ts": 1782398606.799624,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcViewAttachmentHelpers.ts": 1781581579.8782947,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/qc-work-order-selection.ts": 1782875325.8554592,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/inbound-view-sections.ts": 1782894008.6336527,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/inbound-view-sections.ts": 1782894738.7775028,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts": 1782802279.1326668,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/QcWorkOrderSystemViewDialog.vue": 1782893854.2724051,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundQcProductTable.vue": 1782893854.2596574,
@@ -497,13 +499,13 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/index.vue": 1782893853.832618,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/ThirdPartyCompanyTab.vue": 1782893853.7928631,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/my-qc-material-usage/index.vue": 1782893853.6503608,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue": 1782893853.482704,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue": 1782894736.4960976,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialStockCheckTab.vue": 1782893853.4241662,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue": 1782893853.162949,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue": 1782894736.7785268,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialBatchAttachmentDialog.vue": 1782893853.076457,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/index.vue": 1782893853.0101395,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue": 1782894112.8165123,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue": 1782894068.248391,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue": 1782894743.3751435,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/SampleReceptionCardList.vue": 1782894078.8557267,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/my-qc-task/index.vue": 1782893853.507648,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/env-detect-record/index.vue": 1782893853.44988,
@@ -511,7 +513,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue": 1782893853.146115,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/storage-release-review/index.vue": 1782894202.6907072,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/storage-release-review/StorageReleaseReviewDialog.vue": 1782893853.0158439,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/storage-release-review/StorageReleaseViewDialog.vue": 1782894179.409189,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/storage-release-review/StorageReleaseViewDialog.vue": 1782894755.2440438,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material-usage/index.vue": 1782893852.8511324,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/third-party-company/index.vue": 1782893852.8158212,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/exception/500/index.vue": 1782893852.7265046,
@@ -527,13 +529,13 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/InfusionScheduleHandoverDialog.vue": 1782893852.3551466,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleViewDialog.vue": 1782893852.3188872,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleCancelDialog.vue": 1782893852.2808146,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleEditDialog.vue": 1782893852.2546618,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleEditDialog.vue": 1782894736.6489334,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue": 1782893852.1531374,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnTable.vue": 1782893852.1199427,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue": 1782893852.0296383,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue": 1782893851.968867,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelViewDialog.vue": 1782893851.910507,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelServiceOrderTab.vue": 1782893851.6874495,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelViewDialog.vue": 1782894738.0196648,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelServiceOrderTab.vue": 1782894736.1205277,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-refund-confirm/index.vue": 1782893851.613325,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/index.vue": 1782893853.444681,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue": 1782893853.2308147,
@@ -545,22 +547,22 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/index.vue": 1782893852.991473,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationDetailDialog.vue": 1782893852.9339294,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue": 1782893852.8262732,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue": 1782893852.7602282,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue": 1782894737.3121367,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/InfusionScheduleTab.vue": 1782893852.6786568,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue": 1782893852.5596623,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue": 1782894735.609239,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue": 1782893852.365706,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ClinicalPaymentTab.vue": 1782893852.3358445,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-price/index.vue": 1782893852.3049684,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/index.vue": 1782893852.2775676,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupReserveItemsTable.vue": 1782893852.2584097,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupViewDialog.vue": 1782893852.231232,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupViewDialog.vue": 1782894735.5216386,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupRegisterDialog.vue": 1782893852.176913,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupDetailDialog.vue": 1782893852.1057308,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupDetailDialog.vue": 1782894738.2122362,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/checkup-reserve-items.ts": 1781272557.5954251,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupFillDialog.vue": 1782893851.993419,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupMarkCheckedDialog.vue": 1782893851.9295256,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue": 1782893851.7028527,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue": 1782893851.6796,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue": 1782894735.6840522,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/project-price-system/index.vue": 1782893851.639349,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-spec/index.vue": 1782893851.5999632,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue": 1782893851.5876079,
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "label": "DonationFormDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1"}, {"id": "list_donationformdialog_createemptytransport", "label": "createEmptyTransport()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L804"}, {"id": "list_donationformdialog_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L822"}, {"id": "list_donationformdialog_loadethnicoptions", "label": "loadEthnicOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L829"}, {"id": "list_donationformdialog_ensureethnicoptioninlist", "label": "ensureEthnicOptionInList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L840"}, {"id": "list_donationformdialog_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L941"}, {"id": "list_donationformdialog_scrolltosection", "label": "scrollToSection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1000"}, {"id": "list_donationformdialog_normalizesamplerow", "label": "normalizeSampleRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1008"}, {"id": "list_donationformdialog_handleopenforadd", "label": "handleOpenForAdd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1032"}, {"id": "list_donationformdialog_applydonationbundletoform", "label": "applyDonationBundleToForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1079"}, {"id": "list_donationformdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L2207"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_transport_form_section_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L695", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L696", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L697", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_research_donation", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L708", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_business", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L714", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentdropzone", "relation": "imports_from", "cLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_void_type_dict_ts", "label": "void-type-dict.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L1"}, {"id": "utils_void_type_dict_buildfallbackoptions", "label": "buildFallbackOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L12"}, {"id": "utils_void_type_dict_getvoidtypeoptions", "label": "getVoidTypeOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L23"}, {"id": "utils_void_type_dict_loadvoidtypedict", "label": "loadVoidTypeDict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L27"}, {"id": "utils_void_type_dict_resolvevoidtypelabel", "label": "resolveVoidTypeLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L50"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_void_type_dict_ts", "target": "vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_void_type_dict_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_admin", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_void_type_dict_ts", "target": "utils_void_type_dict_buildfallbackoptions", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L12", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_void_type_dict_ts", "target": "utils_void_type_dict_getvoidtypeoptions", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L23", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_void_type_dict_ts", "target": "utils_void_type_dict_loadvoidtypedict", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L27", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_void_type_dict_ts", "target": "utils_void_type_dict_resolvevoidtypelabel", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L50", "weight": 1.0}], "raw_calls": [{"caller_nid": "utils_void_type_dict_buildfallbackoptions", "callee": "map", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L13"}, {"caller_nid": "utils_void_type_dict_buildfallbackoptions", "callee": "entries", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L13"}, {"caller_nid": "utils_void_type_dict_loadvoidtypedict", "callee": "(async () => {\n try {\n const res = await fetchDictDataOptions(VOID_TYPE_DICT)\n voidTypeOptionsRef.value = res?.length ? res : buildFallbackOptions()\n labelMap = {\n ...FALLBACK_LABELS,\n ...Object.fromEntries(voidTypeOptionsRef.value.map((o) => [o.value, o.label]))\n }\n dictLoaded = true\n } catch (e) {\n console.error('\u52a0\u8f7d\u4f5c\u5e9f\u7c7b\u578b\u5b57\u5178\u5931\u8d25:', e)\n voidTypeOptionsRef.value = buildFallbackOptions()\n labelMap = { ...FALLBACK_LABELS }\n } finally {\n loadPromise = null\n }\n })", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L30"}, {"caller_nid": "utils_void_type_dict_resolvevoidtypelabel", "callee": "trim", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L51"}, {"caller_nid": "utils_void_type_dict_resolvevoidtypelabel", "callee": "String", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/void-type-dict.ts", "source_location": "L51"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_chinese_datetime_parse_ts", "label": "chinese-datetime-parse.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L1"}, {"id": "utils_chinese_datetime_parse_formatdatetimetominute", "label": "formatDatetimeToMinute()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L7"}, {"id": "utils_chinese_datetime_parse_parsechinesedatetimetext", "label": "parseChineseDatetimeText()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L14"}, {"id": "utils_chinese_datetime_parse_handlechinesedatetimepaste", "label": "handleChineseDatetimePaste()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L61"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_chinese_datetime_parse_ts", "target": "utils_chinese_datetime_parse_formatdatetimetominute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L7", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_chinese_datetime_parse_ts", "target": "utils_chinese_datetime_parse_parsechinesedatetimetext", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L14", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_chinese_datetime_parse_ts", "target": "utils_chinese_datetime_parse_handlechinesedatetimepaste", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L61", "weight": 1.0}, {"source": "utils_chinese_datetime_parse_formatdatetimetominute", "target": "utils_chinese_datetime_parse_parsechinesedatetimetext", "relation": "calls", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L10", "weight": 1.0}, {"source": "utils_chinese_datetime_parse_handlechinesedatetimepaste", "target": "utils_chinese_datetime_parse_parsechinesedatetimetext", "relation": "calls", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L68", "weight": 1.0}], "raw_calls": [{"caller_nid": "utils_chinese_datetime_parse_formatdatetimetominute", "callee": "trim", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L8"}, {"caller_nid": "utils_chinese_datetime_parse_formatdatetimetominute", "callee": "String", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L8"}, {"caller_nid": "utils_chinese_datetime_parse_parsechinesedatetimetext", "callee": "trim", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L18"}, {"caller_nid": "utils_chinese_datetime_parse_parsechinesedatetimetext", "callee": "test", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L21"}, {"caller_nid": "utils_chinese_datetime_parse_parsechinesedatetimetext", "callee": "test", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L25"}, {"caller_nid": "utils_chinese_datetime_parse_parsechinesedatetimetext", "callee": "replace", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L26"}, {"caller_nid": "utils_chinese_datetime_parse_parsechinesedatetimetext", "callee": "slice", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L27"}, {"caller_nid": "utils_chinese_datetime_parse_parsechinesedatetimetext", "callee": "split", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L28"}, {"caller_nid": "utils_chinese_datetime_parse_parsechinesedatetimetext", "callee": "split", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L30"}, {"caller_nid": "utils_chinese_datetime_parse_parsechinesedatetimetext", "callee": "padStart", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts", "source_location": "L31"}, {"caller_nid": "utils_chinese_datetime_parse_parsechinesedatetimetext", "callee": "padStart", "source_file": "/UsLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "label": "DonationFormDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1"}, {"id": "list_donationformdialog_createemptytransport", "label": "createEmptyTransport()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L804"}, {"id": "list_donationformdialog_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L822"}, {"id": "list_donationformdialog_loadethnicoptions", "label": "loadEthnicOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L829"}, {"id": "list_donationformdialog_ensureethnicoptioninlist", "label": "ensureEthnicOptionInList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L840"}, {"id": "list_donationformdialog_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L941"}, {"id": "list_donationformdialog_scrolltosection", "label": "scrollToSection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1000"}, {"id": "list_donationformdialog_normalizesamplerow", "label": "normalizeSampleRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1008"}, {"id": "list_donationformdialog_handleopenforadd", "label": "handleOpenForAdd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1032"}, {"id": "list_donationformdialog_applydonationbundletoform", "label": "applyDonationBundleToForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1079"}, {"id": "list_donationformdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L2187"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_transport_form_section_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L695", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L696", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L697", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_research_donation", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L708", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_business", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L714", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentdropzone", "relation": "imports_from", "cLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_donation_standard_import_parse_ts", "label": "donation-standard-import-parse.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L1"}, {"id": "utils_donation_standard_import_parse_normalizeline", "label": "normalizeLine()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L66"}, {"id": "utils_donation_standard_import_parse_splitkeyvalue", "label": "splitKeyValue()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L72"}, {"id": "utils_donation_standard_import_parse_resolvesamplecollecthint", "label": "resolveSampleCollectHint()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L78"}, {"id": "utils_donation_standard_import_parse_parsesex", "label": "parseSex()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L89"}, {"id": "utils_donation_standard_import_parse_parsedeliverymode", "label": "parseDeliveryMode()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L97"}, {"id": "utils_donation_standard_import_parse_parseweightgram", "label": "parseWeightGram()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L105"}, {"id": "utils_donation_standard_import_parse_parsescore", "label": "parseScore()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L114"}, {"id": "utils_donation_standard_import_parse_parsedatetime", "label": "parseDatetime()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L123"}, {"id": "utils_donation_standard_import_parse_ismaternalbloodempty", "label": "isMaternalBloodEmpty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L134"}, {"id": "utils_donation_standard_import_parse_resolvetransporttype", "label": "resolveTransportType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L141"}, {"id": "utils_donation_standard_import_parse_addsamplehint", "label": "addSampleHint()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L149"}, {"id": "utils_donation_standard_import_parse_earliestcollecttime", "label": "earliestCollectTime()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L158"}, {"id": "utils_donation_standard_import_parse_parsedonationstandardimporttext", "label": "parseDonationStandardImportText()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L166"}, {"id": "utils_donation_standard_import_parse_matchsampletypebyexactname", "label": "matchSampleTypeByExactName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L270"}, {"id": "utils_donation_standard_import_parse_matchcellsampletype", "label": "matchCellSampleType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L289"}, {"id": "utils_donation_standard_import_parse_matchexpresscompany", "label": "matchExpressCompany()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L320"}, {"id": "utils_donation_standard_import_parse_isblankstring", "label": "isBlankString()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L342"}, {"id": "utils_donation_standard_import_parse_isemptynumber", "label": "isEmptyNumber()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L346"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_donation_standard_import_parse_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_chineseLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_donation_standard_import_parse_ts", "label": "donation-standard-import-parse.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L1"}, {"id": "utils_donation_standard_import_parse_normalizeline", "label": "normalizeLine()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L66"}, {"id": "utils_donation_standard_import_parse_splitkeyvalue", "label": "splitKeyValue()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L72"}, {"id": "utils_donation_standard_import_parse_resolvesamplecollecthint", "label": "resolveSampleCollectHint()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L78"}, {"id": "utils_donation_standard_import_parse_parsesex", "label": "parseSex()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L89"}, {"id": "utils_donation_standard_import_parse_parsedeliverymode", "label": "parseDeliveryMode()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L97"}, {"id": "utils_donation_standard_import_parse_parseweightgram", "label": "parseWeightGram()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L105"}, {"id": "utils_donation_standard_import_parse_parsescore", "label": "parseScore()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L114"}, {"id": "utils_donation_standard_import_parse_parsedatetime", "label": "parseDatetime()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L123"}, {"id": "utils_donation_standard_import_parse_ismaternalbloodempty", "label": "isMaternalBloodEmpty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L134"}, {"id": "utils_donation_standard_import_parse_resolvetransporttype", "label": "resolveTransportType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L141"}, {"id": "utils_donation_standard_import_parse_addsamplehint", "label": "addSampleHint()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L151"}, {"id": "utils_donation_standard_import_parse_earliestcollecttime", "label": "earliestCollectTime()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L160"}, {"id": "utils_donation_standard_import_parse_parsedonationstandardimporttext", "label": "parseDonationStandardImportText()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L168"}, {"id": "utils_donation_standard_import_parse_matchsampletypebyexactname", "label": "matchSampleTypeByExactName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L272"}, {"id": "utils_donation_standard_import_parse_matchcellsampletype", "label": "matchCellSampleType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L291"}, {"id": "utils_donation_standard_import_parse_matchexpresscompany", "label": "matchExpressCompany()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L322"}, {"id": "utils_donation_standard_import_parse_isblankstring", "label": "isBlankString()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L344"}, {"id": "utils_donation_standard_import_parse_isemptynumber", "label": "isEmptyNumber()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L348"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_donation_standard_import_parse_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_chineseLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_material_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1"}, {"id": "material_index_defaultoperatorname", "label": "defaultOperatorName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1307"}, {"id": "material_index_ensureoperatoroption", "label": "ensureOperatorOption()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1312"}, {"id": "material_index_initoperatorfield", "label": "initOperatorField()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1323"}, {"id": "material_index_ensuretabmounted", "label": "ensureTabMounted()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1340"}, {"id": "material_index_handletabchange", "label": "handleTabChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1345"}, {"id": "material_index_loaddictoptions", "label": "loadDictOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1818"}, {"id": "material_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1827"}, {"id": "material_index_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1844"}, {"id": "material_index_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1849"}, {"id": "material_index_oneditpriceqtychange", "label": "onEditPriceQtyChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1857"}, {"id": "material_index_handleedit", "label": "handleEdit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1862"}, {"id": "material_index_handlesubmit", "label": "handleSubmit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1889"}, {"id": "material_index_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1922"}, {"id": "material_index_handledelete", "label": "handleDelete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1943"}, {"id": "material_index_formattodaydate", "label": "formatTodayDate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1962"}, {"id": "material_index_onstockinmaterialkeychange", "label": "onStockInMaterialKeyChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1968"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_material_index_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1263", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_material_index_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1264", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_material_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_system_view_dialog_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue", "source_location": "L1278", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storaLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_chinese_numeral_parse_ts", "label": "chinese-numeral-parse.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L1"}, {"id": "utils_chinese_numeral_parse_parsechinesenumeral", "label": "parseChineseNumeral()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L19"}, {"id": "utils_chinese_numeral_parse_parsebirthorder", "label": "parseBirthOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L55"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_chinese_numeral_parse_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_numeric_input_parse", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_chinese_numeral_parse_ts", "target": "utils_chinese_numeral_parse_parsechinesenumeral", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L19", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_chinese_numeral_parse_ts", "target": "utils_chinese_numeral_parse_parsebirthorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L55", "weight": 1.0}, {"source": "utils_chinese_numeral_parse_parsebirthorder", "target": "utils_chinese_numeral_parse_parsechinesenumeral", "relation": "calls", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L67", "weight": 1.0}], "raw_calls": [{"caller_nid": "utils_chinese_numeral_parse_parsechinesenumeral", "callee": "trim", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L20"}, {"caller_nid": "utils_chinese_numeral_parse_parsechinesenumeral", "callee": "test", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L23"}, {"caller_nid": "utils_chinese_numeral_parse_parsechinesenumeral", "callee": "Number", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L24"}, {"caller_nid": "utils_chinese_numeral_parse_parsechinesenumeral", "callee": "isFinite", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L25"}, {"caller_nid": "utils_chinese_numeral_parse_parsechinesenumeral", "callee": "startsWith", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L32"}, {"caller_nid": "utils_chinese_numeral_parse_parsechinesenumeral", "callee": "slice", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L33"}, {"caller_nid": "utils_chinese_numeral_parse_parsechinesenumeral", "callee": "endsWith", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L39"}, {"caller_nid": "utils_chinese_numeral_parse_parsechinesenumeral", "callee": "slice", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L40"}, {"caller_nid": "utils_chinese_numeral_parse_parsechinesenumeral", "callee": "indexOf", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L44"}, {"caller_nid": "utils_chinese_numeral_parse_parsechinesenumeral", "callee": "slice", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L46"}, {"caller_nid": "utils_chinese_numeral_parse_parsechinesenumeral", "callee": "slice", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L47"}, {"caller_nid": "utils_chinese_numeral_parse_parsebirthorder", "callee": "trim", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L56"}, {"caller_nid": "utils_chinese_numeral_parse_parsebirthorder", "callee": "extractNumericPart", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts", "source_location": "L59"}, {"caller_nid": "utils_chinese_numeral_parse_parsebirthorder", "callee": "Number", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-nLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_standard_import_parse_ts", "label": "protocol-standard-import-parse.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L1"}, {"id": "utils_protocol_standard_import_parse_normalizeline", "label": "normalizeLine()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L84"}, {"id": "utils_protocol_standard_import_parse_splitkeyvalue", "label": "splitKeyValue()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L90"}, {"id": "utils_protocol_standard_import_parse_normalizechinesedatetimeliteral", "label": "normalizeChineseDatetimeLiteral()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L96"}, {"id": "utils_protocol_standard_import_parse_parsedatetime", "label": "parseDatetime()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L105"}, {"id": "utils_protocol_standard_import_parse_parsesex", "label": "parseSex()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L116"}, {"id": "utils_protocol_standard_import_parse_parsedeliverymode", "label": "parseDeliveryMode()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L124"}, {"id": "utils_protocol_standard_import_parse_parsemoney", "label": "parseMoney()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L132"}, {"id": "utils_protocol_standard_import_parse_parsescore", "label": "parseScore()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L139"}, {"id": "utils_protocol_standard_import_parse_ismaternalbloodempty", "label": "isMaternalBloodEmpty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L143"}, {"id": "utils_protocol_standard_import_parse_resolvesamplecollecthint", "label": "resolveSampleCollectHint()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L149"}, {"id": "utils_protocol_standard_import_parse_resolvesamplecodehint", "label": "resolveSampleCodeHint()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L160"}, {"id": "utils_protocol_standard_import_parse_upsertsamplehint", "label": "upsertSampleHint()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L176"}, {"id": "utils_protocol_standard_import_parse_earliestcollecttime", "label": "earliestCollectTime()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L189"}, {"id": "utils_protocol_standard_import_parse_parsepaymodefromtext", "label": "parsePayModeFromText()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L196"}, {"id": "utils_protocol_standard_import_parse_parsepaymenttransfersegments", "label": "parsePaymentTransferSegments()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L209"}, {"id": "utils_protocol_standard_import_parse_resolvetransfertypecode", "label": "resolveTransferTypeCode()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L258"}, {"id": "utils_protocol_standard_import_parse_extractcarriernamefromtransport", "label": "extractCarrierNameFromTransport()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L287"}, {"id": "utils_protocol_standard_import_parse_parseprotocolstandardimporttext", "label": "parseProtocolStandardImportText()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-standard-import-parse.ts", "source_location": "L294"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_standard_imLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "label": "DonationFormDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1"}, {"id": "list_donationformdialog_createemptytransport", "label": "createEmptyTransport()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L804"}, {"id": "list_donationformdialog_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L822"}, {"id": "list_donationformdialog_loadethnicoptions", "label": "loadEthnicOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L829"}, {"id": "list_donationformdialog_ensureethnicoptioninlist", "label": "ensureEthnicOptionInList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L840"}, {"id": "list_donationformdialog_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L941"}, {"id": "list_donationformdialog_scrolltosection", "label": "scrollToSection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1000"}, {"id": "list_donationformdialog_normalizesamplerow", "label": "normalizeSampleRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1008"}, {"id": "list_donationformdialog_handleopenforadd", "label": "handleOpenForAdd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1032"}, {"id": "list_donationformdialog_applydonationbundletoform", "label": "applyDonationBundleToForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L1079"}, {"id": "list_donationformdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L2248"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_transport_form_section_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L695", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L696", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L697", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_research_donation", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L708", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_business", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue", "source_location": "L714", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_composables_useattachmentdropzone", "relation": "imports_from", "cLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationstatuschangedialog_vue", "label": "DonationStatusChangeDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L1"}, {"id": "list_donationstatuschangedialog_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L186"}, {"id": "list_donationstatuschangedialog_handlesubmit", "label": "handleSubmit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L193"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationstatuschangedialog_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L79", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationstatuschangedialog_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L80", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationstatuschangedialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_research_donation", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L81", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationstatuschangedialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_fullscreen_loading", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L82", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationstatuschangedialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_doc_label", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L83", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationstatuschangedialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_void_type_dict", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L84", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationstatuschangedialog_vue", "target": "list_donationstatuschangedialog_resetform", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L186", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationstatuschangedialog_vue", "target": "list_donationstatuschangedialog_handlesubmit", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L193", "weight": 1.0}], "raw_calls": [{"caller_nid": "list_donationstatuschangedialog_resetform", "callee": "clearValidate", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L190"}, {"caller_nid": "list_donationstatuschangedialog_handlesubmit", "callee": "catch", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L194"}, {"caller_nid": "list_donationstatuschangedialog_handlesubmit", "callee": "validate", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue", "source_location": "L194"}, {"caller_nid": "list_donationstatuschangedialog_handlesubmit", "callee": "confirm", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusCLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolformdialog_vue", "label": "ProtocolFormDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1"}, {"id": "protocol_protocolformdialog_ensuretransfertypeoptions", "label": "ensureTransferTypeOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1006"}, {"id": "protocol_protocolformdialog_fmtmoney", "label": "fmtMoney()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1012"}, {"id": "protocol_protocolformdialog_createemptytransport", "label": "createEmptyTransport()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1089"}, {"id": "protocol_protocolformdialog_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1107"}, {"id": "protocol_protocolformdialog_loadethnicoptions", "label": "loadEthnicOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1114"}, {"id": "protocol_protocolformdialog_ensureethnicoptioninlist", "label": "ensureEthnicOptionInList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1125"}, {"id": "protocol_protocolformdialog_initpaymentdetailexpandflags", "label": "initPaymentDetailExpandFlags()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1156"}, {"id": "protocol_protocolformdialog_paymentdetailsummary", "label": "paymentDetailSummary()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1162"}, {"id": "protocol_protocolformdialog_togglepaymentdetailexpand", "label": "togglePaymentDetailExpand()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1189"}, {"id": "protocol_protocolformdialog_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1282"}, {"id": "protocol_protocolformdialog_scrolltosection", "label": "scrollToSection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1358"}, {"id": "protocol_protocolformdialog_normalizesamplerow", "label": "normalizeSampleRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1366"}, {"id": "protocol_protocolformdialog_addpaymentdetail", "label": "addPaymentDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1389"}, {"id": "protocol_protocolformdialog_defaultinstallmentstartdateymd", "label": "defaultInstallmentStartDateYmd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1419"}, {"id": "protocol_protocolformdialog_datetimetoymd", "label": "datetimeToYmd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1429"}, {"id": "protocol_protocolformdialog_isfqnumericfieldempty", "label": "isFqNumericFieldEmpty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1437"}, {"id": "protocol_protocolformdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1886"}, {"id": "protocol_protocolformdialog_for", "label": "for()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1897"}, {"id": "protocol_protocolformdialog_pad", "label": "pad()", "file_type": "code", "source_file": "/Users/wuzilong/Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_donation_standard_import_parse_ts", "label": "donation-standard-import-parse.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L1"}, {"id": "utils_donation_standard_import_parse_normalizeline", "label": "normalizeLine()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L66"}, {"id": "utils_donation_standard_import_parse_splitkeyvalue", "label": "splitKeyValue()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L72"}, {"id": "utils_donation_standard_import_parse_resolvesamplecollecthint", "label": "resolveSampleCollectHint()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L78"}, {"id": "utils_donation_standard_import_parse_parsesex", "label": "parseSex()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L89"}, {"id": "utils_donation_standard_import_parse_parsedeliverymode", "label": "parseDeliveryMode()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L97"}, {"id": "utils_donation_standard_import_parse_parseweightgram", "label": "parseWeightGram()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L105"}, {"id": "utils_donation_standard_import_parse_parsescore", "label": "parseScore()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L114"}, {"id": "utils_donation_standard_import_parse_parsedatetime", "label": "parseDatetime()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L123"}, {"id": "utils_donation_standard_import_parse_ismaternalbloodempty", "label": "isMaternalBloodEmpty()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L134"}, {"id": "utils_donation_standard_import_parse_resolvetransporttype", "label": "resolveTransportType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L141"}, {"id": "utils_donation_standard_import_parse_addsamplehint", "label": "addSampleHint()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L150"}, {"id": "utils_donation_standard_import_parse_earliestcollecttime", "label": "earliestCollectTime()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L159"}, {"id": "utils_donation_standard_import_parse_parsedonationstandardimporttext", "label": "parseDonationStandardImportText()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L167"}, {"id": "utils_donation_standard_import_parse_matchsampletypebyexactname", "label": "matchSampleTypeByExactName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L271"}, {"id": "utils_donation_standard_import_parse_matchcellsampletype", "label": "matchCellSampleType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L290"}, {"id": "utils_donation_standard_import_parse_matchexpresscompany", "label": "matchExpressCompany()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L321"}, {"id": "utils_donation_standard_import_parse_isblankstring", "label": "isBlankString()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L343"}, {"id": "utils_donation_standard_import_parse_isemptynumber", "label": "isEmptyNumber()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts", "source_location": "L347"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_donation_standard_import_parse_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_chineseLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolstatuschangedialog_vue", "label": "ProtocolStatusChangeDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L1"}, {"id": "protocol_protocolstatuschangedialog_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L186"}, {"id": "protocol_protocolstatuschangedialog_handlesubmit", "label": "handleSubmit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L193"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolstatuschangedialog_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L79", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolstatuschangedialog_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L80", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolstatuschangedialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_collection_protocol", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L81", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolstatuschangedialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_research_donation", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L82", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolstatuschangedialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_fullscreen_loading", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L83", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolstatuschangedialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_protocol_doc_label", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L84", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolstatuschangedialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_void_type_dict", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L85", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolstatuschangedialog_vue", "target": "protocol_protocolstatuschangedialog_resetform", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L186", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolstatuschangedialog_vue", "target": "protocol_protocolstatuschangedialog_handlesubmit", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L193", "weight": 1.0}], "raw_calls": [{"caller_nid": "protocol_protocolstatuschangedialog_resetform", "callee": "clearValidate", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L190"}, {"caller_nid": "protocol_protocolstatuschangedialog_handlesubmit", "callee": "catch", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue", "source_location": "L194"}, {"caLine truncated
@@ -38,7 +38,7 @@ export function parseChineseDatetimeText(
}
const cnMatch = raw.match(
/^(\d{4})年(\d{1,2})月(\d{1,2})日(?:\s*(\d{1,2})[时::](\d{1,2})(?:[分::](\d{1,2})[秒]?)?)?/
/^(\d{4})年(\d{1,2})月(\d{1,2})日(?:\s*(\d{1,2})[时点::](\d{1,2})(?:[分::](\d{1,2})[秒]?)?)?/
)
if (!cnMatch) return null
@@ -0,0 +1,77 @@
import { extractNumericPart } from '@/utils/numeric-input-parse'
const CN_DIGIT: Record<string, number> = {
零: 0,
一: 1,
二: 2,
两: 2,
三: 3,
四: 4,
五: 5,
六: 6,
七: 7,
八: 8,
九: 9,
十: 10
}
/** 解析简单中文数字(一~十、十一等),无法解析返回 null */
export function parseChineseNumeral(text: string): number | null {
const v = (text || '').trim()
if (!v) return null
if (/^\d+$/.test(v)) {
const n = Number(v)
return Number.isFinite(n) ? n : null
}
if (v.length === 1 && CN_DIGIT[v] != null) {
return CN_DIGIT[v]
}
if (v.startsWith('十')) {
const rest = v.slice(1)
if (!rest) return 10
const tail = CN_DIGIT[rest]
return tail != null ? 10 + tail : null
}
if (v.endsWith('十')) {
const head = CN_DIGIT[v.slice(0, 1)]
return head != null ? head * 10 : null
}
const shiIdx = v.indexOf('十')
if (shiIdx > 0) {
const head = CN_DIGIT[v.slice(0, shiIdx)]
const tail = CN_DIGIT[v.slice(shiIdx + 1)] ?? 0
if (head != null) return head * 10 + tail
}
return null
}
/** 解析胎次:阿拉伯数字、中文数字、「N胎」 */
export function parseBirthOrder(value: string): number | null | undefined {
const v = (value || '').trim()
if (!v) return undefined
if (/头胎|第一胎/.test(v)) return 1
const num = extractNumericPart(v)
if (num != null && num !== '') {
const n = Number(num)
return Number.isFinite(n) ? n : undefined
}
const taiMatch = v.match(/([一二三四五六七八九十两]+)胎/)
if (taiMatch) {
const n = parseChineseNumeral(taiMatch[1])
if (n != null) return n
}
const cn = parseChineseNumeral(v)
if (cn != null) return cn
return undefined
}
@@ -1,13 +1,26 @@
import { parseChineseDatetimeText } from '@/utils/chinese-datetime-parse'
import { parseBirthOrder } from '@/utils/chinese-numeral-parse'
import { extractNumericPart } from '@/utils/numeric-input-parse'
import {
SAMPLE_TYPE_PERINATAL_HSC,
SAMPLE_TYPE_UC_MSC
} from '@/utils/sample-production-reception-fields'
export type DonationSampleImportHint = {
typeKey: 'hsc' | 'uc_msc'
typeName: string
collectTime: string
}
export type DonationStandardImportParsed = {
sampleTypeHeader: string
sampleHints: DonationSampleImportHint[]
motherName?: string
newbornSex?: '1' | '0'
newbornWeightGram?: number | null
apgarScore?: number | null
newbornDeliveryTime?: string
/** 协议级样本采集时间:多样本时为各 hint 最早时间 */
sampleCollectTime?: string
maternalBloodCollectTime?: string
maternalBloodExplicitEmpty?: boolean
@@ -15,11 +28,19 @@ export type DonationStandardImportParsed = {
birthOrder?: number | null
medicalStaff?: string
hospitalName?: string
/** @deprecated 使用 transportModeText */
transportExpressName?: string
transportModeText?: string
transportType?: 'kdys' | 'ryxd'
salesUserName?: string
}
const KEY_ALIASES: Record<string, keyof Omit<DonationStandardImportParsed, 'sampleTypeHeader'>> = {
type CommonFieldKey = keyof Omit<
DonationStandardImportParsed,
'sampleTypeHeader' | 'sampleHints' | 'transportExpressName' | 'transportModeText' | 'transportType'
>
const KEY_ALIASES: Record<string, CommonFieldKey> = {
产妇姓名: 'motherName',
母亲姓名: 'motherName',
新生儿性别: 'newbornSex',
@@ -30,14 +51,12 @@ const KEY_ALIASES: Record<string, keyof Omit<DonationStandardImportParsed, 'samp
'新生儿评分5分钟': 'apgarScore',
分娩时间: 'newbornDeliveryTime',
新生儿分娩时间: 'newbornDeliveryTime',
造血干细胞采集时间: 'sampleCollectTime',
样本采集时间: 'sampleCollectTime',
母血采集时间: 'maternalBloodCollectTime',
分娩方式: 'deliveryMode',
胎次: 'birthOrder',
采集医护: 'medicalStaff',
采集医院: 'hospitalName',
运输方式: 'transportExpressName',
运输方式: 'transportModeText',
销售人员: 'salesUserName',
采集专员: 'salesUserName'
}
@@ -56,18 +75,29 @@ function splitKeyValue(line: string): { key: string; value: string } | null {
return { key: match[1].trim(), value: match[2].trim() }
}
function resolveSampleCollectHint(key: string): Omit<DonationSampleImportHint, 'collectTime'> | null {
const k = key.trim()
if (/脐带采集时间/.test(k)) {
return { typeKey: 'uc_msc', typeName: SAMPLE_TYPE_UC_MSC }
}
if (/造血干细胞.*采集时间/.test(k) || k === '样本采集时间') {
return { typeKey: 'hsc', typeName: SAMPLE_TYPE_PERINATAL_HSC }
}
return null
}
function parseSex(value: string): '1' | '0' | undefined {
const v = value.trim()
if (!v) return undefined
if (/^男/.test(v)) return '1'
if (/^女/.test(v)) return '0'
if (/^男|^男孩/.test(v)) return '1'
if (/^女|^女孩/.test(v)) return '0'
return undefined
}
function parseDeliveryMode(value: string): string | undefined {
const v = value.trim()
if (!v) return undefined
if (/剖宫产|剖腹产/.test(v)) return 'pgc'
if (/剖宫产|剖腹产|刨宫产/.test(v)) return 'pgc'
if (/顺产|自然分娩/.test(v)) return 'sc'
return undefined
}
@@ -107,6 +137,33 @@ function isMaternalBloodEmpty(value: string): boolean {
return MATERNAL_BLOOD_EMPTY_MARKERS.some((m) => v === m || v.includes(m))
}
/** 运输方式文本 → 系统 transportType */
export function resolveTransportType(text: string): 'kdys' | 'ryxd' | null {
const v = (text || '').trim()
if (!v) return null
// 「顺丰车」为「顺风车」笔误,须先于「顺丰」快递匹配
if (/顺风车|顺丰车|自行携带|人员携带|自带|自送|亲自送|自驾/.test(v)) return 'ryxd'
if (/帮助|取样本|送到实验室|专人送|送到/.test(v)) return 'ryxd'
if (/快递|顺丰|圆通|中通|韵达|申通|EMS|邮政|极兔|京东|德邦/.test(v)) return 'kdys'
return null
}
function addSampleHint(
hints: DonationSampleImportHint[],
meta: Omit<DonationSampleImportHint, 'collectTime'>,
collectTime: string
) {
if (hints.some((h) => h.typeKey === meta.typeKey)) return
hints.push({ ...meta, collectTime })
}
function earliestCollectTime(hints: DonationSampleImportHint[]): string | undefined {
if (!hints.length) return undefined
return hints
.map((h) => h.collectTime)
.sort((a, b) => a.localeCompare(b))[0]
}
/** 解析捐赠协议单一键导入标准文本 */
export function parseDonationStandardImportText(text: string): DonationStandardImportParsed | null {
const raw = (text || '').trim()
@@ -120,13 +177,21 @@ export function parseDonationStandardImportText(text: string): DonationStandardI
if (!lines.length) return null
const result: DonationStandardImportParsed = {
sampleTypeHeader: lines[0]
sampleTypeHeader: lines[0],
sampleHints: []
}
for (let i = 1; i < lines.length; i++) {
const kv = splitKeyValue(lines[i])
if (!kv) continue
const sampleMeta = resolveSampleCollectHint(kv.key)
if (sampleMeta) {
const dt = parseDatetime(kv.value, true)
if (dt) addSampleHint(result.sampleHints, sampleMeta, dt)
continue
}
const field = KEY_ALIASES[kv.key]
if (!field) continue
@@ -154,11 +219,6 @@ export function parseDonationStandardImportText(text: string): DonationStandardI
if (dt) result.newbornDeliveryTime = dt
break
}
case 'sampleCollectTime': {
const dt = parseDatetime(kv.value, true)
if (dt) result.sampleCollectTime = dt
break
}
case 'maternalBloodCollectTime':
if (isMaternalBloodEmpty(kv.value)) {
result.maternalBloodExplicitEmpty = true
@@ -173,7 +233,7 @@ export function parseDonationStandardImportText(text: string): DonationStandardI
break
}
case 'birthOrder': {
const n = parseScore(kv.value)
const n = parseBirthOrder(kv.value)
if (n !== undefined) result.birthOrder = n
break
}
@@ -183,9 +243,12 @@ export function parseDonationStandardImportText(text: string): DonationStandardI
case 'hospitalName':
if (!result.hospitalName) result.hospitalName = kv.value
break
case 'transportExpressName':
case 'transportModeText': {
result.transportModeText = kv.value
result.transportExpressName = kv.value
result.transportType = resolveTransportType(kv.value) ?? undefined
break
}
case 'salesUserName':
result.salesUserName = kv.value
break
@@ -194,13 +257,36 @@ export function parseDonationStandardImportText(text: string): DonationStandardI
}
}
if (result.sampleHints.length) {
result.sampleCollectTime = earliestCollectTime(result.sampleHints)
}
return result
}
type CellSampleTypeOption = { id: string; typeName: string }
type CellSampleTypeOption = { id: string; typeName: string; storageYears?: number | null }
const SAMPLE_TYPE_SEGMENTS = ['围产期', '造血', '干细胞', '脐带', '间充质', '胎盘', '亚全能', '捐献']
/** 按类型名称精确或包含匹配 */
export function matchSampleTypeByExactName(
typeName: string,
types: CellSampleTypeOption[]
): CellSampleTypeOption | null {
const target = (typeName || '').trim()
if (!target || !types.length) return null
const exact = types.find((t) => t.typeName === target)
if (exact) return exact
const contains = types.filter(
(t) => t.typeName.includes(target) || target.includes(t.typeName)
)
if (contains.length === 1) return contains[0]
return matchCellSampleType(target, types)
}
/** 根据首行文本与细胞样本类型列表做语义匹配 */
export function matchCellSampleType(
headerLine: string,
@@ -0,0 +1,442 @@
import { parseChineseDatetimeText } from '@/utils/chinese-datetime-parse'
import { parseBirthOrder } from '@/utils/chinese-numeral-parse'
import {
isBlankString,
matchCellSampleType,
resolveTransportType
} from '@/utils/donation-standard-import-parse'
import { extractNumericPart } from '@/utils/numeric-input-parse'
import {
SAMPLE_TYPE_PERINATAL_HSC,
SAMPLE_TYPE_UC_MSC
} from '@/utils/sample-production-reception-fields'
export type ProtocolSampleImportHint = {
typeKey: 'hsc' | 'uc_msc'
typeName: string
sampleCode?: string
collectTime?: string
}
export type ProtocolPaymentTransferHint = {
transferAmount: number
transferTime: string
}
export type ProtocolStandardImportParsed = {
sampleTypeHeader: string
sampleHints: ProtocolSampleImportHint[]
motherName?: string
motherPhone?: string
newbornSex?: '1' | '0'
newbornWeightGram?: number | null
apgarScore?: number | null
newbornDeliveryTime?: string
sampleCollectTime?: string
maternalBloodCollectTime?: string
maternalBloodExplicitEmpty?: boolean
deliveryMode?: string
birthOrder?: number | null
medicalStaff?: string
hospitalName?: string
salesUserName?: string
payMode: 'dj' | 'fq'
contractAmount?: number | null
transferTypeLabel?: string
paymentTransfers: ProtocolPaymentTransferHint[]
transportModeText?: string
transportType?: 'kdys' | 'ryxd'
carrierName?: string
etaTime?: string
remark?: string
}
const MATERNAL_BLOOD_EMPTY_MARKERS = ['未采集', '无', '暂无', '—', '-', '未采']
const SAMPLE_CODE_RE = /^ZK[A-Z0-9]+$/i
const KEY_ALIASES: Record<string, string> = {
产妇姓名: 'motherName',
母亲姓名: 'motherName',
孕妇电话: 'motherPhone',
母亲联系电话: 'motherPhone',
新生儿性别: 'newbornSex',
新生儿体重: 'newbornWeightGram',
'新生儿体重(克)': 'newbornWeightGram',
新生儿评分: 'apgarScore',
分娩时间: 'newbornDeliveryTime',
新生儿分娩时间: 'newbornDeliveryTime',
母血采集时间: 'maternalBloodCollectTime',
分娩方式: 'deliveryMode',
胎次: 'birthOrder',
采集医护: 'medicalStaff',
采集医院: 'hospitalName',
销售人员: 'salesUserName',
采集专员: 'salesUserName',
缴费方式: 'payModeText',
转账方式: 'transferTypeText',
合同金额: 'contractAmount',
转账金额: 'transferAmount',
转账时间: 'transferTime',
运输方式: 'transportModeText',
预计送达时间: 'etaTime',
备注: 'remark'
}
function normalizeLine(line: string): string {
return line
.replace(/^[\s【】]+|[\s【】]+$/g, '')
.trim()
}
function splitKeyValue(line: string): { key: string; value: string } | null {
const match = line.match(/^([^::]+)[::]\s*(.*)$/)
if (!match) return null
return { key: match[1].trim(), value: match[2].trim() }
}
function normalizeChineseDatetimeLiteral(value: string): string {
let v = (value || '').trim()
v = v.replace(
/^(\d{4})年(\d{1,2})月(\d{1,2})日(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?$/,
(_, y, mo, d, h, mi, s) => `${y}年${Number(mo)}月${Number(d)}日${Number(h)}时${Number(mi)}分${s ? Number(s) + '秒' : ''}`
)
return v
}
function parseDatetime(value: string, minutePrecision = false): string | undefined {
const v = normalizeChineseDatetimeLiteral(value.trim())
if (!v) return undefined
if (MATERNAL_BLOOD_EMPTY_MARKERS.some((m) => v === m || v.includes(m))) {
return undefined
}
return (
parseChineseDatetimeText(v, minutePrecision ? 'datetime-minute' : 'datetime') || undefined
)
}
function parseSex(value: string): '1' | '0' | undefined {
const v = value.trim()
if (!v) return undefined
if (/^男|^男孩/.test(v)) return '1'
if (/^女|^女孩/.test(v)) return '0'
return undefined
}
function parseDeliveryMode(value: string): string | undefined {
const v = value.trim()
if (!v) return undefined
if (/剖宫产|剖腹产|刨宫产/.test(v)) return 'pgc'
if (/顺产|自然分娩/.test(v)) return 'sc'
return undefined
}
function parseMoney(value: string): number | null | undefined {
const num = extractNumericPart(value)
if (num == null || num === '') return undefined
const n = Number(num)
return Number.isFinite(n) ? n : undefined
}
function parseScore(value: string): number | null | undefined {
return parseMoney(value)
}
function isMaternalBloodEmpty(value: string): boolean {
const v = value.trim()
if (!v) return true
return MATERNAL_BLOOD_EMPTY_MARKERS.some((m) => v === m || v.includes(m))
}
function resolveSampleCollectHint(key: string): Pick<ProtocolSampleImportHint, 'typeKey' | 'typeName'> | null {
const k = key.trim()
if (/脐带间充质.*采集时间/.test(k) || k === '脐带采集时间') {
return { typeKey: 'uc_msc', typeName: SAMPLE_TYPE_UC_MSC }
}
if (/造血干细胞.*采集时间/.test(k) || k === '样本采集时间') {
return { typeKey: 'hsc', typeName: SAMPLE_TYPE_PERINATAL_HSC }
}
return null
}
function resolveSampleCodeHint(
key: string,
value: string
): (Pick<ProtocolSampleImportHint, 'typeKey' | 'typeName'> & { sampleCode: string }) | null {
const code = value.trim().toUpperCase()
if (!SAMPLE_CODE_RE.test(code)) return null
const k = key.trim()
if (/脐带间充质/.test(k)) {
return { typeKey: 'uc_msc', typeName: SAMPLE_TYPE_UC_MSC, sampleCode: code }
}
if (/造血干细胞/.test(k)) {
return { typeKey: 'hsc', typeName: SAMPLE_TYPE_PERINATAL_HSC, sampleCode: code }
}
return null
}
function upsertSampleHint(
hints: ProtocolSampleImportHint[],
partial: Partial<ProtocolSampleImportHint> & Pick<ProtocolSampleImportHint, 'typeKey' | 'typeName'>
) {
let hint = hints.find((h) => h.typeKey === partial.typeKey)
if (!hint) {
hint = { typeKey: partial.typeKey, typeName: partial.typeName }
hints.push(hint)
}
if (partial.sampleCode) hint.sampleCode = partial.sampleCode
if (partial.collectTime) hint.collectTime = partial.collectTime
}
function earliestCollectTime(hints: ProtocolSampleImportHint[]): string | undefined {
const times = hints.map((h) => h.collectTime).filter(Boolean) as string[]
if (!times.length) return undefined
return times.sort((a, b) => a.localeCompare(b))[0]
}
/** 缴费方式:仅「分期」为 fq,其余(含微信/趸交)均为 dj */
export function parsePayModeFromText(value: string): {
payMode: 'dj' | 'fq'
transferLabel?: string
} {
const v = (value || '').trim()
if (/分期/.test(v)) return { payMode: 'fq' }
if (/微信|支付宝|银行卡|银行|现金/.test(v)) {
return { payMode: 'dj', transferLabel: v }
}
return { payMode: 'dj' }
}
/** 解析转账时间行(支持多笔:…2000元,…付20880元) */
export function parsePaymentTransferSegments(
text: string,
fallbackAmount?: number | null
): ProtocolPaymentTransferHint[] {
const raw = (text || '').trim()
if (!raw) {
if (fallbackAmount != null && fallbackAmount > 0) {
return [{ transferAmount: fallbackAmount, transferTime: '' }]
}
return []
}
const segments = raw.split(/[,,]/).map((s) => s.trim()).filter(Boolean)
const results: ProtocolPaymentTransferHint[] = []
let defaultYear: number | undefined
for (const seg of segments) {
const amountMatch = seg.match(/(?:付)?(\d+(?:\.\d+)?)\s*元\s*$/)
if (!amountMatch) continue
const transferAmount = Number(amountMatch[1])
if (!Number.isFinite(transferAmount)) continue
let dtRaw = seg.slice(0, seg.length - amountMatch[0].length).trim()
dtRaw = normalizeChineseDatetimeLiteral(dtRaw)
if (/^\d{1,2}月/.test(dtRaw) && defaultYear) {
dtRaw = `${defaultYear}年${dtRaw}`
}
const transferTime = parseChineseDatetimeText(dtRaw, 'datetime')
if (transferTime) {
if (!defaultYear) defaultYear = Number(transferTime.slice(0, 4))
results.push({ transferAmount, transferTime })
}
}
if (results.length) return results
const transferTime = parseChineseDatetimeText(normalizeChineseDatetimeLiteral(raw), 'datetime')
if (fallbackAmount != null && fallbackAmount > 0) {
return [{ transferAmount: fallbackAmount, transferTime: transferTime || '' }]
}
if (transferTime) {
return [{ transferAmount: fallbackAmount ?? 0, transferTime }]
}
return []
}
/** 字典 label → transfer_type 值(wxzz 等) */
export function resolveTransferTypeCode(
label: string,
options: Array<{ value: string; label: string }>
): string {
const v = (label || '').trim()
if (!v || !options.length) return ''
const exact = options.find((o) => o.label === v || o.value === v)
if (exact) return exact.value
const contains = options.filter((o) => o.label.includes(v) || v.includes(o.label))
if (contains.length === 1) return contains[0].value
const keywordMap: Array<[RegExp, string]> = [
[/微信/, '微信'],
[/支付宝/, '支付宝'],
[/银行/, '银行'],
[/现金/, '现金']
]
for (const [re, kw] of keywordMap) {
if (!re.test(v)) continue
const hit = options.find((o) => o.label.includes(kw))
if (hit) return hit.value
}
return ''
}
/** 从运输描述中提取携带人姓名(如「露露帮助…」) */
export function extractCarrierNameFromTransport(text: string): string | undefined {
const v = (text || '').trim()
const m = v.match(/^([\u4e00-\u9fa5]{1,4})(?:帮助|协助|取)/)
return m?.[1]
}
/** 解析采集协议单一键导入标准文本 */
export function parseProtocolStandardImportText(text: string): ProtocolStandardImportParsed | null {
const raw = (text || '').trim()
if (!raw) return null
const lines = raw
.split(/\r?\n/)
.map(normalizeLine)
.filter(Boolean)
if (!lines.length) return null
const result: ProtocolStandardImportParsed = {
sampleTypeHeader: lines[0],
sampleHints: [],
payMode: 'dj',
paymentTransfers: []
}
let transferTimeRaw = ''
let transferAmountSingle: number | null | undefined
for (let i = 1; i < lines.length; i++) {
const kv = splitKeyValue(lines[i])
if (!kv) continue
const codeHint = resolveSampleCodeHint(kv.key, kv.value)
if (codeHint) {
upsertSampleHint(result.sampleHints, codeHint)
continue
}
const collectMeta = resolveSampleCollectHint(kv.key)
if (collectMeta) {
const dt = parseDatetime(kv.value, true)
if (dt) upsertSampleHint(result.sampleHints, { ...collectMeta, collectTime: dt })
continue
}
const field = KEY_ALIASES[kv.key]
if (!field) continue
switch (field) {
case 'motherName':
result.motherName = kv.value
break
case 'motherPhone':
result.motherPhone = kv.value.replace(/\s+/g, '')
break
case 'newbornSex': {
const sex = parseSex(kv.value)
if (sex) result.newbornSex = sex
break
}
case 'newbornWeightGram': {
const w = parseMoney(kv.value)
if (w !== undefined) result.newbornWeightGram = w
break
}
case 'apgarScore': {
const s = parseScore(kv.value)
if (s !== undefined) result.apgarScore = s
break
}
case 'newbornDeliveryTime': {
const dt = parseDatetime(kv.value)
if (dt) result.newbornDeliveryTime = dt
break
}
case 'maternalBloodCollectTime':
if (isMaternalBloodEmpty(kv.value)) {
result.maternalBloodExplicitEmpty = true
} else {
const dt = parseDatetime(kv.value, true)
if (dt) result.maternalBloodCollectTime = dt
}
break
case 'deliveryMode': {
const mode = parseDeliveryMode(kv.value)
if (mode) result.deliveryMode = mode
break
}
case 'birthOrder': {
const n = parseBirthOrder(kv.value)
if (n !== undefined) result.birthOrder = n
break
}
case 'medicalStaff':
result.medicalStaff = kv.value
break
case 'hospitalName':
if (!result.hospitalName) result.hospitalName = kv.value
break
case 'salesUserName':
result.salesUserName = kv.value
break
case 'payModeText': {
const pm = parsePayModeFromText(kv.value)
result.payMode = pm.payMode
if (pm.transferLabel && !result.transferTypeLabel) {
result.transferTypeLabel = pm.transferLabel
}
break
}
case 'transferTypeText':
result.transferTypeLabel = kv.value
break
case 'contractAmount': {
const amt = parseMoney(kv.value)
if (amt !== undefined) result.contractAmount = amt
break
}
case 'transferAmount': {
const amt = parseMoney(kv.value)
if (amt !== undefined) transferAmountSingle = amt
break
}
case 'transferTime':
transferTimeRaw = kv.value
break
case 'transportModeText': {
result.transportModeText = kv.value
result.transportType = resolveTransportType(kv.value) ?? undefined
result.carrierName = extractCarrierNameFromTransport(kv.value)
break
}
case 'etaTime': {
const dt = parseDatetime(kv.value)
if (dt) result.etaTime = dt
break
}
case 'remark':
result.remark = kv.value
break
default:
break
}
}
result.paymentTransfers = parsePaymentTransferSegments(transferTimeRaw, transferAmountSingle ?? null)
if (result.sampleHints.length) {
result.sampleCollectTime = earliestCollectTime(result.sampleHints)
}
return result
}
export { matchCellSampleType, isBlankString }
@@ -41,7 +41,17 @@ export type AttachmentZipExportResult = {
const PREPARING_MAX = 5
const DOWNLOADING_MAX = 85
function isInboundQcWorkOrder(row: QcWorkOrder) {
return (row.workOrderType || 'inbound') === 'inbound'
}
function workOrderFolderName(row: QcWorkOrder, used: Set<string>) {
if (isInboundQcWorkOrder(row)) {
const labCode = sanitizeZipPathSegment(row.labStorageCode || '', '未命名')
const workOrderNo = sanitizeZipPathSegment(row.workOrderNo || row.id, '工单')
const base = `入库${labCode}_${workOrderNo}`
return ensureUniqueZipEntryName(base, used)
}
const parts = [sanitizeZipPathSegment(row.workOrderNo || row.id, '工单')]
if (row.sampleCode) {
parts.push(`样本${sanitizeZipPathSegment(row.sampleCode)}`)
@@ -49,15 +59,34 @@ function workOrderFolderName(row: QcWorkOrder, used: Set<string>) {
return ensureUniqueZipEntryName(parts.join('_'), used)
}
function batchFolderName(batch: QcInspectionBatch, used: Set<string>) {
const no = sanitizeZipPathSegment(batch.batchNo || '', '')
function applyInboundLabStorageCodePrefix(code: string, workOrder: QcWorkOrder) {
if (!isInboundQcWorkOrder(workOrder)) return code
const raw = String(code || '').trim()
const workOrderNo = String(workOrder.workOrderNo || '').trim()
if (!raw || !workOrderNo || !raw.startsWith(workOrderNo)) return raw
const labCode = sanitizeZipPathSegment(workOrder.labStorageCode || '', '未命名')
return sanitizeZipPathSegment(`${labCode}${raw.slice(workOrderNo.length)}`, '')
}
function batchFolderName(batch: QcInspectionBatch, workOrder: QcWorkOrder, used: Set<string>) {
const no = sanitizeZipPathSegment(
applyInboundLabStorageCodePrefix(batch.batchNo || '', workOrder),
''
)
const name = sanitizeZipPathSegment(batch.batchName || '未命名批次')
const base = no ? `${no}_${name}` : name || `批次${batch.orderNum ?? 1}`
return ensureUniqueZipEntryName(base, used)
}
function taskFolderName(task: { taskNo?: string; itemName?: string }, used: Set<string>) {
const no = sanitizeZipPathSegment(task.taskNo || '', '')
function taskFolderName(
task: { taskNo?: string; itemName?: string },
workOrder: QcWorkOrder,
used: Set<string>
) {
const no = sanitizeZipPathSegment(
applyInboundLabStorageCodePrefix(task.taskNo || '', workOrder),
''
)
const name = sanitizeZipPathSegment(task.itemName || '未命名任务')
const base = no ? `${no}_${name}` : name
return ensureUniqueZipEntryName(base, used)
@@ -76,7 +105,7 @@ export function buildQcWorkOrderZipEntries(
const usedBatchFolders = new Set<string>()
for (const batch of batches) {
const batchFolder = batchFolderName(batch, usedBatchFolders)
const batchFolder = batchFolderName(batch, wo, usedBatchFolders)
const tasks = batch.tasks || []
const usedTaskFolders = new Set<string>()
@@ -84,7 +113,7 @@ export function buildQcWorkOrderZipEntries(
const files = task.attachmentFiles?.filter((f) => String(f.fileUrl || '').trim()) || []
if (!files.length) continue
const taskFolder = taskFolderName(task, usedTaskFolders)
const taskFolder = taskFolderName(task, wo, usedTaskFolders)
const usedFileNames = new Set<string>()
const contextHint = [wo.workOrderNo, batch.batchName, task.itemName]
.filter(Boolean)
@@ -200,6 +200,9 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="经办人" min-width="100" align="center" header-align="center">
<template #default="{ row }">{{ row.operatorName || '—' }}</template>
</el-table-column>
<el-table-column
v-if="!mineOnly"
label="领用人"
@@ -575,6 +578,10 @@
value: getSourceLabel(row.sourceType),
tagType: getSourceTagType(row.sourceType) as any
},
{
label: '经办人',
value: row.operatorName || '—'
},
{
label: '领用人',
value: displayReceiver(row) === '-' ? '—' : displayReceiver(row)
@@ -292,13 +292,13 @@
</el-select>
</el-form-item>
<el-form-item label="入库编号" prop="stockInNo">
<el-input v-model="formData.stockInNo" placeholder="请输入入库编号" />
<el-input v-model="formData.stockInNo" placeholder="可选" />
</el-form-item>
<el-form-item label="入库日期" prop="stockInDate">
<el-date-picker
v-model="formData.stockInDate"
type="date"
placeholder="选择入库日期"
placeholder="可选"
value-format="YYYY-MM-DD"
style="width: 100%"
/>
@@ -307,19 +307,19 @@
<el-date-picker
v-model="formData.expireDate"
type="date"
placeholder="选择过期日期"
placeholder="可选"
value-format="YYYY-MM-DD"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="货号" prop="catalogNo">
<el-input v-model="formData.catalogNo" placeholder="请输入货号" />
<el-input v-model="formData.catalogNo" placeholder="可选" />
</el-form-item>
<el-form-item label="批号" prop="batchNo">
<el-input v-model="formData.batchNo" placeholder="请输入批号" />
<el-input v-model="formData.batchNo" placeholder="可选" />
</el-form-item>
<el-form-item label="厂家" prop="manufacturer">
<el-input v-model="formData.manufacturer" placeholder="请输入厂家" />
<el-input v-model="formData.manufacturer" placeholder="可选" />
</el-form-item>
<el-form-item label="单位" prop="unit">
<el-select
@@ -348,7 +348,7 @@
<AmountInput
v-model="formData.unitPrice"
:min="0"
placeholder="请输入单价"
placeholder="可选"
@change="onEditPriceQtyChange"
/>
</el-form-item>
@@ -356,7 +356,7 @@
<AmountInput
v-model="formData.amount"
:min="0"
placeholder="自动计算:单价 × 数量"
placeholder="可选,可自动计算:单价 × 数量"
@change="formData.amountManual = true"
/>
</el-form-item>
@@ -402,6 +402,28 @@
:scroll-into-view-options="{ behavior: 'smooth', block: 'center' }"
>
<div class="form-grid-3">
<el-form-item label="经办人" prop="operator">
<el-select
v-model="stockInForm.operator"
placeholder="请选择经办人"
clearable
filterable
remote
allow-create
default-first-option
reserve-keyword
:loading="receiverUserLoading"
:remote-method="searchReceiverUsers"
style="width: 100%"
>
<el-option
v-for="u in receiverUserOptions"
:key="u.id"
:label="formatReceiverUserLabel(u)"
:value="(u.nickName || '').trim()"
/>
</el-select>
</el-form-item>
<el-form-item label="物资" prop="materialKey">
<el-select
v-model="stockInForm.materialKey"
@@ -461,13 +483,13 @@
</el-select>
</el-form-item>
<el-form-item label="入库编号" prop="stockInNo">
<el-input v-model="stockInForm.stockInNo" placeholder="请输入入库编号" />
<el-input v-model="stockInForm.stockInNo" placeholder="可选" />
</el-form-item>
<el-form-item label="入库日期" prop="stockInDate">
<el-date-picker
v-model="stockInForm.stockInDate"
type="date"
placeholder="选择入库日期"
placeholder="可选"
value-format="YYYY-MM-DD"
style="width: 100%"
/>
@@ -476,19 +498,19 @@
<el-date-picker
v-model="stockInForm.expireDate"
type="date"
placeholder="选择过期日期"
placeholder="可选"
value-format="YYYY-MM-DD"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="货号" prop="catalogNo">
<el-input v-model="stockInForm.catalogNo" placeholder="请输入货号" />
<el-input v-model="stockInForm.catalogNo" placeholder="可选" />
</el-form-item>
<el-form-item label="批号" prop="batchNo">
<el-input v-model="stockInForm.batchNo" placeholder="请输入批号" />
<el-input v-model="stockInForm.batchNo" placeholder="可选" />
</el-form-item>
<el-form-item label="厂家" prop="manufacturer">
<el-input v-model="stockInForm.manufacturer" placeholder="请输入厂家" />
<el-input v-model="stockInForm.manufacturer" placeholder="可选" />
</el-form-item>
<el-form-item label="单位">
<el-select
@@ -519,7 +541,7 @@
<el-form-item label="入库数量" prop="qty">
<DecimalInput
v-model="stockInForm.qty"
:min="0.01"
:min="0"
:precision="2"
style="width: 100%"
@change="onSingleStockInPriceQtyChange"
@@ -529,7 +551,7 @@
<AmountInput
v-model="stockInForm.unitPrice"
:min="0"
placeholder="请输入单价"
placeholder="可选"
@change="onSingleStockInPriceQtyChange"
/>
</el-form-item>
@@ -537,7 +559,7 @@
<AmountInput
v-model="stockInForm.amount"
:min="0"
placeholder="自动计算:单价 × 数量"
placeholder="可选,可自动计算:单价 × 数量"
@change="stockInForm.amountManual = true"
/>
</el-form-item>
@@ -584,6 +606,28 @@
:scroll-into-view-options="{ behavior: 'smooth', block: 'center' }"
>
<div class="form-grid-2 batch-stock-move-head">
<el-form-item label="经办人" prop="operator">
<el-select
v-model="batchStockInForm.operator"
placeholder="请选择经办人"
clearable
filterable
remote
allow-create
default-first-option
reserve-keyword
:loading="receiverUserLoading"
:remote-method="searchReceiverUsers"
style="width: 100%"
>
<el-option
v-for="u in receiverUserOptions"
:key="u.id"
:label="formatReceiverUserLabel(u)"
:value="(u.nickName || '').trim()"
/>
</el-select>
</el-form-item>
<el-form-item label="入库时间" prop="stockInTime">
<el-date-picker
v-model="batchStockInForm.stockInTime"
@@ -665,7 +709,7 @@
/>
</el-form-item>
<el-form-item label="入库编号">
<el-input v-model="row.stockInNo" size="small" placeholder="必填" />
<el-input v-model="row.stockInNo" size="small" placeholder="可选" />
</el-form-item>
<el-form-item label="入库日期">
<el-date-picker
@@ -673,7 +717,7 @@
size="small"
type="date"
value-format="YYYY-MM-DD"
placeholder="日期"
placeholder="可选"
style="width: 100%"
/>
</el-form-item>
@@ -683,24 +727,24 @@
size="small"
type="date"
value-format="YYYY-MM-DD"
placeholder="必填"
placeholder="可选"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="货号">
<el-input v-model="row.catalogNo" size="small" placeholder="必填" />
<el-input v-model="row.catalogNo" size="small" placeholder="可选" />
</el-form-item>
<el-form-item label="批号">
<el-input v-model="row.batchNo" size="small" placeholder="必填" />
<el-input v-model="row.batchNo" size="small" placeholder="可选" />
</el-form-item>
<el-form-item label="厂家">
<el-input v-model="row.manufacturer" size="small" placeholder="必填" />
<el-input v-model="row.manufacturer" size="small" placeholder="可选" />
</el-form-item>
<el-form-item label="数量">
<DecimalInput
v-model="row.qty"
size="small"
:min="0.01"
:min="0"
:precision="2"
style="width: 100%"
@change="() => onBatchInLinePriceQtyChange(row)"
@@ -767,6 +811,28 @@
:scroll-into-view-options="{ behavior: 'smooth', block: 'center' }"
>
<div class="form-grid-2 batch-stock-move-head">
<el-form-item label="经办人" prop="operator">
<el-select
v-model="batchStockOutForm.operator"
placeholder="请选择经办人"
clearable
filterable
remote
allow-create
default-first-option
reserve-keyword
:loading="receiverUserLoading"
:remote-method="searchReceiverUsers"
style="width: 100%"
>
<el-option
v-for="u in receiverUserOptions"
:key="u.id"
:label="formatReceiverUserLabel(u)"
:value="(u.nickName || '').trim()"
/>
</el-select>
</el-form-item>
<el-form-item label="出库时间" prop="stockOutTime">
<el-date-picker
v-model="batchStockOutForm.stockOutTime"
@@ -959,6 +1025,28 @@
:scroll-into-view-options="{ behavior: 'smooth', block: 'center' }"
>
<div class="form-grid-2 batch-stock-move-head">
<el-form-item label="经办人" prop="operator">
<el-select
v-model="batchDiscardForm.operator"
placeholder="请选择经办人"
clearable
filterable
remote
allow-create
default-first-option
reserve-keyword
:loading="receiverUserLoading"
:remote-method="searchReceiverUsers"
style="width: 100%"
>
<el-option
v-for="u in receiverUserOptions"
:key="u.id"
:label="formatReceiverUserLabel(u)"
:value="(u.nickName || '').trim()"
/>
</el-select>
</el-form-item>
<el-form-item label="废弃时间" prop="discardTime">
<el-date-picker
v-model="batchDiscardForm.discardTime"
@@ -1143,6 +1231,9 @@
<el-table-column label="领用人" min-width="90" align="center" header-align="center">
<template #default="{ row }">{{ row.receiver || '—' }}</template>
</el-table-column>
<el-table-column label="经办人" min-width="90" align="center" header-align="center">
<template #default="{ row }">{{ row.operatorName || '—' }}</template>
</el-table-column>
<el-table-column label="用途" min-width="120" align="center" header-align="center" show-overflow-tooltip>
<template #default="{ row }">{{ row.purpose || row.remark || '—' }}</template>
</el-table-column>
@@ -1204,12 +1295,37 @@
import { fetchMaterialUsageList, type MaterialUsage } from '@/api/material-usage'
import { MATERIAL_DISCARD_REASONS } from '@/constants/material-discard'
import { fetchAllPagedRecords } from '@/utils/fetch-paged-list'
import { useUserStore } from '@/store/modules/user'
import MaterialUsageTab from './MaterialUsageTab.vue'
import MaterialStockCheckTab from './MaterialStockCheckTab.vue'
defineOptions({ name: 'CellStorageMaterial' })
const route = useRoute()
const userStore = useUserStore()
function defaultOperatorName() {
const info = userStore.info as Record<string, unknown>
return String(info?.realName || info?.userName || info?.username || info?.nickName || '').trim()
}
function ensureOperatorOption(name: string) {
const v = name?.trim()
if (!v) return
if (!receiverUserOptions.value.some((u) => (u.nickName || '').trim() === v)) {
receiverUserOptions.value = [
{ id: `local-op-${v}`, nickName: v, userNo: '', phoneNo: '' } as Api.User.UserItem,
...receiverUserOptions.value
]
}
}
function initOperatorField(target: { operator: string }) {
const name = defaultOperatorName()
target.operator = name
ensureOperatorOption(name)
void searchReceiverUsers('')
}
const MATERIAL_TABS = [
{ name: 'list', label: '物料列表' },
@@ -1347,14 +1463,6 @@
})
const formRules = {
stockInNo: [{ required: true, message: '请输入入库编号', trigger: 'blur' }],
stockInDate: [{ required: true, message: '请选择入库日期', trigger: 'change' }],
expireDate: [{ required: true, message: '请选择过期日期', trigger: 'change' }],
catalogNo: [{ required: true, message: '请输入货号', trigger: 'blur' }],
batchNo: [{ required: true, message: '请输入批号', trigger: 'blur' }],
manufacturer: [{ required: true, message: '请输入厂家', trigger: 'blur' }],
unitPrice: [{ required: true, message: '请输入单价', trigger: 'change' }],
amount: [{ required: true, message: '请输入金额', trigger: 'change' }],
materialCode: [{ required: true, message: '请输入物料编码', trigger: 'blur' }],
materialName: [{ required: true, message: '请输入物料名称', trigger: 'blur' }]
}
@@ -1380,6 +1488,7 @@
amount: 0 as number | null,
amountManual: false,
qty: 1,
operator: '',
remark: ''
})
@@ -1408,15 +1517,7 @@
trigger: 'blur'
}
],
stockInNo: [{ required: true, message: '请输入入库编号', trigger: 'blur' }],
stockInDate: [{ required: true, message: '请选择入库日期', trigger: 'change' }],
expireDate: [{ required: true, message: '请选择过期日期', trigger: 'change' }],
catalogNo: [{ required: true, message: '请输入货号', trigger: 'blur' }],
batchNo: [{ required: true, message: '请输入批号', trigger: 'blur' }],
manufacturer: [{ required: true, message: '请输入厂家', trigger: 'blur' }],
unitPrice: [{ required: true, message: '请输入单价', trigger: 'change' }],
amount: [{ required: true, message: '请输入金额', trigger: 'change' }],
qty: [{ required: true, message: '请输入入库数量', trigger: 'blur' }]
operator: [{ required: true, message: '请选择经办人', trigger: 'change' }]
}
function formatReceiverUserLabel(u: Api.User.UserItem) {
@@ -1478,11 +1579,13 @@
const batchStockInLines = ref<BatchStockInLine[]>([])
const batchStockInForm = reactive({
stockInTime: '',
operator: '',
remark: ''
})
const batchStockInRules = {
stockInTime: [{ required: true, message: '请选择入库时间', trigger: 'change' }]
stockInTime: [{ required: true, message: '请选择入库时间', trigger: 'change' }],
operator: [{ required: true, message: '请选择经办人', trigger: 'change' }]
}
// 批量出库
@@ -1503,6 +1606,7 @@
const batchStockOutLines = ref<BatchStockOutLine[]>([])
const batchStockOutForm = reactive({
stockOutTime: '',
operator: '',
receiver: '',
purpose: '',
remark: ''
@@ -1513,6 +1617,7 @@
const batchStockOutRules = {
stockOutTime: [{ required: true, message: '请选择出库时间', trigger: 'change' }],
operator: [{ required: true, message: '请选择经办人', trigger: 'change' }],
receiver: [{ required: true, message: '请选择领用人', trigger: 'change' }]
}
@@ -1534,12 +1639,14 @@
const batchDiscardLines = ref<BatchDiscardLine[]>([])
const batchDiscardForm = reactive({
discardTime: '',
operator: '',
discardReason: '',
remark: ''
})
const batchDiscardRules = {
discardTime: [{ required: true, message: '请选择废弃时间', trigger: 'change' }],
operator: [{ required: true, message: '请选择经办人', trigger: 'change' }],
discardReason: [{ required: true, message: '请选择废弃原因', trigger: 'change' }],
remark: [
{
@@ -1906,6 +2013,7 @@
stockInForm.amount = null
stockInForm.amountManual = false
stockInForm.qty = 1
stockInForm.operator = defaultOperatorName()
stockInForm.remark = ''
}
@@ -1916,6 +2024,7 @@
function handleOpenStockIn() {
resetStockInForm()
initOperatorField(stockInForm)
stockInVisible.value = true
void searchMaterialOptions('')
stockInFormRef.value?.clearValidate?.()
@@ -1937,6 +2046,7 @@
amount: Number(stockInForm.amount) || 0,
qty: stockInForm.qty,
stockInTime: formatNowDatetime(),
operatorName: stockInForm.operator?.trim() || undefined,
remark: stockInForm.remark?.trim() || undefined
})
ElMessage.success('入库成功')
@@ -2081,6 +2191,7 @@
batchDiscardForm.discardTime = formatNowDatetime()
batchDiscardForm.discardReason = ''
batchDiscardForm.remark = ''
initOperatorField(batchDiscardForm)
batchDiscardVisible.value = true
void searchBatchOptions('')
void searchUnitOptions('')
@@ -2134,6 +2245,7 @@
remark: l.remark?.trim() || undefined
})),
discardReason: batchDiscardForm.discardReason?.trim() || '',
operatorName: batchDiscardForm.operator?.trim() || undefined,
remark: batchDiscardForm.remark?.trim() || undefined,
discardTime: batchDiscardForm.discardTime || undefined
})
@@ -2151,6 +2263,7 @@
batchStockInLines.value = [newBatchStockInLine()]
batchStockInForm.stockInTime = formatNowDatetime()
batchStockInForm.remark = ''
initOperatorField(batchStockInForm)
batchStockInVisible.value = true
void searchMaterialOptions('')
batchStockInFormRef.value?.clearValidate?.()
@@ -2167,30 +2280,6 @@
ElMessage.warning('请选择物资')
return
}
if (!line.stockInNo?.trim()) {
ElMessage.warning('请填写入库编号')
return
}
if (!line.stockInDate) {
ElMessage.warning('请选择入库日期')
return
}
if (!line.expireDate) {
ElMessage.warning('请选择过期日期')
return
}
if (!line.catalogNo?.trim() || !line.batchNo?.trim() || !line.manufacturer?.trim()) {
ElMessage.warning('请填写货号、批号、厂家')
return
}
if (line.unitPrice == null || line.amount == null) {
ElMessage.warning('请填写单价和金额')
return
}
if (!line.qty || line.qty <= 0) {
ElMessage.warning('入库数量必须大于 0')
return
}
}
try {
await ElMessageBox.confirm(
@@ -2218,6 +2307,7 @@
remark: l.remark?.trim() || undefined
})),
stockInTime: batchStockInForm.stockInTime || undefined,
operatorName: batchStockInForm.operator?.trim() || undefined,
remark: batchStockInForm.remark?.trim() || undefined
})
ElMessage.success(`批量入库成功,共 ${res.count ?? batchStockInLines.value.length} 项`)
@@ -2236,6 +2326,7 @@
batchStockOutForm.receiver = ''
batchStockOutForm.purpose = ''
batchStockOutForm.remark = ''
initOperatorField(batchStockOutForm)
batchStockOutVisible.value = true
void searchReceiverUsers('')
void searchBatchOptions('')
@@ -2286,6 +2377,7 @@
remark: l.remark?.trim() || undefined
})),
stockOutTime: batchStockOutForm.stockOutTime || undefined,
operatorName: batchStockOutForm.operator?.trim() || undefined,
receiver: batchStockOutForm.receiver?.trim() || undefined,
purpose: batchStockOutForm.purpose?.trim() || undefined,
remark: batchStockOutForm.remark?.trim() || undefined
@@ -34,13 +34,41 @@
scroll-to-error
class="protocol-form"
>
<!-- Tab 1: 基本信息 -->
<div id="form-section-basic" class="form-tab-pane">
<!-- Tab 1: 基本信息(新增时左侧一键导入、右侧基本信息) -->
<div
id="form-section-basic"
class="form-tab-pane"
:class="{ 'form-tab-pane--import-basic': !isEdit }"
>
<div v-if="!isEdit" class="section-card section-card--import">
<div class="section-title">
<div class="section-title-left"><h3>一键导入</h3></div>
</div>
<el-form-item label="标准信息">
<el-input
v-model="standardImportText"
type="textarea"
:rows="12"
placeholder="请粘贴标准格式信息,点击「一键导入」填充各 Tab 字段"
/>
</el-form-item>
<div class="import-actions">
<el-button
class="btn-main"
type="primary"
:loading="standardImportLoading"
@click="handleStandardImport"
>
<el-icon><Upload /></el-icon>
一键导入
</el-button>
</div>
</div>
<div class="section-card">
<div class="section-title">
<div class="section-title-left"><h3>基本信息</h3></div>
</div>
<div class="form-grid form-grid--col4">
<div class="form-grid" :class="isEdit ? 'form-grid--col4' : 'form-grid--col2'">
<el-form-item label="协议状态" prop="protocolStatus">
<el-select
v-model="formData.protocolStatus"
@@ -673,13 +701,12 @@
<div class="detail-body-inner">
<div class="form-grid form-grid--col4">
<el-form-item label="应缴费金额(元)">
<el-input
<AmountInput
v-model="detail.dueAmount"
type="number"
step="any"
:min="0"
disabled
style="width: 100%"
:disabled="isPayDetailLocked(detail)"
placeholder="请输入应缴费金额"
@change="onPaymentDetailDueAmountChange(dIdx)"
/>
</el-form-item>
<el-form-item label="转账方式">
@@ -891,7 +918,8 @@
Loading,
Download,
ArrowDown,
ArrowRight
ArrowRight,
Upload
} from '@element-plus/icons-vue'
import {
fetchCollectionProtocolDetail,
@@ -906,6 +934,17 @@
useIndexedAttachmentDropZone
} from '@/composables/useAttachmentDropZone'
import { formatDatetimeToMinute } from '@/utils/chinese-datetime-parse'
import {
matchExpressCompany,
matchSampleTypeByExactName
} from '@/utils/donation-standard-import-parse'
import {
parseProtocolStandardImportText,
resolveTransferTypeCode,
isBlankString,
matchCellSampleType,
type ProtocolStandardImportParsed
} from '@/utils/protocol-standard-import-parse'
import {
fetchCustomerList,
fetchUserList,
@@ -914,6 +953,7 @@
fetchItemUnitList,
fetchCollectionRegionList,
fetchHospitalList,
fetchSearchCollectionHospitals,
fetchSampleCodeList,
fetchExpressCompanyList,
fetchSiteList
@@ -1165,6 +1205,8 @@
const dialogFormLoading = ref(false)
const dialogTitle = ref('新增协议单')
const isEdit = ref(false)
const standardImportText = ref('')
const standardImportLoading = ref(false)
const submitLoading = ref(false)
const editingId = ref<string | null>(null)
const formRef = ref()
@@ -1302,6 +1344,7 @@
expressCompanyOptions.value = []
activeFormTab.value = 'basic'
lastConfirmedPayMode.value = 'dj'
standardImportText.value = ''
lastConfirmedFqParams.value = {
installmentCount: null,
installmentIntervalMonths: null,
@@ -1862,7 +1905,6 @@
submitLoading.value = true
try {
syncFqPaymentDetailRowCount(fqPaymentContext(), formData.paymentDetails)
syncPaymentDueAmounts()
const protocolAttachmentUrls = formData.attachments
.map((a) => a.fileUrl)
.filter(Boolean)
@@ -2246,6 +2288,527 @@
ensureSitesInOptions(formData.samples)
}
function formatNowDatetime(): string {
const now = new Date()
const pad = (n: number) => String(n).padStart(2, '0')
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
}
/** 一键导入前清空上次导入/手填的可覆盖字段(保留协议状态、登记日期、附件等) */
function clearFormBeforeStandardImport() {
customerId.value = null
customerSnapshot.value = null
customerOptions.value = []
formData.customerId = ''
formData.motherName = ''
formData.motherPhone = ''
formData.motherIdCard = ''
formData.motherBirthYm = ''
formData.motherEmail = ''
formData.motherAddress = ''
formData.fatherName = ''
formData.fatherPhone = ''
formData.fatherIdCard = ''
formData.newbornName = ''
formData.newbornIdCard = ''
formData.expectedDeliveryDate = ''
formData.newbornSex = ''
formData.newbornWeightGram = null
formData.apgar1min = null
formData.apgar5min = null
formData.newbornDeliveryTime = ''
formData.deliveryMode = ''
formData.birthOrder = null
formData.regionId = ''
formData.hospitalId = ''
formData.medicalStaff = ''
formData.sampleCollectTime = ''
formData.maternalBloodCollectTime = ''
regionOptions.value = []
hospitalOptions.value = []
collectorUserId.value = null
collectorSnapshot.value = null
collectorUserOptions.value = []
formData.collectorUserId = ''
salesUserId.value = null
salesSnapshot.value = null
salesUserOptions.value = []
formData.salesUserId = ''
formData.samples = []
sampleCodeOptions.value = []
siteOptions.value = []
expressCompanyOptions.value = []
formData.payMode = 'dj'
formData.contractAmount = null
formData.lumpSumDeadline = ''
formData.installmentCount = null
formData.installmentIntervalMonths = null
formData.installmentStartDate = ''
formData.installmentAdvanceDays = DEFAULT_INSTALLMENT_ADVANCE_DAYS
formData.installmentRatios = []
formData.paymentDetails = []
lastConfirmedPayMode.value = 'dj'
lastConfirmedFqParams.value = {
installmentCount: null,
installmentIntervalMonths: null,
installmentStartDate: '',
installmentAdvanceDays: DEFAULT_INSTALLMENT_ADVANCE_DAYS,
installmentRatios: [] as number[]
}
formData.remark = ''
}
async function applyMotherByName(name: string): Promise<'linked' | 'name-only' | 'skipped'> {
const keyword = (name || '').trim()
if (!keyword) return 'skipped'
if (!isBlankString(formData.customerId)) return 'skipped'
if (!isBlankString(formData.motherName)) return 'skipped'
try {
const res = await fetchCustomerList({ page: 1, pageSize: 50, keyword })
const list = res.list || []
const match =
list.find((c) => c.customerName === keyword) ||
list.find((c) => (c.customerName || '').includes(keyword))
if (match) {
customerOptions.value = [match, ...list.filter((c) => c.id !== match.id)]
onCustomerChange(match.id)
return 'linked'
}
formData.motherName = keyword
return 'name-only'
} catch {
formData.motherName = keyword
return 'name-only'
}
}
async function applyHospitalByName(name: string): Promise<boolean> {
const keyword = (name || '').trim()
if (!keyword || !isBlankString(formData.hospitalId)) return false
try {
const res = await fetchSearchCollectionHospitals({ keyword, limit: 20 })
const list = res.list || []
const match =
list.find((h) => h.hospitalName === keyword) ||
list.find((h) => (h.hospitalName || '').includes(keyword)) ||
list[0]
if (!match) return false
const regionStub: Api.BizCollectionRegion.RegionItem = {
id: match.regionId,
regionName: match.regionName || match.regionId,
hospitalNames: [],
tenantNo: match.tenantNo || '',
orderNum: 0,
remark: '',
createTime: '',
updateTime: ''
}
if (!regionOptions.value.some((r) => r.id === match.regionId)) {
regionOptions.value = [regionStub, ...regionOptions.value]
}
formData.regionId = match.regionId
await loadHospitalsByRegion(match.regionId, keyword)
if (!hospitalOptions.value.some((h) => h.id === match.id)) {
hospitalOptions.value = [match, ...hospitalOptions.value]
}
formData.hospitalId = match.id
return true
} catch {
return false
}
}
async function applySalesUserByName(name: string): Promise<boolean> {
const keyword = (name || '').trim()
if (!keyword) return false
try {
const res = await fetchUserList({
page: 1,
pageSize: 50,
keyword,
status: '1'
})
const list = res.list || []
const match =
list.find((u) => u.nickName === keyword) ||
list.find((u) => (u.nickName || '').includes(keyword))
if (!match) return false
applyUserToCollector(match)
applyUserToSales(match)
return true
} catch {
return false
}
}
function applyUserToCollector(u: Api.User.UserItem) {
collectorSnapshot.value = { ...u }
collectorUserId.value = u.id
formData.collectorUserId = u.id
if (!collectorUserOptions.value.some((x) => x.id === u.id)) {
collectorUserOptions.value = [u, ...collectorUserOptions.value]
}
}
function applyUserToSales(u: Api.User.UserItem) {
salesSnapshot.value = { ...u }
salesUserId.value = u.id
formData.salesUserId = u.id
if (!salesUserOptions.value.some((x) => x.id === u.id)) {
salesUserOptions.value = [u, ...salesUserOptions.value]
}
}
async function resolveSampleCodeByCode(code: string) {
const keyword = (code || '').trim()
if (!keyword) return null
const res = await fetchSampleCodeList({ page: 1, pageSize: 50, keyword })
const list = (res.list || []) as Api.BizSampleCode.SampleCodeItem[]
return (
list.find((sc) => sc.sampleCode === keyword) ||
list.find((sc) => String(sc.sampleCode || '').includes(keyword)) ||
null
)
}
function applyParsedTransportToSample(
sample: Record<string, any>,
parsed: ProtocolStandardImportParsed,
warnings: string[],
filledLabels: string[]
) {
if (!parsed.transportType) return
const transport = { ...(sample.transport || createEmptyTransport()) }
let transportFilled = false
if (isBlankString(transport.transportType)) {
transport.transportType = parsed.transportType
transportFilled = true
}
if (isBlankString(transport.destSiteId) && siteOptions.value.length) {
const site = siteOptions.value[0]
transport.destSiteId = site.id
transportFilled = true
}
if (parsed.etaTime && isBlankString(transport.etaTime)) {
transport.etaTime = parsed.etaTime
transportFilled = true
} else if (isBlankString(transport.etaTime)) {
transport.etaTime = formatNowDatetime()
transportFilled = true
}
if (parsed.transportType === 'kdys' && isBlankString(transport.expressCompanyId)) {
const ec = matchExpressCompany(
parsed.transportModeText || '顺丰快递',
expressCompanyOptions.value
)
if (ec) {
transport.expressCompanyId = ec.id
if (!expressCompanyOptions.value.some((x) => x.id === ec.id)) {
expressCompanyOptions.value = [ec, ...expressCompanyOptions.value]
}
transportFilled = true
} else {
warnings.push(`未找到快递公司「${parsed.transportModeText || ''}」`)
}
}
if (parsed.transportType === 'ryxd' && parsed.carrierName && isBlankString(transport.carrierName)) {
transport.carrierName = parsed.carrierName
transportFilled = true
}
sample.transport = transport
if (transportFilled) filledLabels.push('运输信息')
}
async function applySampleHintsFromImport(
parsed: ProtocolStandardImportParsed,
warnings: string[],
filledLabels: string[]
) {
let hints = parsed.sampleHints
if (!hints.length) {
const matched = matchCellSampleType(parsed.sampleTypeHeader, sampleTypeOptions.value)
if (matched) {
hints = [{ typeKey: 'hsc', typeName: matched.typeName }]
}
}
for (const hint of hints) {
const matchedType = matchSampleTypeByExactName(hint.typeName, sampleTypeOptions.value)
const sample = normalizeSampleRow({ sampleTypeId: '', sampleStatus: 'ycj' }, formData.samples.length)
formData.samples.push(sample)
if (matchedType) {
sample.sampleTypeId = matchedType.id
sample.storageYears = matchedType.storageYears ?? null
sample.originalPrice = matchedType.storagePrice ?? null
sample.price = matchedType.storagePrice ?? null
if (!sampleTypeOptions.value.some((x) => x.id === matchedType.id)) {
sampleTypeOptions.value = [matchedType, ...sampleTypeOptions.value]
}
filledLabels.push(hint.typeName)
} else {
warnings.push(`无法匹配样本类型「${hint.typeName}」`)
}
if (hint.sampleCode) {
const sc = await resolveSampleCodeByCode(hint.sampleCode)
if (sc) {
sample.sampleCodeId = sc.id
sample.sampleCode = sc.sampleCode
if (!sampleCodeOptions.value.some((x) => x.id === sc.id)) {
sampleCodeOptions.value = [sc, ...sampleCodeOptions.value]
}
filledLabels.push('样本编码')
} else {
warnings.push(`未找到样本编码「${hint.sampleCode}」`)
}
}
applyParsedTransportToSample(sample, parsed, warnings, filledLabels)
}
}
function syncFormSamplesAfterImport() {
formData.samples = formData.samples.map((s, i) =>
normalizeSampleRow(
{
...s,
transport: s.transport ? { ...s.transport } : undefined
},
i
)
)
hydrateSampleLookupOptions()
}
function applyPaymentFromImport(parsed: ProtocolStandardImportParsed, warnings: string[]) {
formData.payMode = parsed.payMode || 'dj'
lastConfirmedPayMode.value = formData.payMode as PayMode
if (parsed.payMode === 'fq') {
applyFqPaymentDefaults()
}
if (parsed.contractAmount != null) {
formData.contractAmount = parsed.contractAmount
}
const transferTypeCode = resolveTransferTypeCode(
parsed.transferTypeLabel || '',
transferTypeOptions.value
)
if (parsed.transferTypeLabel && !transferTypeCode) {
warnings.push(`无法匹配转账方式「${parsed.transferTypeLabel}」`)
}
const now = new Date()
const pad = (n: number) => String(n).padStart(2, '0')
const defaultTime = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
formData.paymentDetails = []
const transfers = parsed.paymentTransfers.filter((t) => t.transferAmount > 0)
if (transfers.length) {
transfers.forEach((t, i) => {
formData.paymentDetails.push({
transferType: transferTypeCode,
dueAmount: t.transferAmount,
transferAmount: t.transferAmount,
transferTime: t.transferTime || defaultTime,
payStatus: 'dfj',
installmentDueDate: formData.payMode === 'dj' ? formData.lumpSumDeadline : '',
_expanded: i === 0,
attachments: []
})
})
} else if (formData.payMode === 'dj' && formData.contractAmount != null) {
addPaymentDetail()
const detail = formData.paymentDetails[0]
if (detail) {
detail.transferType = transferTypeCode
detail.dueAmount = formData.contractAmount
detail.transferAmount = formData.contractAmount
}
}
initPaymentDetailExpandFlags(formData.paymentDetails)
markPayDetailLocks(formData.paymentDetails)
if (!transfers.length && !(formData.payMode === 'dj' && formData.contractAmount != null)) {
syncPaymentDueAmounts()
}
if (parsed.contractAmount != null && transfers.length) {
const sum = transfers.reduce((acc, t) => acc + Number(t.transferAmount || 0), 0)
if (Math.abs(sum - Number(parsed.contractAmount)) > 0.01) {
warnings.push(
`转账合计 ${sum} 与合同金额 ${parsed.contractAmount} 不一致,请核对缴费明细`
)
}
}
}
async function handleStandardImport() {
const parsed = parseProtocolStandardImportText(standardImportText.value)
if (!parsed) {
ElMessage.warning('请粘贴有效的标准信息')
return
}
standardImportLoading.value = true
const warnings: string[] = []
const filledLabels: string[] = []
try {
clearFormBeforeStandardImport()
await ensureTransferTypeOptions()
await remoteSearchSampleTypes('')
const tasks: Promise<void>[] = []
if (parsed.motherName) {
tasks.push(
applyMotherByName(parsed.motherName).then((result) => {
if (result === 'linked') filledLabels.push('母亲信息(已关联客户)')
else if (result === 'name-only') filledLabels.push('母亲姓名')
})
)
}
if (parsed.hospitalName) {
tasks.push(
applyHospitalByName(parsed.hospitalName).then((ok) => {
if (ok) filledLabels.push('采集地区/采集医院')
else if (isBlankString(formData.hospitalId)) {
warnings.push(`未找到采集医院「${parsed.hospitalName}」`)
}
})
)
}
if (parsed.salesUserName) {
tasks.push(
applySalesUserByName(parsed.salesUserName).then((ok) => {
if (ok) filledLabels.push('采集专员/销售人员')
else warnings.push(`未找到销售人员「${parsed.salesUserName}」`)
})
)
}
const needsTransport = !!parsed.transportType
if (needsTransport) {
tasks.push(remoteSearchSites('').then(() => undefined))
if (parsed.transportType === 'kdys') {
tasks.push(
remoteSearchExpressCompanies(
(parsed.transportModeText || '').replace(/快递$/, '') || '顺丰'
).then(() => undefined)
)
}
}
await Promise.all(tasks)
if (parsed.motherPhone) {
formData.motherPhone = parsed.motherPhone
filledLabels.push('孕妇电话')
}
if (parsed.newbornSex) {
formData.newbornSex = parsed.newbornSex
filledLabels.push('新生儿性别')
}
if (parsed.newbornWeightGram != null) {
formData.newbornWeightGram = parsed.newbornWeightGram
filledLabels.push('新生儿体重')
}
if (parsed.apgarScore != null) {
formData.apgar1min = parsed.apgarScore
filledLabels.push('新生儿评分')
}
if (parsed.newbornDeliveryTime) {
formData.newbornDeliveryTime = parsed.newbornDeliveryTime
filledLabels.push('新生儿分娩时间')
}
if (parsed.sampleCollectTime) {
formData.sampleCollectTime = formatDatetimeToMinute(parsed.sampleCollectTime)
filledLabels.push('样本采集时间')
}
if (parsed.maternalBloodExplicitEmpty) {
formData.maternalBloodCollectTime = ''
filledLabels.push('母血采集时间')
} else if (parsed.maternalBloodCollectTime) {
formData.maternalBloodCollectTime = formatDatetimeToMinute(parsed.maternalBloodCollectTime)
filledLabels.push('母血采集时间')
}
if (parsed.deliveryMode) {
formData.deliveryMode = parsed.deliveryMode
filledLabels.push('分娩方式')
}
if (parsed.birthOrder != null) {
formData.birthOrder = parsed.birthOrder
filledLabels.push('胎次')
}
if (parsed.medicalStaff) {
formData.medicalStaff = parsed.medicalStaff
filledLabels.push('采集医护')
}
if (parsed.remark) {
formData.remark = parsed.remark
filledLabels.push('备注')
}
await applySampleHintsFromImport(parsed, warnings, filledLabels)
if (formData.samples.length) {
syncFormSamplesAfterImport()
}
applyPaymentFromImport(parsed, warnings)
if (parsed.contractAmount != null) {
filledLabels.push('合同金额')
const sampleTotal = formData.samples.reduce(
(sum, s) => sum + (Number(s.price) || 0),
0
)
if (sampleTotal > 0 && Math.abs(sampleTotal - Number(parsed.contractAmount)) > 0.01) {
warnings.push(
`样本优惠价合计 ${sampleTotal} 与合同金额 ${parsed.contractAmount} 不一致,请核对样本价格`
)
}
}
if (parsed.transportModeText && !parsed.transportType) {
warnings.push(`无法识别运输方式「${parsed.transportModeText}」`)
}
const uniqueFilled = [...new Set(filledLabels)]
if (uniqueFilled.length) {
ElMessage.success(`已填充:${uniqueFilled.join('、')}`)
} else if (!warnings.length) {
ElMessage.info('没有可填充的字段')
}
if (warnings.length) {
ElMessage.warning(warnings.join(';'))
}
} catch {
ElMessage.error('导入失败,请检查标准信息格式')
} finally {
standardImportLoading.value = false
}
}
/* ====== 客户检索(母亲信息) ====== */
function formatCustomerLabel(c: { customerName: string; phoneNo: string; idCardNo: string }) {
const parts = [c.customerName || '']
@@ -2554,6 +3117,20 @@
handleFqParamsChange()
}
/** 缴费明细应缴金额变更:分期模式下回写分期金额,保持与主表一致 */
function onPaymentDetailDueAmountChange(dIdx: number) {
if (formData.payMode !== 'fq') return
const detail = formData.paymentDetails[dIdx]
if (!detail || isPayDetailLocked(detail)) return
const installmentNo = Number(detail.installmentNo)
const ratioIdx = installmentNo >= 1 ? installmentNo - 1 : dIdx
if (!formData.installmentRatios) formData.installmentRatios = []
while (formData.installmentRatios.length <= ratioIdx) {
formData.installmentRatios.push(0)
}
formData.installmentRatios[ratioIdx] = Number(detail.dueAmount) || 0
}
const installmentAmountsError = computed(() => {
const amounts = formData.installmentRatios || []
if (!amounts.length || formData.contractAmount == null) return ''
@@ -2867,6 +3444,29 @@
&--green {
background: #f0fdf4;
}
&--import {
margin-bottom: 0;
}
}
.import-actions {
display: flex;
justify-content: flex-end;
padding: 0 0 8px;
}
.form-tab-pane--import-basic {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: 16px;
align-items: stretch;
margin-bottom: 28px;
.section-card {
margin-bottom: 0;
height: 100%;
}
}
.section-title {
@@ -3318,6 +3918,10 @@
RESPONSIVE
═══════════════════════════════════════════ */
@media (max-width: 900px) {
.form-tab-pane--import-basic {
grid-template-columns: 1fr;
}
.form-grid {
grid-template-columns: repeat(2, 1fr);
@@ -97,7 +97,7 @@
<el-dropdown-item v-if="hasPrimaryTaskActions(row)" command="view">
<el-icon><View /></el-icon>查看
</el-dropdown-item>
<el-dropdown-item v-if="canDeleteTask(row)" command="delete" divided>
<el-dropdown-item command="delete" divided>
<el-icon><Delete /></el-icon>删除
</el-dropdown-item>
</el-dropdown-menu>
@@ -763,17 +763,9 @@
return base
}
/** 待执行时可删除(仅工单管理视图) */
function canDeleteTask(row: QcTask) {
return listMode.value === 'workOrder' && row.taskStatus === 'dzx'
}
/** 更多菜单是否展示 */
function hasMoreTaskActions(row: QcTask) {
if (hasPrimaryTaskActions(row)) {
return true
}
return canDeleteTask(row)
/** 更多菜单是否展示(删除始终可用,故始终展示) */
function hasMoreTaskActions(_row: QcTask) {
return true
}
function handleDropdownCommand(command: string, row: QcTask) {
@@ -719,9 +719,11 @@
import {
parseDonationStandardImportText,
matchCellSampleType,
matchSampleTypeByExactName,
matchExpressCompany,
isBlankString,
isEmptyNumber
isEmptyNumber,
type DonationStandardImportParsed
} from '@/utils/donation-standard-import-parse'
import {
fetchCustomerList,
@@ -1987,6 +1989,152 @@
}
}
/** 一键导入前清空上次导入/手填的可覆盖字段(保留捐赠状态、日期、附件等) */
function clearFormBeforeStandardImport() {
customerId.value = null
customerSnapshot.value = null
formData.customerId = ''
formData.motherName = ''
formData.motherPhone = ''
formData.motherIdCard = ''
formData.motherBirthYm = ''
formData.motherEmail = ''
formData.motherAddress = ''
formData.newbornSex = ''
formData.newbornWeightGram = null
formData.apgar1min = null
formData.apgar5min = null
formData.newbornDeliveryTime = ''
formData.deliveryMode = ''
formData.birthOrder = null
formData.regionId = ''
formData.hospitalId = ''
formData.medicalStaff = ''
formData.sampleCollectTime = ''
formData.maternalBloodCollectTime = ''
collectorUserId.value = null
collectorSnapshot.value = null
collectorUserOptions.value = []
formData.collectorUserId = ''
salesUserId.value = null
salesSnapshot.value = null
salesUserOptions.value = []
formData.salesUserId = ''
formData.samples = []
sampleCodeOptions.value = []
}
function applyParsedTransportToSample(
sample: Record<string, any>,
parsed: DonationStandardImportParsed,
warnings: string[],
filledLabels: string[]
) {
if (!parsed.transportType) return
const transport = { ...(sample.transport || createEmptyTransport()) }
let transportFilled = false
if (isBlankString(transport.transportType)) {
transport.transportType = parsed.transportType
transportFilled = true
}
if (isBlankString(transport.destSiteId) && siteOptions.value.length) {
const site = siteOptions.value[0]
transport.destSiteId = site.id
transport.destSiteName = site.siteName || ''
transportFilled = true
}
if (isBlankString(transport.etaTime)) {
transport.etaTime = formatNowDatetime()
transportFilled = true
}
if (parsed.transportType === 'kdys' && isBlankString(transport.expressCompanyId)) {
const ec = matchExpressCompany(
parsed.transportModeText || '顺丰快递',
expressCompanyOptions.value
)
if (ec) {
transport.expressCompanyId = ec.id
if (!expressCompanyOptions.value.some((x) => x.id === ec.id)) {
expressCompanyOptions.value = [ec, ...expressCompanyOptions.value]
}
transportFilled = true
} else {
warnings.push(`未找到快递公司「${parsed.transportModeText || ''}」`)
}
}
sample.transport = transport
if (transportFilled) filledLabels.push('运输信息')
}
async function applySampleHintsFromImport(
parsed: DonationStandardImportParsed,
warnings: string[],
filledLabels: string[]
) {
for (const hint of parsed.sampleHints) {
const matchedType = matchSampleTypeByExactName(hint.typeName, sampleTypeOptions.value)
let sample = matchedType
? formData.samples.find((s) => s.sampleTypeId === matchedType.id)
: undefined
if (!sample) {
sample = formData.samples.find((s) => isBlankString(s.sampleTypeId))
}
if (!sample) {
sample = normalizeSampleRow({ sampleTypeId: '', sampleStatus: 'ycj' })
formData.samples.push(sample)
}
if (matchedType && isBlankString(sample.sampleTypeId)) {
sample.sampleTypeId = matchedType.id
sample.storageYears = matchedType.storageYears ?? null
if (!sampleTypeOptions.value.some((x) => x.id === matchedType.id)) {
sampleTypeOptions.value = [matchedType, ...sampleTypeOptions.value]
}
filledLabels.push(hint.typeName)
} else if (!matchedType && isBlankString(sample.sampleTypeId)) {
warnings.push(`无法匹配样本类型「${hint.typeName}」`)
}
try {
await assignDonationSampleCodeIfMissing(sample)
if (String(sample.sampleCode || '').trim()) {
filledLabels.push('样本编码')
}
} catch {
warnings.push('样本编码自动生成失败')
}
applyParsedTransportToSample(sample, parsed, warnings, filledLabels)
}
}
/** 导入后重建样本行引用,确保样本及运输列表列刷新(与编辑样本弹窗确定逻辑一致) */
function syncFormSamplesAfterImport() {
formData.samples = formData.samples.map((s) => {
const row = normalizeSampleRow({
...s,
transport: s.transport ? { ...s.transport } : undefined
})
const destSiteId = String(row.transport?.destSiteId || '')
if (destSiteId && isBlankString(row.transport?.destSiteName)) {
const site = siteOptions.value.find((x) => x.id === destSiteId)
if (site?.siteName && site.siteName !== site.id) {
row.transport.destSiteName = site.siteName
}
}
return row
})
hydrateSampleLookupOptions()
}
async function handleStandardImport() {
const parsed = parseDonationStandardImportText(standardImportText.value)
if (!parsed) {
@@ -1999,6 +2147,7 @@
const filledLabels: string[] = []
try {
clearFormBeforeStandardImport()
await remoteSearchSampleTypes('')
const tasks: Promise<void>[] = []
@@ -2032,14 +2181,16 @@
)
}
const needsTransport = !!parsed.transportExpressName
const needsTransport = !!parsed.transportType
if (needsTransport) {
tasks.push(
remoteSearchSites('').then(() => undefined),
remoteSearchExpressCompanies(
(parsed.transportExpressName || '').replace(/快递$/, '') || '顺丰'
).then(() => undefined)
)
tasks.push(remoteSearchSites('').then(() => undefined))
if (parsed.transportType === 'kdys') {
tasks.push(
remoteSearchExpressCompanies(
(parsed.transportModeText || '').replace(/快递$/, '') || '顺丰'
).then(() => undefined)
)
}
}
await Promise.all(tasks)
@@ -2087,78 +2238,62 @@
filledLabels.push('采集医护')
}
const matchedType = matchCellSampleType(parsed.sampleTypeHeader, sampleTypeOptions.value)
const needsSampleRow = !!matchedType || needsTransport
if (parsed.sampleHints.length > 0) {
await applySampleHintsFromImport(parsed, warnings, filledLabels)
} else {
const matchedType = matchCellSampleType(parsed.sampleTypeHeader, sampleTypeOptions.value)
const needsSampleRow = !!matchedType || needsTransport
if (needsSampleRow) {
if (!formData.samples.length) {
formData.samples = [normalizeSampleRow({ sampleTypeId: '', sampleStatus: 'ycj' })]
}
const sample = formData.samples[0]
if (needsSampleRow) {
if (!formData.samples.length) {
formData.samples = [normalizeSampleRow({ sampleTypeId: '', sampleStatus: 'ycj' })]
}
const sample = formData.samples[0]
if (matchedType && isBlankString(sample.sampleTypeId)) {
sample.sampleTypeId = matchedType.id
sample.storageYears = matchedType.storageYears ?? null
if (!sampleTypeOptions.value.some((x) => x.id === matchedType.id)) {
sampleTypeOptions.value = [matchedType, ...sampleTypeOptions.value]
}
filledLabels.push('样本类型')
} else if (parsed.sampleTypeHeader && !matchedType && isBlankString(sample.sampleTypeId)) {
warnings.push(`无法匹配样本类型「${parsed.sampleTypeHeader}」`)
}
if (needsTransport) {
const transport = { ...(sample.transport || createEmptyTransport()) }
let transportFilled = false
if (isBlankString(transport.transportType)) {
transport.transportType = 'kdys'
transportFilled = true
}
if (isBlankString(transport.destSiteId) && siteOptions.value.length) {
transport.destSiteId = siteOptions.value[0].id
transportFilled = true
}
if (isBlankString(transport.etaTime)) {
transport.etaTime = formatNowDatetime()
transportFilled = true
}
if (isBlankString(transport.expressCompanyId)) {
const ec = matchExpressCompany(
parsed.transportExpressName || '顺丰快递',
expressCompanyOptions.value
)
if (ec) {
transport.expressCompanyId = ec.id
if (!expressCompanyOptions.value.some((x) => x.id === ec.id)) {
expressCompanyOptions.value = [ec, ...expressCompanyOptions.value]
}
transportFilled = true
} else {
warnings.push(`未找到快递公司「${parsed.transportExpressName}」`)
if (matchedType && isBlankString(sample.sampleTypeId)) {
sample.sampleTypeId = matchedType.id
sample.storageYears = matchedType.storageYears ?? null
if (!sampleTypeOptions.value.some((x) => x.id === matchedType.id)) {
sampleTypeOptions.value = [matchedType, ...sampleTypeOptions.value]
}
filledLabels.push('样本类型')
} else if (
parsed.sampleTypeHeader &&
!matchedType &&
isBlankString(sample.sampleTypeId)
) {
warnings.push(`无法匹配样本类型「${parsed.sampleTypeHeader}」`)
}
sample.transport = transport
if (transportFilled) filledLabels.push('运输信息')
}
try {
await assignDonationSampleCodeIfMissing(sample)
if (String(sample.sampleCode || '').trim()) {
filledLabels.push('样本编码')
if (needsTransport) {
applyParsedTransportToSample(sample, parsed, warnings, filledLabels)
}
} catch {
warnings.push('样本编码自动生成失败')
}
hydrateSampleLookupOptions()
} else if (parsed.sampleTypeHeader) {
const sample = formData.samples[0]
const matched = matchCellSampleType(parsed.sampleTypeHeader, sampleTypeOptions.value)
if (!matched && (!sample || isBlankString(sample.sampleTypeId))) {
warnings.push(`无法匹配样本类型「${parsed.sampleTypeHeader}」`)
try {
await assignDonationSampleCodeIfMissing(sample)
if (String(sample.sampleCode || '').trim()) {
filledLabels.push('样本编码')
}
} catch {
warnings.push('样本编码自动生成失败')
}
} else if (parsed.sampleTypeHeader) {
const sample = formData.samples[0]
const matched = matchCellSampleType(parsed.sampleTypeHeader, sampleTypeOptions.value)
if (!matched && (!sample || isBlankString(sample.sampleTypeId))) {
warnings.push(`无法匹配样本类型「${parsed.sampleTypeHeader}」`)
}
}
}
if (formData.samples.length) {
syncFormSamplesAfterImport()
}
if (parsed.transportModeText && !parsed.transportType) {
warnings.push(`无法识别运输方式「${parsed.transportModeText}」`)
}
const uniqueFilled = [...new Set(filledLabels)]
if (uniqueFilled.length) {
ElMessage.success(`已填充:${uniqueFilled.join('、')}`)