zlwu 4 tháng trước cách đây
mục cha
commit
817dfff43c
100 tập tin đã thay đổi với 2819 bổ sung và 1802 xóa
  1. 1 1
      backend/app.pid
  2. 2 0
      backend/app/api/pilot_service.py
  3. 222 70
      backend/app/crud/outbound_handover_inventory.py
  4. 8 8
      backend/app/crud/outbound_release_material.py
  5. 49 15
      backend/app/crud/outbound_release_review.py
  6. 1 0
      backend/app/crud/pilot_infusion_schedule_mgmt.py
  7. 5 1
      backend/app/crud/pilot_outbound_status_sync.py
  8. 35 16
      backend/app/crud/pilot_service.py
  9. 124 32
      backend/app/crud/qc_work_order.py
  10. 0 0
      backend/app/graphify-out/cache/ast/098e2895af990740a8c04a027b8159db1855fbd3aa0c02c1a043fbdbe6ed9c73.json
  11. 0 0
      backend/app/graphify-out/cache/ast/2dc202ecf4e1448d81904387ae1f120bd7216aceb73388c0a6b35a1842f6bdcc.json
  12. 0 0
      backend/app/graphify-out/cache/ast/473a1f11b4bd699d31117c1729237d28926ce64c4eba076ce0fb2cdcfb24438f.json
  13. 0 0
      backend/app/graphify-out/cache/ast/6392d99ffb8d96094d254eb926f7016de67f49c75e11f7cfed6d2b5f3c12d9a4.json
  14. 0 0
      backend/app/graphify-out/cache/ast/6d03b440aaf41bc7fed10a1ba61634c13bc365db841bb4205d5ebea3bea808c6.json
  15. 0 0
      backend/app/graphify-out/cache/ast/80ff4d99f0f374f7532c1d8edf194f1e663982470fd00a30019df92035ccf38c.json
  16. 0 0
      backend/app/graphify-out/cache/ast/8e54eae994db3a9274b19756489bac0c84c5115cd451b723daee09bcc7de65e0.json
  17. 0 0
      backend/app/graphify-out/cache/ast/9a546303c18c1f714014958e869476c25ab1280eac2704256f798b89b8ae3512.json
  18. 0 0
      backend/app/graphify-out/cache/ast/abdff0d5150ff2ed866d94efed509e966213ec069e88c55bdef5d03b675ba177.json
  19. 0 0
      backend/app/graphify-out/cache/ast/e28b7cbc542ef7ce058956fcfc5a2d377b5fe88db57f5541cb566ad3ac561624.json
  20. 1 1
      backend/app/models/models.py
  21. 575 272
      backend/graphify-out/.graphify_analysis.json
  22. 227 150
      backend/graphify-out/.graphify_extract.json
  23. 77 137
      backend/graphify-out/GRAPH_REPORT.md
  24. 1 1
      backend/graphify-out/graph.html
  25. 112 112
      backend/graphify-out/graph.json
  26. 9 9
      backend/graphify-out/manifest.json
  27. 7 8
      docs/panel-tab-demos/_shared.css
  28. 12 0
      docs/sql/alter_biz_qc_work_order_outbound_trigger_source_schedule.sql
  29. 441 436
      web-admin/graphify-out/.graphify_analysis.json
  30. 264 159
      web-admin/graphify-out/.graphify_extract.json
  31. 109 126
      web-admin/graphify-out/GRAPH_REPORT.md
  32. 1 1
      web-admin/graphify-out/graph.html
  33. 153 117
      web-admin/graphify-out/graph.json
  34. 64 63
      web-admin/graphify-out/manifest.json
  35. 2 0
      web-admin/src/api/outbound-release-review.ts
  36. 6 0
      web-admin/src/api/qc-work-order.ts
  37. 220 19
      web-admin/src/assets/styles/core/app.scss
  38. 9 2
      web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue
  39. 9 6
      web-admin/src/components/business/outbound-material-form-sections/index.vue
  40. 1 0
      web-admin/src/components/business/sample-qc-info-cards/index.vue
  41. 44 40
      web-admin/src/components/business/sample-qc-info-grouped-panel/index.vue
  42. 0 0
      web-admin/src/graphify-out/cache/ast/00d400955a62e83d40a52b3cd9debde813d8139e4c7347f78d56529ea8577b28.json
  43. 1 0
      web-admin/src/graphify-out/cache/ast/041e5b6eea36082aef31b456e3f3452fda034a13e1e3a362f9652a9ac5d2fb97.json
  44. 0 0
      web-admin/src/graphify-out/cache/ast/06c0b5b8453611137332aab18062a5261b21c0f069f35171b49a2ad7911368ed.json
  45. 0 0
      web-admin/src/graphify-out/cache/ast/09be959089c5a1259c6797fdec2718d20a026361b0875c1292e6810f1220d48e.json
  46. 1 0
      web-admin/src/graphify-out/cache/ast/130e78d331d0fc642283c4aa2647e5b634cea40f98d7d6ded3b465c8a7434ebb.json
  47. 1 0
      web-admin/src/graphify-out/cache/ast/173a225e66c378635376adce467f56ff95d39dd799d2e320f0b4ea5f711513d1.json
  48. 0 0
      web-admin/src/graphify-out/cache/ast/18a594816c6e89957a83f856c71e9a6d14b92226a6d16def761c1e14d4423e45.json
  49. 1 0
      web-admin/src/graphify-out/cache/ast/1c56b81482396e3aceb3051dba7cec42f6ee5c1eff159e590a3bebdf60816c57.json
  50. 0 0
      web-admin/src/graphify-out/cache/ast/1cb4b69d3ca69cee91a2758dd505cad427618c6752545bdadd8ebedcf5022e72.json
  51. 0 0
      web-admin/src/graphify-out/cache/ast/1fa3950e774787977360e3d61c0b2fcf1612c95a4f146198ca66e9858e7d9fdc.json
  52. 1 0
      web-admin/src/graphify-out/cache/ast/2ba83168b702d44f8d92439a4b9ecc150d16cee01103fa07674d8918db01a63c.json
  53. 1 0
      web-admin/src/graphify-out/cache/ast/2c6f5f15436cf42ed22dea3ec6946f85a5b8c06f0ada2aa06fcdf5187bdbe513.json
  54. 0 0
      web-admin/src/graphify-out/cache/ast/30bcc0a66a8c7357652ca6d70c7407f425d1c54201aad8a56fa310c8ce9e4c15.json
  55. 0 0
      web-admin/src/graphify-out/cache/ast/30c59d440a6872e8166410b047a919e4fa8d4f1ea80c45a3e96437a943cacf56.json
  56. 0 0
      web-admin/src/graphify-out/cache/ast/33b08f1faecf3140a52477d55f835f889ee0f704558388a8b68caf26bece603d.json
  57. 0 0
      web-admin/src/graphify-out/cache/ast/3770b8f2348484a7a9940b567e5b2089008625ea1936ae0f2e5586bf283e028f.json
  58. 0 0
      web-admin/src/graphify-out/cache/ast/384ce5249283a3d2a46158a4ac6df87f1c522cac7cb180b379cb37d78975e031.json
  59. 0 0
      web-admin/src/graphify-out/cache/ast/396ddb8c02c71a1e2e2fa357a3c7f6c1a7b3fbb8d65698561aca8c75705dbbd7.json
  60. 1 0
      web-admin/src/graphify-out/cache/ast/3af1c66117392690e36e73263684a59248ff2c759fe4d14178059f196d55f697.json
  61. 1 0
      web-admin/src/graphify-out/cache/ast/3e738b9cfef74ba6e8e5e89727ec771e3e24f4632cbb8121ef67a822833ed7ee.json
  62. 0 0
      web-admin/src/graphify-out/cache/ast/45771d50ec2df425a694aefb97bb9b823c6228a84ac2ff6d4e411214c3e12cb9.json
  63. 1 0
      web-admin/src/graphify-out/cache/ast/494cfd6995ffa31172179478f2729f4e43f00bf353bb16861b3aed6d4c7e0d27.json
  64. 1 0
      web-admin/src/graphify-out/cache/ast/4b4ad7c6acb524b90d1324a2580788f8553ff9ba83e8fed8d69d96bba8a75053.json
  65. 1 0
      web-admin/src/graphify-out/cache/ast/5280ad16c1dd0eb472561a1a28b5dde65ae625c2fce95d7556bafa7530a25828.json
  66. 1 0
      web-admin/src/graphify-out/cache/ast/53330f8f92ac42a69f7308ff6942dff5084d51752257fc7d034d8fedd62449a9.json
  67. 0 0
      web-admin/src/graphify-out/cache/ast/55c124b3e54db58de69afef1ddd1dad032fe00c409d77c731569a7c71bf6d7ff.json
  68. 1 0
      web-admin/src/graphify-out/cache/ast/61fd1ff27201c7bea915f68110a35f17f7810ce84f9f82f4d17f6618ab09aa5d.json
  69. 1 0
      web-admin/src/graphify-out/cache/ast/64ab9f30e87b365813bd12bb63a951483e0fd8d26e7ae3092d8071fd7c704463.json
  70. 0 0
      web-admin/src/graphify-out/cache/ast/67f9f5f46d9c949db0435ea2455d18ea2f4894d396f664b421f928e85b04d193.json
  71. 1 0
      web-admin/src/graphify-out/cache/ast/6965fd9f880af2878674a155edc5d17fdd92fbbdb5eac4c114325364064632c4.json
  72. 1 0
      web-admin/src/graphify-out/cache/ast/707f82b5aa5697b356a0c435cf3c919b0fba12a37373b8e7ef1f1c852f05bcdb.json
  73. 0 0
      web-admin/src/graphify-out/cache/ast/75944460e46ef27212fa7afccf5bc73d0b0fa502b0bbf9f3224c4022f968c2d6.json
  74. 0 0
      web-admin/src/graphify-out/cache/ast/75f0a0134f5772c1d32c5be1b194eb6003c7cd983f41b8680d973541dcc7ca0e.json
  75. 0 0
      web-admin/src/graphify-out/cache/ast/76e4eb9cfc7b336e6dac097aa3fe05932d1713d45ba86e3bcbd23ba1f6fc95b3.json
  76. 0 0
      web-admin/src/graphify-out/cache/ast/771e1acf4e2a7750272e7a350200d4d7ed2abcb86a091d6887665e59acb79722.json
  77. 0 0
      web-admin/src/graphify-out/cache/ast/7be99455eb3b3873d076644d5d3d5506bde7f9d8ae1940b636c85cb50b931573.json
  78. 1 0
      web-admin/src/graphify-out/cache/ast/7fef75f59527a909b8868a0d9c75209260f0c3c0fd647c5214056df6262589c4.json
  79. 0 0
      web-admin/src/graphify-out/cache/ast/848b570bbd3a09b44fcb96a0863231b9076ac5e8edd3a09baf48f5c8228f27c2.json
  80. 0 0
      web-admin/src/graphify-out/cache/ast/8508cda6e23c47dce4251e3ca96eca4b237275eb47200c9049e1ca0cdb2012b9.json
  81. 0 0
      web-admin/src/graphify-out/cache/ast/86b9f8187b3798a28a113bd16483a4845a50710dede1c6e0d81b7f682e7f2b36.json
  82. 1 0
      web-admin/src/graphify-out/cache/ast/89110193ec193ba0e3f825809af8cf324185524922c92c3fca72598de9e9488f.json
  83. 0 0
      web-admin/src/graphify-out/cache/ast/9ab8112557bb3323eef8ab53b7c35e9eb93610bb178714fc847b38ff11712472.json
  84. 1 0
      web-admin/src/graphify-out/cache/ast/9f0b9588a2eee159514775f95ddc891d2123dd716b883813749c0d36df6a0b25.json
  85. 1 0
      web-admin/src/graphify-out/cache/ast/a0c0afa7bb284d1939002cb55e870b3a82fa267a23b24f21a1008a41db2bb748.json
  86. 1 0
      web-admin/src/graphify-out/cache/ast/a0f0c8011045baf2401c8a75226f844c95b8c7351a58a7c969646b15ca71201b.json
  87. 0 0
      web-admin/src/graphify-out/cache/ast/a1adcd2a84f506fbf814c728bf05ed7f7ad497f5b2c4023f02cf0ef3c1a21c05.json
  88. 0 0
      web-admin/src/graphify-out/cache/ast/a4825f88608a4281634df573f530a899d42ee189037b2ab2bc7aaa2983083942.json
  89. 0 0
      web-admin/src/graphify-out/cache/ast/a948a5a61d367bf15f86067a4b0ed26279513e89af19c61c095440719fc39414.json
  90. 1 0
      web-admin/src/graphify-out/cache/ast/a9bc9afa400193997fd49f72eefd3d0aa24360385bf4b7d4b2c1e8c096e44121.json
  91. 0 0
      web-admin/src/graphify-out/cache/ast/ac17fe7b02f680fc1127c51c132b637fd51ab00a5286c7704fe4a4b7bf2c01db.json
  92. 1 0
      web-admin/src/graphify-out/cache/ast/b7e1c76a9591a8c32f983074c63cba294e198c3f1337f96afd58bec9a89729d5.json
  93. 1 0
      web-admin/src/graphify-out/cache/ast/b88baee832990513f2f36b79c8aced0fff2f91e2b712bc2b01f0fa07d62b3fd0.json
  94. 1 0
      web-admin/src/graphify-out/cache/ast/ba341174c25128f0e296962de19aea41e23e50ea212500f05a6648a2bac8ba1c.json
  95. 0 0
      web-admin/src/graphify-out/cache/ast/bacf2089fe890969d977c2733641e6779966638f2b0f4491b5210d679cf86016.json
  96. 0 0
      web-admin/src/graphify-out/cache/ast/c1011a236780c8788382cdd431c174659d2912c0764c57a644ea4de9c21aa10c.json
  97. 0 0
      web-admin/src/graphify-out/cache/ast/c9c3998fc006ef16fdd6a476202e3779b3aac1b868d6e3e70bb7bbd6d0cf0c6e.json
  98. 1 0
      web-admin/src/graphify-out/cache/ast/c9fe7190a53ace0c56c079d77509c57fd1e7f978957de3a6c9f75400448aa2dd.json
  99. 1 0
      web-admin/src/graphify-out/cache/ast/cb66f03371e5c5b4eb2d48298236196567c2c96c7a8fbf9db05a96baa56ba69d.json
  100. 1 0
      web-admin/src/graphify-out/cache/ast/d0278637a57cacbe1934040a5176515e10207a6dec4d33a8f895d1e879291043.json

+ 1 - 1
backend/app.pid

@@ -1 +1 @@
-18456
+40943

+ 2 - 0
backend/app/api/pilot_service.py

@@ -1954,6 +1954,7 @@ async def list_service_order_txns(
     page: int = Query(1, ge=1),
     pageSize: int = Query(20, ge=1, le=100, alias="pageSize"),
     serviceOrderId: Optional[str] = Query(None, alias="serviceOrderId"),
+    channelId: Optional[str] = Query(None, alias="channelId"),
     txnStatus: Optional[str] = Query(None, alias="txnStatus"),
     txnType: Optional[str] = Query(None, alias="txnType"),
     keyword: Optional[str] = None,
@@ -1967,6 +1968,7 @@ async def list_service_order_txns(
     items, total = ps_svc.list_service_order_txns(
         db,
         service_order_id=serviceOrderId,
+        channel_id=channelId,
         txn_status=txnStatus,
         txn_type=txnType,
         keyword=keyword,

+ 222 - 70
backend/app/crud/outbound_handover_inventory.py

@@ -1,4 +1,4 @@
-"""输注计划出库交接 — 细胞产品状态与质检物料库存联动。"""
+"""输注计划出库交接 — 细胞产品状态与市场物料库存联动。"""
 from __future__ import annotations
 
 from datetime import datetime
@@ -10,11 +10,16 @@ from sqlalchemy.orm import Session
 
 from app.core.utils import generate_uuid
 from app.crud import storage_occupancy as occupancy_svc
+from app.crud.material import _is_enabled_status
+from app.crud.material_stock_batch import _get_material_for_update, _usage_batch_snapshots
+from app.models.material import BizMaterialStockBatch, BizMaterialUsage
 from app.models.models import BizCellProduct, BizStorageSlotOccupancy
 from app.models.qc_material import BizQcMaterial, BizQcMaterialUsage
 
 # 出库交接后细胞产品目标状态(已售卖/已出库)
 HANDOVER_CELL_OUT_STATUS = "sold"
+HANDOVER_MARKET_SOURCE_TYPE = "outbound_handover"
+# 历史数据:曾扣减质检物料库存
 HANDOVER_QC_SOURCE_TYPE = "outbound_handover"
 
 
@@ -153,20 +158,16 @@ def _get_cell_product_locked(
     return product
 
 
-def revert_handover_inventory(
+def _revert_legacy_qc_handover_usages(
     db: Session,
-    schedule_id: str,
     *,
-    cell_product_ids: Iterable[str],
+    schedule_id: str,
     tenant_no: str,
-    user_id: Optional[str] = None,
+    user_id: Optional[str],
+    remark_prefix: str,
+    now: datetime,
 ) -> None:
-    """回滚本输注计划上次出库交接产生的库存/状态变更(不 commit)。"""
-    sid = (schedule_id or "").strip()
-    if not sid:
-        return
-
-    remark_prefix = _handover_usage_remark_prefix(sid)
+    """回滚历史版本曾写入的质检物料出库交接记录。"""
     usage_rows = (
         db.query(BizQcMaterialUsage)
         .filter(
@@ -178,7 +179,6 @@ def revert_handover_inventory(
         )
         .all()
     )
-    now = datetime.now()
     for usage in usage_rows:
         restore_qty = abs(usage.change_qty) if usage.change_qty is not None else Decimal("0")
         if restore_qty > 0:
@@ -202,6 +202,93 @@ def revert_handover_inventory(
         usage.update_time = now
         db.add(usage)
 
+
+def _revert_market_handover_usages(
+    db: Session,
+    *,
+    schedule_id: str,
+    tenant_no: str,
+    user_id: Optional[str],
+    remark_prefix: str,
+    now: datetime,
+) -> None:
+    """回滚市场物料出库交接记录(含批次剩余量)。"""
+    usage_rows = (
+        db.query(BizMaterialUsage)
+        .filter(
+            BizMaterialUsage.tenant_no == tenant_no,
+            BizMaterialUsage.del_flag == 0,
+            BizMaterialUsage.source_type == HANDOVER_MARKET_SOURCE_TYPE,
+            BizMaterialUsage.change_type == "use",
+            BizMaterialUsage.remark.like(f"%{remark_prefix}%"),
+        )
+        .all()
+    )
+    for usage in usage_rows:
+        restore_qty = abs(usage.change_qty) if usage.change_qty is not None else Decimal("0")
+        if restore_qty > 0:
+            material = _get_material_for_update(db, usage.material_id, tenant_no)
+            material.stock_qty = (material.stock_qty or Decimal("0")) + restore_qty
+            material.update_by = user_id
+            material.update_time = now
+            db.add(material)
+
+            batch_id = (usage.batch_id or "").strip()
+            if batch_id:
+                batch = (
+                    db.query(BizMaterialStockBatch)
+                    .with_for_update()
+                    .filter(
+                        BizMaterialStockBatch.id == batch_id,
+                        BizMaterialStockBatch.tenant_no == tenant_no,
+                        BizMaterialStockBatch.del_flag == 0,
+                    )
+                    .first()
+                )
+                if batch:
+                    batch.remaining_qty = (batch.remaining_qty or Decimal("0")) + restore_qty
+                    batch.update_by = user_id
+                    batch.update_time = now
+                    db.add(batch)
+
+        usage.del_flag = 1
+        usage.update_by = user_id
+        usage.update_time = now
+        db.add(usage)
+
+
+def revert_handover_inventory(
+    db: Session,
+    schedule_id: str,
+    *,
+    cell_product_ids: Iterable[str],
+    tenant_no: str,
+    user_id: Optional[str] = None,
+) -> None:
+    """回滚本输注计划上次出库交接产生的库存/状态变更(不 commit)。"""
+    sid = (schedule_id or "").strip()
+    if not sid:
+        return
+
+    remark_prefix = _handover_usage_remark_prefix(sid)
+    now = datetime.now()
+    _revert_legacy_qc_handover_usages(
+        db,
+        schedule_id=sid,
+        tenant_no=tenant_no,
+        user_id=user_id,
+        remark_prefix=remark_prefix,
+        now=now,
+    )
+    _revert_market_handover_usages(
+        db,
+        schedule_id=sid,
+        tenant_no=tenant_no,
+        user_id=user_id,
+        remark_prefix=remark_prefix,
+        now=now,
+    )
+
     seen: Set[str] = set()
     for raw_id in cell_product_ids:
         cp_id = (raw_id or "").strip()
@@ -223,6 +310,116 @@ def revert_handover_inventory(
     db.flush()
 
 
+def _deduct_market_material_for_handover(
+    db: Session,
+    material_id: str,
+    qty: Decimal,
+    *,
+    schedule_id: str,
+    tenant_no: str,
+    user_id: Optional[str],
+    create_dept_id: str,
+    receiver_person: str,
+    line_remark: str,
+    now: datetime,
+) -> None:
+    """按 FIFO 从市场物料入库批次扣减,并写入变动记录。"""
+    material = _get_material_for_update(db, material_id, tenant_no)
+    if not _is_enabled_status(material.status):
+        raise HTTPException(
+            status_code=400,
+            detail=f"市场物料「{material.material_name}」已停用,无法出库",
+        )
+
+    stock_before = material.stock_qty if material.stock_qty is not None else Decimal("0")
+    if stock_before < qty:
+        raise HTTPException(
+            status_code=400,
+            detail=(
+                f"物料「{material.material_name}」库存不足,"
+                f"当前库存 {stock_before},需出库 {qty}"
+            ),
+        )
+
+    batches = (
+        db.query(BizMaterialStockBatch)
+        .with_for_update()
+        .filter(
+            BizMaterialStockBatch.material_id == material_id,
+            BizMaterialStockBatch.tenant_no == tenant_no,
+            BizMaterialStockBatch.del_flag == 0,
+            BizMaterialStockBatch.remaining_qty > 0,
+        )
+        .order_by(
+            BizMaterialStockBatch.stock_in_date.asc(),
+            BizMaterialStockBatch.create_time.asc(),
+        )
+        .all()
+    )
+
+    usage_remark = _handover_usage_remark(schedule_id)
+    receiver = (receiver_person or "").strip() or None
+    remaining = qty
+    running_stock = stock_before
+
+    for batch in batches:
+        if remaining <= 0:
+            break
+        rem = batch.remaining_qty if batch.remaining_qty is not None else Decimal("0")
+        if rem <= 0:
+            continue
+        take = min(rem, remaining)
+        batch.remaining_qty = rem - take
+        batch.update_by = user_id
+        batch.update_time = now
+        db.add(batch)
+
+        stock_after = running_stock - take
+        snaps = _usage_batch_snapshots(batch, out_qty=take)
+        db.add(
+            BizMaterialUsage(
+                id=generate_uuid(),
+                material_id=material.id,
+                material_code=material.material_code,
+                material_name=material.material_name,
+                change_type="use",
+                change_qty=-take,
+                usage_unit=(material.unit or "").strip() or None,
+                stock_before=running_stock,
+                stock_after=stock_after,
+                source_type=HANDOVER_MARKET_SOURCE_TYPE,
+                requisition_status="closed",
+                tenant_no=tenant_no,
+                receiver=receiver,
+                purpose="输注计划出库交接",
+                remark=usage_remark if not line_remark else f"{usage_remark};{line_remark}",
+                create_by=user_id,
+                create_dept_id=create_dept_id or "",
+                create_time=now,
+                update_by=user_id,
+                update_time=now,
+                del_flag=0,
+                **snaps,
+            )
+        )
+        running_stock = stock_after
+        remaining -= take
+
+    if remaining > 0:
+        raise HTTPException(
+            status_code=400,
+            detail=(
+                f"物料「{material.material_name}」批次库存不足,"
+                f"汇总库存 {stock_before},需出库 {qty},批次可分配 {qty - remaining}"
+            ),
+        )
+
+    material.stock_qty = stock_before - qty
+    material.update_by = user_id
+    material.update_time = now
+    db.add(material)
+
+
 def apply_handover_inventory(
     db: Session,
     schedule_id: str,
@@ -234,10 +431,8 @@ def apply_handover_inventory(
     create_dept_id: str = "",
     receiver_person: str = "",
 ) -> None:
-    """应用出库交接:细胞产品出库 + 质检物料扣减(不 commit)。"""
+    """应用出库交接:细胞产品出库 + 市场物料扣减(不 commit)。"""
     sid = (schedule_id or "").strip()
-    usage_remark = _handover_usage_remark(sid)
-    receiver = (receiver_person or "").strip() or None
     now = datetime.now()
 
     for item in cells or []:
@@ -265,7 +460,7 @@ def apply_handover_inventory(
         mid = (item.get("materialId") or item.get("material_id") or "").strip()
         qty_raw = item.get("qty")
         if not mid:
-            raise HTTPException(status_code=400, detail="质检物料ID不能为空")
+            raise HTTPException(status_code=400, detail="市场物料ID不能为空")
         try:
             qty_dec = Decimal(str(qty_raw))
         except Exception:
@@ -273,61 +468,18 @@ def apply_handover_inventory(
         if qty_dec <= 0:
             raise HTTPException(status_code=400, detail="物料用量必须大于0")
 
-        material = (
-            db.query(BizQcMaterial)
-            .with_for_update()
-            .filter(
-                BizQcMaterial.id == mid,
-                BizQcMaterial.tenant_no == tenant_no,
-                BizQcMaterial.del_flag == 0,
-                BizQcMaterial.status == "1",
-            )
-            .first()
-        )
-        if not material:
-            raise HTTPException(
-                status_code=400,
-                detail=f"质检物料不存在或已停用(ID: {mid})",
-            )
-
-        stock_before = material.stock_qty if material.stock_qty is not None else Decimal("0")
-        if stock_before < qty_dec:
-            raise HTTPException(
-                status_code=400,
-                detail=(
-                    f"物料「{material.material_name}」库存不足,"
-                    f"当前库存 {stock_before},需出库 {qty_dec}"
-                ),
-            )
-
-        stock_after = stock_before - qty_dec
-        material.stock_qty = stock_after
-        material.update_by = user_id
-        material.update_time = now
-        db.add(material)
-
         line_remark = (item.get("remark") or "").strip()
-        db.add(
-            BizQcMaterialUsage(
-                id=generate_uuid(),
-                material_id=mid,
-                material_code=material.material_code,
-                material_name=material.material_name,
-                change_type="use",
-                change_qty=-qty_dec,
-                stock_after=stock_after,
-                source_type=HANDOVER_QC_SOURCE_TYPE,
-                tenant_no=tenant_no,
-                receiver=receiver,
-                purpose="输注计划出库交接",
-                remark=usage_remark if not line_remark else f"{usage_remark};{line_remark}",
-                create_by=user_id,
-                create_dept_id=create_dept_id or "",
-                create_time=now,
-                update_by=user_id,
-                update_time=now,
-                del_flag=0,
-            )
+        _deduct_market_material_for_handover(
+            db,
+            mid,
+            qty_dec,
+            schedule_id=sid,
+            tenant_no=tenant_no,
+            user_id=user_id,
+            create_dept_id=create_dept_id,
+            receiver_person=receiver_person,
+            line_remark=line_remark,
+            now=now,
         )
 
     db.flush()

+ 8 - 8
backend/app/crud/outbound_release_material.py

@@ -18,7 +18,7 @@ from app.models.models import (
     BizOutboundReleaseQcMaterial,
     BizPilotInfusionSchedule,
 )
-from app.models.qc_material import BizQcMaterial
+from app.models.material import BizMaterial
 
 
 def _fmt_dt(t: Optional[datetime]) -> str:
@@ -310,7 +310,7 @@ def save_outbound_material(
     if len([x for x in cell_ids if x]) != len(set(x for x in cell_ids if x)):
         raise HTTPException(status_code=400, detail="同一输注计划中不能重复添加相同细胞产品")
     if len([x for x in qc_ids if x]) != len(set(x for x in qc_ids if x)):
-        raise HTTPException(status_code=400, detail="同一输注计划中不能重复添加相同质检物料")
+        raise HTTPException(status_code=400, detail="同一输注计划中不能重复添加相同物料")
 
     now = datetime.now()
 
@@ -431,7 +431,7 @@ def save_outbound_material(
         mid = (item.get("materialId") or item.get("material_id") or "").strip()
         qty_raw = item.get("qty")
         if not mid:
-            raise HTTPException(status_code=400, detail="质检物料ID不能为空")
+            raise HTTPException(status_code=400, detail="市场物料ID不能为空")
         try:
             qty_dec = Decimal(str(qty_raw))
         except Exception:
@@ -440,16 +440,16 @@ def save_outbound_material(
             raise HTTPException(status_code=400, detail="物料用量必须大于0")
 
         material = (
-            db.query(BizQcMaterial)
+            db.query(BizMaterial)
             .filter(
-                BizQcMaterial.id == mid,
-                BizQcMaterial.tenant_no == tenant_no,
-                BizQcMaterial.del_flag == 0,
+                BizMaterial.id == mid,
+                BizMaterial.tenant_no == tenant_no,
+                BizMaterial.del_flag == 0,
             )
             .first()
         )
         if not material:
-            raise HTTPException(status_code=400, detail=f"质检物料不存在或已删除(ID: {mid})")
+            raise HTTPException(status_code=400, detail=f"市场物料不存在或已删除(ID: {mid})")
 
         qc_row = _find_outbound_qc_material_row(db, schedule_id, tenant_no, mid)
         if qc_row:

+ 49 - 15
backend/app/crud/outbound_release_review.py

@@ -2,6 +2,7 @@
 from __future__ import annotations
 
 import math
+from collections import defaultdict
 from datetime import datetime
 from typing import Any, Dict, List, Optional
 
@@ -14,6 +15,7 @@ from app.models.models import (
     BizPilotApplication,
     BizPilotInfusionPlan,
     BizPilotInfusionSchedule,
+    BizPilotInfusionScheduleProduct,
     BizPilotPatient,
     BizProductionTask,
     BizProductionWorkOrder,
@@ -51,6 +53,15 @@ def _fmt_dt(t: Optional[datetime]) -> str:
     return t.strftime("%Y-%m-%d %H:%M:%S") if t else ""
 
 
+def _dec(v: Any) -> Optional[float]:
+    if v is None:
+        return None
+    try:
+        return float(v)
+    except (TypeError, ValueError):
+        return None
+
+
 def _total_pages(total: int, page_size: int) -> int:
     if total <= 0:
         return 0
@@ -332,11 +343,38 @@ def list_reviews_paginated(
                 BizQcWorkOrder.biz_type.in_(list(_BIZ_TYPE_LABELS.keys())),
                 BizQcWorkOrder.tenant_no == tenant_no,
                 BizQcWorkOrder.del_flag == 0,
+                BizQcWorkOrder.trigger_source == "schedule",
             )
             .all()
         ):
             qc_map[qwo.infusion_schedule_id] = qwo
 
+    # 输注计划产品明细(用户需求细胞)
+    products_map: Dict[str, List[Dict[str, Any]]] = defaultdict(list)
+    if schedule_ids:
+        for product in (
+            db.query(BizPilotInfusionScheduleProduct)
+            .filter(
+                BizPilotInfusionScheduleProduct.infusion_schedule_id.in_(schedule_ids),
+                BizPilotInfusionScheduleProduct.tenant_no == tenant_no,
+                BizPilotInfusionScheduleProduct.del_flag == 0,
+            )
+            .order_by(BizPilotInfusionScheduleProduct.order_num.asc())
+            .all()
+        ):
+            products_map[product.infusion_schedule_id].append(
+                {
+                    "projectCode": product.project_code or "",
+                    "projectName": product.project_name or "",
+                    "cellTypeName": product.cell_type_name or "",
+                    "specText": product.spec_text or "",
+                    "agreementPrice": _dec(product.agreement_price),
+                    "actualPrice": _dec(product.actual_price),
+                    "quantity": product.quantity,
+                    "productStatus": product.product_status or "",
+                }
+            )
+
     # 输注计划 → 申请单 → 患者
     plan_ids_for_schedules = {
         s.id: s.infusion_plan_id for s in schedules if s.infusion_plan_id
@@ -398,6 +436,7 @@ def list_reviews_paginated(
         biz_type = _resolve_schedule_biz_type(app, qwo, pwo)
 
         item: Dict[str, Any] = {
+            "id": s.id,
             "scheduleId": s.id,
             "bizType": biz_type,
             "bizTypeLabel": _BIZ_TYPE_LABELS.get(biz_type, biz_type),
@@ -416,6 +455,7 @@ def list_reviews_paginated(
             "qcStatusLabel": _QC_STATUS_LABELS.get(
                 s.qc_status or "", s.qc_status or ""
             ),
+            "products": products_map.get(s.id, []),
             "reviewConclusion": "",
             "reviewConclusionLabel": "",
             "reviewByName": "",
@@ -492,22 +532,14 @@ def get_schedule_detail(
         production_info = _production_info_item(db, pwo)
 
     # ── 质检工单 + 任务 + 结果 ──
-    qc_info: Dict[str, Any] = {}
-    qwo = (
-        db.query(BizQcWorkOrder)
-        .filter(
-            BizQcWorkOrder.infusion_schedule_id == schedule_id,
-            BizQcWorkOrder.qc_biz_type == "outbound",
-            BizQcWorkOrder.biz_type.in_(list(_BIZ_TYPE_LABELS.keys())),
-            BizQcWorkOrder.tenant_no == tenant_no,
-            BizQcWorkOrder.del_flag == 0,
-        )
-        .first()
-    )
-    if qwo:
-        from app.crud.qc_work_order import _qc_info_item
+    from app.crud import qc_work_order as qc_work_order_svc
 
-        qc_info = _qc_info_item(db, qwo, tenant_no)
+    qc_info = qc_work_order_svc.get_schedule_gate_qc_info(
+        db, schedule_id=schedule_id, tenant_no=tenant_no
+    ) or {}
+    process_qc_info_list = qc_work_order_svc.list_process_qc_info_for_schedule(
+        db, schedule_id=schedule_id, tenant_no=tenant_no
+    )
 
     # ── 审核记录 ──
     review_info: Dict[str, Any] = {}
@@ -536,6 +568,7 @@ def get_schedule_detail(
         **(pilot_context or {}),
         "productionInfo": production_info,
         "qcInfo": qc_info,
+        "processQcInfoList": process_qc_info_list,
         "reviewInfo": review_info,
         "outboundMaterial": outbound_material,
     }
@@ -590,6 +623,7 @@ def review_schedule(
             BizQcWorkOrder.qc_biz_type == "outbound",
             BizQcWorkOrder.tenant_no == tenant_no,
             BizQcWorkOrder.del_flag == 0,
+            BizQcWorkOrder.trigger_source == "schedule",
         )
         .first()
     )

+ 1 - 0
backend/app/crud/pilot_infusion_schedule_mgmt.py

@@ -534,6 +534,7 @@ def get_infusion_schedule_detail(
         "products": flat.get("products") or aggregated.get("products") or [],
         "productionInfo": aggregated.get("productionInfo") or {},
         "qcInfo": aggregated.get("qcInfo") or {},
+        "processQcInfoList": aggregated.get("processQcInfoList") or [],
         "reviewInfo": aggregated.get("reviewInfo") or {},
         "outboundMaterial": aggregated.get("outboundMaterial") or {},
         "outboundHandover": handover_svc.get_outbound_handover_view(db, schedule_id, tenant_no),

+ 5 - 1
backend/app/crud/pilot_outbound_status_sync.py

@@ -93,9 +93,12 @@ def sync_schedule_from_qc_work_order(
     *,
     user_id: Optional[str] = None,
 ) -> None:
-    """出库质检工单状态 → 输注计划 qc_status。"""
+    """出库质检工单状态 → 输注计划 qc_status(仅计划自动质检参与联动)。"""
     if not _is_pilot_outbound_qc(wo):
         return
+    trigger = (getattr(wo, "trigger_source", None) or "reception").strip()
+    if trigger != "schedule":
+        return
     sched = _get_schedule(db, wo.infusion_schedule_id or "", wo.tenant_no or "")
     if not sched:
         return
@@ -182,6 +185,7 @@ def sync_qc_work_order_from_schedule(
             BizQcWorkOrder.del_flag == 0,
             BizQcWorkOrder.work_order_type == "outbound",
             BizQcWorkOrder.biz_type.in_(_OUTBOUND_BIZ_TYPES),
+            BizQcWorkOrder.trigger_source == "schedule",
         )
         .first()
     )

+ 35 - 16
backend/app/crud/pilot_service.py

@@ -3505,6 +3505,7 @@ def list_service_order_txns(
     db,
     *,
     service_order_id=None,
+    channel_id=None,
     txn_status=None,
     txn_type=None,
     keyword=None,
@@ -3521,6 +3522,40 @@ def list_service_order_txns(
         q = q.filter(BizChannelServiceOrderTxn.tenant_no == tenant_no)
     if service_order_id:
         q = q.filter(BizChannelServiceOrderTxn.service_order_id == service_order_id)
+    cid = (channel_id or "").strip()
+    kw = (keyword or "").strip()
+    if cid:
+        q = q.join(
+            BizChannelServiceOrder,
+            and_(
+                BizChannelServiceOrder.id == BizChannelServiceOrderTxn.service_order_id,
+                BizChannelServiceOrder.del_flag == 0,
+            ),
+        ).filter(BizChannelServiceOrder.channel_id == cid)
+        if kw:
+            like = f"%{kw}%"
+            q = q.filter(
+                or_(
+                    BizChannelServiceOrder.channel_name.like(like),
+                    BizChannelServiceOrder.order_name.like(like),
+                    BizChannelServiceOrder.dept_name.like(like),
+                )
+            )
+    elif kw:
+        like = f"%{kw}%"
+        q = q.outerjoin(
+            BizChannelServiceOrder,
+            and_(
+                BizChannelServiceOrder.id == BizChannelServiceOrderTxn.service_order_id,
+                BizChannelServiceOrder.del_flag == 0,
+            ),
+        ).filter(
+            or_(
+                BizChannelServiceOrder.channel_name.like(like),
+                BizChannelServiceOrder.order_name.like(like),
+                BizChannelServiceOrder.dept_name.like(like),
+            )
+        )
     if finance_done_only:
         q = q.filter(
             or_(
@@ -3542,22 +3577,6 @@ def list_service_order_txns(
         types = [t.strip() for t in tt.split(",") if t.strip()]
         if types:
             q = q.filter(BizChannelServiceOrderTxn.txn_type.in_(types))
-    kw = (keyword or "").strip()
-    if kw:
-        like = f"%{kw}%"
-        q = q.outerjoin(
-            BizChannelServiceOrder,
-            and_(
-                BizChannelServiceOrder.id == BizChannelServiceOrderTxn.service_order_id,
-                BizChannelServiceOrder.del_flag == 0,
-            ),
-        ).filter(
-            or_(
-                BizChannelServiceOrder.channel_name.like(like),
-                BizChannelServiceOrder.order_name.like(like),
-                BizChannelServiceOrder.dept_name.like(like),
-            )
-        )
     if create_time_start and create_time_start.strip():
         q = q.filter(
             BizChannelServiceOrderTxn.create_time

+ 124 - 32
backend/app/crud/qc_work_order.py

@@ -58,6 +58,7 @@ _QC_BIZ_TYPE_LABELS = {
 }
 _TRIGGER_SOURCE_LABELS = {
     "reception": "样本接收",
+    "schedule": "计划质检",
     "production": "生产过程",
 }
 _ACCEPT_CONCLUSION_LABELS = {"js": "接收", "bj": "拒收"}
@@ -839,13 +840,13 @@ def create_qc_work_order_from_production(
     if not pwo:
         raise ValueError("生产工单不存在")
     wo_type = (getattr(pwo, "work_order_type", None) or "inbound").strip()
-    if wo_type != "inbound":
-        raise ValueError("仅入库生产工单可派发质检")
+    if wo_type not in ("inbound", "outbound"):
+        raise ValueError("仅入库或出库生产工单可派发质检")
     status = (pwo.work_order_status or "").strip()
     if status == "yzf":
         raise ValueError("已作废的生产工单不可派发质检")
     if status not in ("jxz", "ywc"):
-        raise ValueError("仅进行中或已完成的入库生产工单可派发质检")
+        raise ValueError("仅进行中或已完成的生产工单可派发质检")
 
     cp_id = _validate_cell_product_id(db, cell_product_id, tenant_no)
     options = list_cell_product_options_for_production_work_order(
@@ -870,35 +871,72 @@ def create_qc_work_order_from_production(
         if not task:
             raise ValueError("关联生产任务不存在")
 
-    wo = BizQcWorkOrder(
-        id=generate_uuid(),
-        work_order_no=_gen_daily_no(db, tenant_no, "ZJ"),
-        work_order_type="inbound",
-        # 生产过程触发不写入 reception_id,避免与 uk_qc_wo_reception(reception_id,del_flag) 冲突;
-        # 样本关联仍通过 sample_code / protocol_sample_id 等快照字段。
-        reception_id=None,
-        protocol_sample_id=pwo.protocol_sample_id,
-        collection_protocol_id=pwo.collection_protocol_id,
-        protocol_no=pwo.protocol_no or None,
-        sample_code=pwo.sample_code or None,
-        reception_source=getattr(pwo, "reception_source", "cell_storage") or "cell_storage",
-        qc_biz_type="inbound",
-        trigger_source="production",
-        cell_product_id=cp_id,
-        production_work_order_id=pwo.id,
-        production_task_id=task_id,
-        work_order_status="dpz",
-        has_lab="0",
-        has_third_party="0",
-        tenant_no=tenant_no,
-        remark=(remark or "").strip() or None,
-        create_by=user_id,
-        create_dept_id=create_dept_id or "",
-        update_by=user_id,
-        create_time=datetime.now(),
-        update_time=datetime.now(),
-        del_flag=0,
-    )
+    if wo_type == "outbound":
+        schedule_id = (getattr(pwo, "infusion_schedule_id", None) or "").strip()
+        if not schedule_id:
+            raise ValueError("出库生产工单缺少输注计划关联")
+        biz_type = (getattr(pwo, "biz_type", None) or "pilot_service").strip() or "pilot_service"
+        if biz_type not in _OUTBOUND_BIZ_TYPE_LABELS:
+            biz_type = "pilot_service"
+        wo = BizQcWorkOrder(
+            id=generate_uuid(),
+            work_order_no=_gen_daily_no(db, tenant_no, "CKZJ"),
+            work_order_type="outbound",
+            reception_id=None,
+            protocol_sample_id=None,
+            collection_protocol_id=None,
+            protocol_no=None,
+            sample_code=None,
+            reception_source="outbound",
+            qc_biz_type="outbound",
+            biz_type=biz_type,
+            infusion_schedule_id=schedule_id,
+            trigger_source="production",
+            cell_product_id=cp_id,
+            production_work_order_id=pwo.id,
+            production_task_id=task_id,
+            work_order_status="dpz",
+            has_lab="0",
+            has_third_party="0",
+            tenant_no=tenant_no,
+            remark=(remark or "").strip() or None,
+            create_by=user_id,
+            create_dept_id=create_dept_id or "",
+            update_by=user_id,
+            create_time=datetime.now(),
+            update_time=datetime.now(),
+            del_flag=0,
+        )
+    else:
+        wo = BizQcWorkOrder(
+            id=generate_uuid(),
+            work_order_no=_gen_daily_no(db, tenant_no, "ZJ"),
+            work_order_type="inbound",
+            # 生产过程触发不写入 reception_id,避免与 uk_qc_wo_reception(reception_id,del_flag) 冲突;
+            # 样本关联仍通过 sample_code / protocol_sample_id 等快照字段。
+            reception_id=None,
+            protocol_sample_id=pwo.protocol_sample_id,
+            collection_protocol_id=pwo.collection_protocol_id,
+            protocol_no=pwo.protocol_no or None,
+            sample_code=pwo.sample_code or None,
+            reception_source=getattr(pwo, "reception_source", "cell_storage") or "cell_storage",
+            qc_biz_type="inbound",
+            trigger_source="production",
+            cell_product_id=cp_id,
+            production_work_order_id=pwo.id,
+            production_task_id=task_id,
+            work_order_status="dpz",
+            has_lab="0",
+            has_third_party="0",
+            tenant_no=tenant_no,
+            remark=(remark or "").strip() or None,
+            create_by=user_id,
+            create_dept_id=create_dept_id or "",
+            update_by=user_id,
+            create_time=datetime.now(),
+            update_time=datetime.now(),
+            del_flag=0,
+        )
     db.add(wo)
     db.flush()
     return wo
@@ -1353,6 +1391,58 @@ def list_process_qc_info_for_sample(
     return _process_qc_info_items_from_wos(db, wos, tenant_no)
 
 
+def get_schedule_gate_qc_info(
+    db: Session,
+    *,
+    schedule_id: str,
+    tenant_no: str,
+) -> Optional[Dict[str, Any]]:
+    """出库计划自动质检(trigger_source=schedule),供输注计划/出库放行查看。"""
+    sid = (schedule_id or "").strip()
+    if not sid or not tenant_no:
+        return None
+    wo = (
+        db.query(BizQcWorkOrder)
+        .filter(
+            BizQcWorkOrder.tenant_no == tenant_no,
+            BizQcWorkOrder.del_flag == 0,
+            BizQcWorkOrder.work_order_type == "outbound",
+            BizQcWorkOrder.infusion_schedule_id == sid,
+            BizQcWorkOrder.trigger_source == "schedule",
+        )
+        .order_by(BizQcWorkOrder.create_time.asc())
+        .first()
+    )
+    if not wo:
+        return None
+    return _qc_info_item(db, wo, tenant_no)
+
+
+def list_process_qc_info_for_schedule(
+    db: Session,
+    *,
+    schedule_id: str,
+    tenant_no: str,
+) -> List[Dict[str, Any]]:
+    """按输注计划返回生产过程触发的出库质检工单摘要。"""
+    sid = (schedule_id or "").strip()
+    if not sid or not tenant_no:
+        return []
+    wos = (
+        db.query(BizQcWorkOrder)
+        .filter(
+            BizQcWorkOrder.tenant_no == tenant_no,
+            BizQcWorkOrder.del_flag == 0,
+            BizQcWorkOrder.work_order_type == "outbound",
+            BizQcWorkOrder.infusion_schedule_id == sid,
+            BizQcWorkOrder.trigger_source == "production",
+        )
+        .order_by(BizQcWorkOrder.create_time.asc())
+        .all()
+    )
+    return _process_qc_info_items_from_wos(db, wos, tenant_no)
+
+
 def _resolve_reception_id_for_work_order_detail(
     db: Session, wo: BizQcWorkOrder, tenant_no: str
 ) -> Optional[str]:
@@ -2516,6 +2606,7 @@ def create_outbound_qc_work_order(
             BizQcWorkOrder.infusion_schedule_id == schedule_id,
             BizQcWorkOrder.tenant_no == tenant_no,
             BizQcWorkOrder.del_flag == 0,
+            BizQcWorkOrder.trigger_source == "schedule",
         )
         .first()
     )
@@ -2537,6 +2628,7 @@ def create_outbound_qc_work_order(
         qc_biz_type="outbound",
         biz_type=resolved_biz_type,
         infusion_schedule_id=schedule_id,
+        trigger_source="schedule",
         cell_product_id=cell_product_id or None,
         work_order_status="dpz",
         has_lab="0",

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
backend/app/graphify-out/cache/ast/098e2895af990740a8c04a027b8159db1855fbd3aa0c02c1a043fbdbe6ed9c73.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
backend/app/graphify-out/cache/ast/2dc202ecf4e1448d81904387ae1f120bd7216aceb73388c0a6b35a1842f6bdcc.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
backend/app/graphify-out/cache/ast/473a1f11b4bd699d31117c1729237d28926ce64c4eba076ce0fb2cdcfb24438f.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
backend/app/graphify-out/cache/ast/6392d99ffb8d96094d254eb926f7016de67f49c75e11f7cfed6d2b5f3c12d9a4.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
backend/app/graphify-out/cache/ast/6d03b440aaf41bc7fed10a1ba61634c13bc365db841bb4205d5ebea3bea808c6.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
backend/app/graphify-out/cache/ast/80ff4d99f0f374f7532c1d8edf194f1e663982470fd00a30019df92035ccf38c.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
backend/app/graphify-out/cache/ast/8e54eae994db3a9274b19756489bac0c84c5115cd451b723daee09bcc7de65e0.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
backend/app/graphify-out/cache/ast/9a546303c18c1f714014958e869476c25ab1280eac2704256f798b89b8ae3512.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
backend/app/graphify-out/cache/ast/abdff0d5150ff2ed866d94efed509e966213ec069e88c55bdef5d03b675ba177.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
backend/app/graphify-out/cache/ast/e28b7cbc542ef7ce058956fcfc5a2d377b5fe88db57f5541cb566ad3ac561624.json


+ 1 - 1
backend/app/models/models.py

@@ -1295,7 +1295,7 @@ class BizQcWorkOrder(Base):
         String(20),
         nullable=False,
         default="reception",
-        comment="触发来源 reception=样本接收 production=生产过程",
+        comment="触发来源 reception=样本接收 schedule=计划创建 production=生产过程",
     )
     infusion_schedule_id = Column(String(64), nullable=True, comment="中试输注计划ID(出库质检关联)")
     biz_type = Column(String(20), nullable=True, comment="业务类型: pilot_service=中试服务, clinical_application=临床应用")

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 575 - 272
backend/graphify-out/.graphify_analysis.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 227 - 150
backend/graphify-out/.graphify_extract.json


+ 77 - 137
backend/graphify-out/GRAPH_REPORT.md

@@ -1,11 +1,11 @@
 # Graph Report - app  (2026-06-16)
 
 ## Corpus Check
-- Large corpus: 208 files · ~241,502 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
+- Large corpus: 208 files · ~242,154 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
 
 ## Summary
-- 4146 nodes · 21662 edges · 55 communities detected
-- Extraction: 33% EXTRACTED · 67% INFERRED · 0% AMBIGUOUS · INFERRED: 14559 edges (avg confidence: 0.6)
+- 4157 nodes · 21763 edges · 43 communities detected
+- Extraction: 33% EXTRACTED · 67% INFERRED · 0% AMBIGUOUS · INFERRED: 14643 edges (avg confidence: 0.6)
 - Token cost: 0 input · 0 output
 
 ## Community Hubs (Navigation)
@@ -46,110 +46,98 @@
 - [[_COMMUNITY_Community 34|Community 34]]
 - [[_COMMUNITY_Community 35|Community 35]]
 - [[_COMMUNITY_Community 36|Community 36]]
-- [[_COMMUNITY_Community 37|Community 37]]
-- [[_COMMUNITY_Community 38|Community 38]]
 - [[_COMMUNITY_Community 39|Community 39]]
 - [[_COMMUNITY_Community 40|Community 40]]
 - [[_COMMUNITY_Community 41|Community 41]]
 - [[_COMMUNITY_Community 42|Community 42]]
 - [[_COMMUNITY_Community 43|Community 43]]
 - [[_COMMUNITY_Community 44|Community 44]]
-- [[_COMMUNITY_Community 45|Community 45]]
-- [[_COMMUNITY_Community 46|Community 46]]
-- [[_COMMUNITY_Community 47|Community 47]]
-- [[_COMMUNITY_Community 48|Community 48]]
-- [[_COMMUNITY_Community 51|Community 51]]
-- [[_COMMUNITY_Community 52|Community 52]]
-- [[_COMMUNITY_Community 53|Community 53]]
-- [[_COMMUNITY_Community 54|Community 54]]
-- [[_COMMUNITY_Community 55|Community 55]]
-- [[_COMMUNITY_Community 56|Community 56]]
 
 ## God Nodes (most connected - your core abstractions)
 1. `success_response()` - 636 edges
 2. `error_response()` - 528 edges
-3. `SysUser` - 449 edges
+3. `SysUser` - 451 edges
 4. `BizProductionMaterialUsage` - 294 edges
 5. `BizProductionMaterial` - 293 edges
-6. `BizQcTaskResult` - 290 edges
-7. `BizQcMaterialUsage` - 289 edges
+6. `BizQcTaskResult` - 292 edges
+7. `BizQcMaterialUsage` - 291 edges
 8. `BizQcMaterial` - 282 edges
 9. `BizProductionMaterialStockBatch` - 281 edges
-10. `BizQcMaterialStockBatch` - 275 edges
+10. `BizMaterialUsage` - 278 edges
 
 ## Surprising Connections (you probably didn't know these)
 - `统一记录 API 请求/响应出入参的中间件` --uses--> `SysApiRequestLog`  [INFERRED]
   core/api_request_log_middleware.py → models/models.py
 - `get_menu_list()` --calls--> `success_response()`  [INFERRED]
   api/menu.py → core/response.py
-- `保留匹配节点及其全部上级,供关键词检索后仍能正确组树。` --uses--> `SysDept`  [INFERRED]
-  crud/dept.py → models/models.py
 - `物品单位 CRUD(biz_item_unit)` --uses--> `BizItemUnit`  [INFERRED]
   crud/item_unit.py → models/models.py
 - `快递公司 CRUD(biz_express_company)` --uses--> `BizExpressCompany`  [INFERRED]
   crud/express_company.py → models/models.py
+- `客户 CRUD(biz_customer)` --uses--> `BizCustomer`  [INFERRED]
+  crud/customer.py → models/models.py
 
 ## Communities
 
 ### Community 0 - "Community 0"
 Cohesion: 0.01
-Nodes (778): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+770 more)
+Nodes (866): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+858 more)
 
 ### Community 1 - "Community 1"
 Cohesion: 0.01
-Nodes (589): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+581 more)
+Nodes (598): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+590 more)
 
 ### Community 2 - "Community 2"
 Cohesion: 0.07
-Nodes (428): 环境检测 — 检测项维护 + 登记管理 API, 保险公司及险种价格管理 API(保险公司 + 开票信息 + 险种价格), AccessLogCreateBody, AccessLogUpdateBody, CleanRoomCreateBody, CleanRoomUpdateBody, ExhibitionAppointmentCreateBody, ExhibitionAppointmentUpdateBody (+420 more)
+Nodes (481): 细胞存储 — 采集协议单 / 审核 / 财务确认 / 分期预警 API, If mother info exists but no customerId, create a customer record and link it., Base, 细胞产品 CRUD(biz_cell_product), 解析任务样本投入物,返回祖先链单段(样本终止节点)。, 管理端手动改状态:允许在合法枚举间任意变更,并同步库位占用。, 去掉末尾 -01/-02 等序号,得到多份入库时的基础编码。, 按基础编码生成 基础-01、基础-02 … (+473 more)
 
 ### Community 3 - "Community 3"
 Cohesion: 0.01
-Nodes (270): list_ethnics_for_select(), apply_data_scope(), _get_child_dept_ids(), get_user_dept_id(), _resolve_user_role_scopes(), ApiRequestLogCRUD, delete(), get_multi_with_filters() (+262 more)
+Nodes (407): _persist_protocol_sub_resources(), generate_uuid(), ApiRequestLogCRUD, delete(), get_multi_with_filters(), batch_create_sterilize_logs(), batch_create_wash_logs(), batch_discard_garments() (+399 more)
 
 ### Community 4 - "Community 4"
 Cohesion: 0.02
-Nodes (232): get_next_cell_product_code(), generate_uuid(), _ancestor_link_from_cell_product_input(), _ancestor_sample_chain_link(), _apply_cell_product_status_change(), _build_ancestor_chain(), _build_descendant_chain(), _build_facility_path_label() (+224 more)
+Nodes (243): eq_unicode(), like_unicode(), MySQL 字符串比较/模糊匹配时统一排序规则,避免 Illegal mix of collations。, 跨表字符串等值比较(JOIN / WHERE)时统一为 utf8mb4_unicode_ci。, 将列显式设为 utf8mb4_unicode_ci。, unicode_ci(), _format_attachment_file_size(), urls_to_attachment_list() (+235 more)
 
 ### Community 5 - "Community 5"
 Cohesion: 0.02
-Nodes (235): eq_unicode(), like_unicode(), MySQL 字符串比较/模糊匹配时统一排序规则,避免 Illegal mix of collations。, 跨表字符串等值比较(JOIN / WHERE)时统一为 utf8mb4_unicode_ci。, 将列显式设为 utf8mb4_unicode_ci。, unicode_ci(), _format_attachment_file_size(), urls_to_attachment_list() (+227 more)
+Nodes (113): get_designer_data(), _error_json(), lifespan(), 数据库异常:返回 JSON 并保留 CORS 头,避免浏览器只报跨域错误, 未捕获异常:统一 JSON 500,确保跨域场景下仍有 Access-Control-Allow-Origin, sqlalchemy_exception_handler(), unhandled_exception_handler(), BaseHTTPMiddleware (+105 more)
 
 ### Community 6 - "Community 6"
-Cohesion: 0.03
-Nodes (166): batch_discard(), batch_options(), _batch_row_to_dict(), batch_stock_in(), batch_stock_out(), _create_batch_and_usage(), delete_batch(), _discard_batch() (+158 more)
+Cohesion: 0.02
+Nodes (140): _jwt_user_payload(), Web 端登录用 RSA 公钥(PKCS#1 v1.5,与 JSEncrypt 一致), Web 端登录:账号为 sys_user.user_no,密码为 sys_user.password(bcrypt)。, refresh_token(), web_login(), web_login_rsa_public_key(), create_access_token(), create_refresh_token() (+132 more)
 
 ### Community 7 - "Community 7"
-Cohesion: 0.02
-Nodes (107): _avatar_url_field(), _build_current_user_payload(), _build_user_info_payload(), get_current_user_profile(), _jwt_user_payload(), logout(), 公共接口(Web 登录、刷新 Token、登出;用户模型对齐 docs/sql/zkxw.sql 基线), Web 端登录用 RSA 公钥(PKCS#1 v1.5,与 JSEncrypt 一致) (+99 more)
+Cohesion: 0.03
+Nodes (140): _ancestor_link_from_cell_product_input(), _ancestor_sample_chain_link(), _apply_cell_product_status_change(), _build_ancestor_chain(), _build_descendant_chain(), _build_facility_path_label(), build_split_product_codes(), create_cell_product() (+132 more)
 
 ### Community 8 - "Community 8"
-Cohesion: 0.09
-Nodes (146): CellSampleTypeCreateBody, CellSampleTypeUpdateBody, CollectionRegionCreateBody, CollectionRegionUpdateBody, CustomerCreateBody, CustomerUpdateBody, HospitalCreateBody, HospitalUpdateBody (+138 more)
+Cohesion: 0.03
+Nodes (119): _batch_line_to_dict(), _check_header_to_dict(), get_check_detail(), _line_counts(), list_checks(), _parse_check_time(), _resolve_unused_item_fields(), _status_label() (+111 more)
 
 ### Community 9 - "Community 9"
-Cohesion: 0.02
-Nodes (133): get_protocol_nos_used_in_protocols(), create_dict_type(), dict_type_code_exists(), get_dict_type(), list_dict_types(), 字典类型 CRUD(sys_dict_type), _row_to_dict(), soft_delete_dict_type() (+125 more)
+Cohesion: 0.03
+Nodes (115): list_ethnics_for_select(), apply_data_scope(), _get_child_dept_ids(), get_user_dept_id(), _resolve_user_role_scopes(), _cascade_soft_delete(), create_dept(), get_dept() (+107 more)
 
 ### Community 10 - "Community 10"
 Cohesion: 0.03
-Nodes (89): get_designer_data(), _error_json(), 数据库异常:返回 JSON 并保留 CORS 头,避免浏览器只报跨域错误, 未捕获异常:统一 JSON 500,确保跨域场景下仍有 Access-Control-Allow-Origin, sqlalchemy_exception_handler(), unhandled_exception_handler(), BaseHTTPMiddleware, ApiCryptoError (+81 more)
+Nodes (104): format_date(), optional_date(), parse_date(), 将字符串 / date / datetime 转为 date 或 None, allocate_next_biz_no(), _format_biz_no(), _prefix_for(), 业务协议号自动生成:XBCC / JZCC + YYYYMMDD + 6 位序号 (+96 more)
 
 ### Community 11 - "Community 11"
-Cohesion: 0.04
-Nodes (96): batch_delete_research_donations(), change_donation_status(), convert_from_storage(), convert_to_storage(), create_research_donation(), delete_research_donation(), _get_current_user_id(), get_research_donation_detail() (+88 more)
+Cohesion: 0.06
+Nodes (89): AccessLogCreateBody, AccessLogUpdateBody, CleanRoomCreateBody, CleanRoomUpdateBody, ExhibitionAppointmentCreateBody, ExhibitionAppointmentUpdateBody, OccupancyCreateBody, 运营支撑 API(洁净室、进出记录、仓储设施、储位、展厅预约) (+81 more)
 
 ### Community 12 - "Community 12"
-Cohesion: 0.04
-Nodes (103): _persist_protocol_sub_resources(), align_fq_payment_details_payload(), _apply_payment_detail_list_filters(), _apply_submit_receipt_finance(), _apply_submit_refund_finance(), attachments_to_urls(), _audit_to_dict(), batch_submit_receipt_finance() (+95 more)
+Cohesion: 0.36
+Nodes (66): BatchStockInBody, BatchStockInItem, BatchStockOutBody, BatchStockOutItem, ConsumableCreateBody, ConsumablePackCreateBody, ConsumablePackUpdateBody, ConsumableUpdateBody (+58 more)
 
 ### Community 13 - "Community 13"
 Cohesion: 0.08
-Nodes (57): api_save_application(), auto_create_payment(), auto_generate_schedules(), complete_application(), create_application(), create_basic_experiment_sale_schedules(), create_infusion_plan(), create_schedule() (+49 more)
+Nodes (57): api_save_application(), auto_generate_schedules(), complete_application(), create_application(), create_basic_experiment_sale_schedules(), create_infusion_plan(), create_schedule(), _create_schedule_products() (+49 more)
 
 ### Community 14 - "Community 14"
-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)
+Cohesion: 0.1
+Nodes (44): _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), get_material_entity(), get_my_usages(), _is_enabled_status() (+36 more)
 
 ### Community 15 - "Community 15"
 Cohesion: 0.12
@@ -157,194 +145,146 @@ Nodes (10): get_wechat_pay_client(), get_wechat_pay_v2(), 微信支付工具模
 
 ### Community 16 - "Community 16"
 Cohesion: 0.15
-Nodes (20): _access_log_to_dict(), _calc_duration_minutes(), create_access_log(), create_clean_room(), create_uv_disinfect_log(), get_access_log(), get_clean_room(), get_uv_disinfect_log() (+12 more)
+Nodes (24): join_equipment_ids(), parse_equipment_ids(), 工艺/步骤设备多选:逗号分隔 ID 与名称快照解析, 校验设备列表,返回 (equipment_ids 逗号串, equipment_name 逗号串快照)。, resolve_equipment_list_snapshot(), _consumable_row_to_dict(), create_process(), _create_sub_consumable() (+16 more)
 
 ### Community 17 - "Community 17"
-Cohesion: 0.2
-Nodes (19): _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), get_material_entity(), get_my_usages(), _is_enabled_status() (+11 more)
+Cohesion: 0.17
+Nodes (21): batch_stock_in(), batch_stock_out(), code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), _is_enabled_status() (+13 more)
 
 ### Community 18 - "Community 18"
 Cohesion: 0.18
 Nodes (18): company_code_exists(), create_company(), get_company(), list_companies(), list_company_options(), _row_to_dict(), soft_delete_company(), update_company() (+10 more)
 
 ### Community 19 - "Community 19"
-Cohesion: 0.21
-Nodes (13): create_collection_region(), create_hospital(), get_collection_region(), get_hospital(), _hospital_names_by_region_ids(), _hospital_to_dict(), list_collection_regions(), list_hospitals() (+5 more)
-
-### Community 20 - "Community 20"
-Cohesion: 0.25
-Nodes (13): batch_issue_protocol_nos(), batch_revoke_protocol_nos(), create_protocol_no(), get_protocol_no(), list_protocol_nos(), _parse_issued_time(), protocol_no_exists(), 采集协议号池 CRUD(biz_collection_protocol_no) (+5 more)
-
-### Community 21 - "Community 21"
 Cohesion: 0.24
 Nodes (9): 微信消息通知服务  支持微信小程序模板消息推送  使用方式:     from app.core.wechat_message import Wech, 发送模板消息                  Args:             openid: 用户openid             templ, send_delivery_notice(), send_delivery_warning(), send_order_status(), send_payment_success(), send_refund_result(), send_urge_notification() (+1 more)
 
-### Community 22 - "Community 22"
-Cohesion: 0.23
-Nodes (12): Config, ProductBase, ProductCategoryBase, ProductCategoryCreate, ProductCategoryResponse, ProductCreate, ProductResponse, ProductUnitBase (+4 more)
-
-### Community 23 - "Community 23"
+### Community 20 - "Community 20"
 Cohesion: 0.31
 Nodes (11): create_equipment(), _dec(), equipment_code_exists(), equipment_is_referenced(), get_equipment(), list_equipments(), _norm_status(), _parse_date() (+3 more)
 
-### Community 24 - "Community 24"
-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 21 - "Community 21"
+Cohesion: 0.27
+Nodes (11): create_consumable_pack(), get_consumable_pack(), get_pack_detail(), _item_row_to_dict(), list_all_packs(), list_consumable_packs(), pack_code_exists(), 耗材包 CRUD(biz_consumable_pack + biz_consumable_pack_item) (+3 more)
 
-### Community 25 - "Community 25"
+### 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 26 - "Community 26"
+### 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 27 - "Community 27"
+### 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 28 - "Community 28"
-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 29 - "Community 29"
-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 30 - "Community 30"
+### Community 25 - "Community 25"
 Cohesion: 0.27
 Nodes (8): create_customer(), get_customer(), id_card_taken(), list_customers(), 客户 CRUD(biz_customer), _row_to_dict(), soft_delete_customer(), update_customer()
 
-### Community 31 - "Community 31"
-Cohesion: 0.31
-Nodes (8): create_sop_document(), get_sop_document(), list_sop_documents(), SOP文档 CRUD(biz_sop_document), _row_to_dict(), soft_delete_sop_document(), sop_code_exists(), update_sop_document()
-
-### Community 32 - "Community 32"
-Cohesion: 0.31
-Nodes (8): create_express_company(), express_code_exists(), get_express_company(), list_express_companies(), 快递公司 CRUD(biz_express_company), _row_to_dict(), soft_delete_express_company(), update_express_company()
-
-### Community 33 - "Community 33"
+### Community 26 - "Community 26"
 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 34 - "Community 34"
-Cohesion: 0.27
-Nodes (8): create_dict_data(), get_dict_data(), list_dict_data(), list_dict_data_options(), 字典数据 CRUD(sys_dict_data), _row_to_dict(), soft_delete_dict_data(), update_dict_data()
-
-### Community 35 - "Community 35"
+### Community 27 - "Community 27"
 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 36 - "Community 36"
-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 37 - "Community 37"
+### Community 28 - "Community 28"
 Cohesion: 0.31
 Nodes (8): create_cell_sample_type(), get_cell_sample_type(), list_cell_sample_types(), 细胞样本类型 CRUD(biz_cell_sample_type), _row_to_dict(), soft_delete_cell_sample_type(), type_code_exists(), update_cell_sample_type()
 
-### Community 38 - "Community 38"
-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 39 - "Community 39"
-Cohesion: 0.36
-Nodes (7): create_tenant(), get_tenant(), list_tenants(), _row_to_dict(), soft_delete_tenant(), tenant_no_exists(), update_tenant()
-
-### Community 40 - "Community 40"
-Cohesion: 0.36
-Nodes (7): create_site(), get_site(), list_sites(), _row_to_dict(), site_code_exists(), soft_delete_site(), update_site()
-
-### Community 41 - "Community 41"
+### Community 29 - "Community 29"
 Cohesion: 0.25
 Nodes (7): 菜单 code 权限守卫(V0.3:通过 sys_user_role → sys_role_menu → sys_menu.perms), 运营端角色守卫:admin / super_admin 可访问。, 接口菜单权限守卫。super_admin 直接放行。, 接口菜单权限守卫:拥有任一 menuCode 即可访问。super_admin 直接放行。, require_admin_or_super_admin(), require_any_menu_code(), require_menu_code()
 
-### Community 42 - "Community 42"
+### Community 30 - "Community 30"
 Cohesion: 0.29
 Nodes (2): BaseModel, SoftDeleteModel
 
-### Community 43 - "Community 43"
+### Community 31 - "Community 31"
 Cohesion: 0.38
 Nodes (6): derive_legacy_status_from_three(), derive_three_status_from_legacy(), 阶段A兼容:从旧 status 推导三字段。     约束:旧 status 本身混合了支付/配送/订单生命周期,因此只能尽力推断;     若业务侧已有更精确, 阶段A兼容:从三字段反推旧 status(用于旧前端/旧筛选参数兼容)。, ThreeStatus, _to_decimal()
 
-### Community 44 - "Community 44"
+### Community 32 - "Community 32"
 Cohesion: 0.5
 Nodes (3): BaseSettings, Config, Settings
 
-### Community 45 - "Community 45"
+### Community 33 - "Community 33"
 Cohesion: 0.5
 Nodes (2): _auto_fill_create_dept_id(), ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID
 
-### Community 46 - "Community 46"
+### Community 34 - "Community 34"
 Cohesion: 0.67
 Nodes (2): get_menu_list(), 运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,5 个一级菜单分组)
 
-### Community 47 - "Community 47"
+### Community 35 - "Community 35"
 Cohesion: 1.0
 Nodes (1): 请求级别的用户上下文变量  通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传
 
-### Community 48 - "Community 48"
+### Community 36 - "Community 36"
 Cohesion: 1.0
 Nodes (1): API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)
 
-### Community 51 - "Community 51"
+### Community 39 - "Community 39"
 Cohesion: 1.0
 Nodes (1): 发送订单状态通知                  Args:             openid: 用户openid             ord
 
-### Community 52 - "Community 52"
+### Community 40 - "Community 40"
 Cohesion: 1.0
 Nodes (1): 发送支付成功通知                  Args:             openid: 用户openid             ord
 
-### Community 53 - "Community 53"
+### Community 41 - "Community 41"
 Cohesion: 1.0
 Nodes (1): 发送配送通知                  Args:             openid: 配送员openid             task
 
-### Community 54 - "Community 54"
+### Community 42 - "Community 42"
 Cohesion: 1.0
 Nodes (1): 发送配送时效预警                  Args:             openid: 配送员openid             ta
 
-### Community 55 - "Community 55"
+### Community 43 - "Community 43"
 Cohesion: 1.0
 Nodes (1): 发送退款结果通知                  Args:             openid: 用户openid             ord
 
-### Community 56 - "Community 56"
+### Community 44 - "Community 44"
 Cohesion: 1.0
 Nodes (1): 发送催单通知给配送员                  Args:             deliver_openid: 配送员openid
 
 ## Knowledge Gaps
 - **127 isolated node(s):** `刷新会话 TTL(refreshToken 续期;已登录用户每次 API 校验通过后滑动续期)`, `写入 refreshToken(用于 one-time 使用/吊销)`, `根据 token 获取当前用户(包含 Redis 会话校验;会话滑动续期)`, `登录凭据 RSA 解密(与前端 JSEncrypt PKCS#1 v1.5 兼容)。`, `Base64 密文 -> JSON 对象(须含 username、password、ts 毫秒时间戳)。` (+122 more)
   These have ≤1 connection - possible missing edges or undocumented components.
-- **Thin community `Community 42`** (8 nodes): `BaseModel`, `.to_dict()`, `get_active()`, `base.py`, `SoftDeleteModel`, `.restore()`, `.soft_delete()`, `__tablename__()`
+- **Thin community `Community 30`** (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 45`** (4 nodes): `_auto_fill_create_dept_id()`, `get_db()`, `database.py`, `ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID`
+- **Thin community `Community 33`** (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 46`** (3 nodes): `get_menu_list()`, `menu.py`, `运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,5 个一级菜单分组)`
+- **Thin community `Community 34`** (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 47`** (2 nodes): `context.py`, `请求级别的用户上下文变量  通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
+- **Thin community `Community 35`** (2 nodes): `context.py`, `请求级别的用户上下文变量  通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 48`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
+- **Thin community `Community 36`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 51`** (1 nodes): `发送订单状态通知                  Args:             openid: 用户openid             ord`
+- **Thin community `Community 39`** (1 nodes): `发送订单状态通知                  Args:             openid: 用户openid             ord`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 52`** (1 nodes): `发送支付成功通知                  Args:             openid: 用户openid             ord`
+- **Thin community `Community 40`** (1 nodes): `发送支付成功通知                  Args:             openid: 用户openid             ord`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 53`** (1 nodes): `发送配送通知                  Args:             openid: 配送员openid             task`
+- **Thin community `Community 41`** (1 nodes): `发送配送通知                  Args:             openid: 配送员openid             task`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 54`** (1 nodes): `发送配送时效预警                  Args:             openid: 配送员openid             ta`
+- **Thin community `Community 42`** (1 nodes): `发送配送时效预警                  Args:             openid: 配送员openid             ta`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 55`** (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 56`** (1 nodes): `发送催单通知给配送员                  Args:             deliver_openid: 配送员openid`
+- **Thin community `Community 44`** (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 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 20`, `Community 25`, `Community 27`?**
-  _High betweenness centrality (0.127) - this node is a cross-community bridge._
-- **Why does `generate_uuid()` connect `Community 4` to `Community 0`, `Community 3`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 14`, `Community 16`, `Community 17`, `Community 18`, `Community 19`, `Community 20`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 33`, `Community 34`, `Community 35`, `Community 36`, `Community 37`, `Community 38`, `Community 39`, `Community 40`?**
-  _High betweenness centrality (0.076) - this node is a cross-community bridge._
-- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 3`, `Community 4`, `Community 7`, `Community 10`, `Community 11`, `Community 13`, `Community 46`?**
+- **Why does `SysUser` connect `Community 1` to `Community 0`, `Community 2`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 14`, `Community 22`, `Community 24`?**
+  _High betweenness centrality (0.124) - this node is a cross-community bridge._
+- **Why does `generate_uuid()` connect `Community 3` to `Community 0`, `Community 1`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 13`, `Community 14`, `Community 16`, `Community 17`, `Community 18`, `Community 20`, `Community 21`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`?**
+  _High betweenness centrality (0.061) - this node is a cross-community bridge._
+- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 34`, `Community 5`, `Community 6`, `Community 9`, `Community 13`?**
   _High betweenness centrality (0.049) - this node is a cross-community bridge._
 - **Are the 689 inferred relationships involving `str` (e.g. with `unhandled_exception_handler()` and `get_current_user_by_token()`) actually correct?**
   _`str` has 689 INFERRED edges - model-reasoned connections that need verification._
@@ -352,5 +292,5 @@ _Questions this graph is uniquely positioned to answer:_
   _`success_response()` has 635 INFERRED edges - model-reasoned connections that need verification._
 - **Are the 527 inferred relationships involving `error_response()` (e.g. with `_json_error_response()` and `list_storage_release_reviews()`) actually correct?**
   _`error_response()` has 527 INFERRED edges - model-reasoned connections that need verification._
-- **Are the 447 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤)  data_scope 值:   1 = 全部数据   2 = 本部门数据   3` and `从 SysUser 读取用户的 dept_id。`) actually correct?**
-  _`SysUser` has 447 INFERRED edges - model-reasoned connections that need verification._
+- **Are the 449 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤)  data_scope 值:   1 = 全部数据   2 = 本部门数据   3` and `从 SysUser 读取用户的 dept_id。`) actually correct?**
+  _`SysUser` has 449 INFERRED edges - model-reasoned connections that need verification._

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
backend/graphify-out/graph.html


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 112 - 112
backend/graphify-out/graph.json


+ 9 - 9
backend/graphify-out/manifest.json

@@ -28,7 +28,7 @@
   "/Users/wuzilong/work/00code/zkxw/backend/app/models/material.py": 1781427174.243315,
   "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py": 1781427178.0074935,
   "/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py": 1779022399.0175831,
-  "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py": 1781524055.78666,
+  "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py": 1781595822.599162,
   "/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": 1780458012.8329656,
@@ -78,7 +78,7 @@
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/process_route.py": 1781524077.6406052,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py": 1780479191.5382729,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py": 1779331731.6720955,
-  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py": 1781079917.390382,
+  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py": 1781597286.8580213,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_check.py": 1781423988.9720724,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/material_stock_batch.py": 1781521998.393167,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/post.py": 1779265648.38155,
@@ -106,7 +106,7 @@
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/biz_no_generator.py": 1779882385.4674172,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_confirm.py": 1779828818.7646794,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent_stock_log.py": 1779515479.6599197,
-  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py": 1781079923.2487886,
+  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_infusion_schedule_mgmt.py": 1781595844.0818596,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/clean_room.py": 1781403189.1288755,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/__init__.py": 1778605691.3816392,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_check.py": 1781427225.7574296,
@@ -136,12 +136,12 @@
   "/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": 1781593577.8460922,
-  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_handover_inventory.py": 1781335574.0796413,
+  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py": 1781595812.8827713,
+  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_handover_inventory.py": 1781598316.476379,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py": 1781145773.959546,
-  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_material.py": 1779928413.9677577,
+  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_material.py": 1781598316.369666,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/process.py": 1781524075.6578302,
-  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_service.py": 1781411605.207482,
+  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_service.py": 1781598987.4458413,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/customer.py": 1779686149.7508218,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/workflow.py": 1779265993.677624,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_sms_notification.py": 1781063495.0317714,
@@ -154,7 +154,7 @@
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/storage_facility.py": 1781435014.6878881,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py": 1780462849.099601,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_sample_type.py": 1781406022.0539382,
-  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_outbound_status_sync.py": 1781079916.545948,
+  "/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_outbound_status_sync.py": 1781595840.6955194,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py": 1779515477.284446,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/dept.py": 1779265637.7914758,
   "/Users/wuzilong/work/00code/zkxw/backend/app/crud/base.py": 1778578258.062207,
@@ -190,7 +190,7 @@
   "/Users/wuzilong/work/00code/zkxw/backend/app/api/research_donation.py": 1781592190.878251,
   "/Users/wuzilong/work/00code/zkxw/backend/app/api/ethnic.py": 1779266243.9511197,
   "/Users/wuzilong/work/00code/zkxw/backend/app/api/pilot_checkup.py": 1779935751.2658868,
-  "/Users/wuzilong/work/00code/zkxw/backend/app/api/pilot_service.py": 1781411609.3643663,
+  "/Users/wuzilong/work/00code/zkxw/backend/app/api/pilot_service.py": 1781598988.5409384,
   "/Users/wuzilong/work/00code/zkxw/backend/app/api/workflow.py": 1779266232.4568832,
   "/Users/wuzilong/work/00code/zkxw/backend/app/api/sample_sms_notification.py": 1780325524.907156,
   "/Users/wuzilong/work/00code/zkxw/backend/app/api/sample_reception.py": 1781535825.750677,

+ 7 - 8
docs/panel-tab-demos/_shared.css

@@ -286,9 +286,9 @@ body {
   gap: 4px;
   margin-top: 16px;
   padding: 4px;
-  background: #f1f5f9;
+  background: linear-gradient(180deg, var(--primary-bg, #ecfdf5) 0%, #fff 100%);
   border-radius: var(--radius-sm);
-  border: 1px solid var(--border);
+  border: 1px solid #d1fae5;
 }
 
 .tabs-02 .tab-btn {
@@ -304,15 +304,14 @@ body {
 }
 
 .tabs-02 .tab-btn:hover:not(.is-active) {
-  color: var(--text);
-  background: rgba(255, 255, 255, 0.6);
+  color: #065f46;
 }
 
 .tabs-02 .tab-btn.is-active {
-  background: var(--surface);
-  color: var(--primary-dark);
-  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08);
-  font-weight: 600;
+  background: var(--primary, #10b981);
+  color: #fff;
+  box-shadow: 0 1px 3px rgba(16, 185, 129, 0.28);
+  font-weight: 500;
 }
 
 /* ── 样式 03:卡片 Tab(独立卡片 + 底边融合) ── */

+ 12 - 0
docs/sql/alter_biz_qc_work_order_outbound_trigger_source_schedule.sql

@@ -0,0 +1,12 @@
+-- 出库质检:计划自动 QC 使用 trigger_source=schedule(生产过程派发仍为 production)
+-- 历史出库工单(无 production_work_order_id)由 reception 默认误标为样本接收,回写为 schedule
+
+UPDATE biz_qc_work_order
+SET trigger_source = 'schedule'
+WHERE work_order_type = 'outbound'
+  AND del_flag = 0
+  AND (production_work_order_id IS NULL OR production_work_order_id = '')
+  AND trigger_source IN ('reception', '');
+
+CREATE INDEX idx_qc_wo_schedule_trigger
+  ON biz_qc_work_order (tenant_no, infusion_schedule_id, trigger_source, del_flag);

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 441 - 436
web-admin/graphify-out/.graphify_analysis.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 264 - 159
web-admin/graphify-out/.graphify_extract.json


+ 109 - 126
web-admin/graphify-out/GRAPH_REPORT.md

@@ -1,11 +1,11 @@
 # Graph Report - src  (2026-06-16)
 
 ## Corpus Check
-- Large corpus: 780 files · ~517,635 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
+- Large corpus: 781 files · ~515,927 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
 
 ## Summary
-- 2545 nodes · 3514 edges · 57 communities detected
-- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 768 edges (avg confidence: 0.8)
+- 2560 nodes · 3538 edges · 54 communities detected
+- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 775 edges (avg confidence: 0.8)
 - Token cost: 0 input · 0 output
 
 ## Community Hubs (Navigation)
@@ -43,107 +43,104 @@
 - [[_COMMUNITY_Community 31|Community 31]]
 - [[_COMMUNITY_Community 32|Community 32]]
 - [[_COMMUNITY_Community 33|Community 33]]
-- [[_COMMUNITY_Community 34|Community 34]]
 - [[_COMMUNITY_Community 35|Community 35]]
 - [[_COMMUNITY_Community 36|Community 36]]
 - [[_COMMUNITY_Community 37|Community 37]]
+- [[_COMMUNITY_Community 38|Community 38]]
 - [[_COMMUNITY_Community 39|Community 39]]
 - [[_COMMUNITY_Community 40|Community 40]]
 - [[_COMMUNITY_Community 41|Community 41]]
-- [[_COMMUNITY_Community 42|Community 42]]
 - [[_COMMUNITY_Community 43|Community 43]]
 - [[_COMMUNITY_Community 45|Community 45]]
+- [[_COMMUNITY_Community 46|Community 46]]
 - [[_COMMUNITY_Community 47|Community 47]]
-- [[_COMMUNITY_Community 48|Community 48]]
+- [[_COMMUNITY_Community 50|Community 50]]
 - [[_COMMUNITY_Community 51|Community 51]]
 - [[_COMMUNITY_Community 52|Community 52]]
-- [[_COMMUNITY_Community 53|Community 53]]
+- [[_COMMUNITY_Community 54|Community 54]]
 - [[_COMMUNITY_Community 55|Community 55]]
 - [[_COMMUNITY_Community 56|Community 56]]
 - [[_COMMUNITY_Community 58|Community 58]]
-- [[_COMMUNITY_Community 60|Community 60]]
-- [[_COMMUNITY_Community 61|Community 61]]
 - [[_COMMUNITY_Community 63|Community 63]]
-- [[_COMMUNITY_Community 66|Community 66]]
-- [[_COMMUNITY_Community 68|Community 68]]
+- [[_COMMUNITY_Community 65|Community 65]]
 
 ## God Nodes (most connected - your core abstractions)
-1. `get()` - 259 edges
-2. `push()` - 60 edges
+1. `get()` - 260 edges
+2. `push()` - 63 edges
 3. `emit()` - 27 edges
 4. `WebSocketClient` - 26 edges
 5. `MenuProcessor` - 16 edges
 6. `withFullscreenLoading()` - 15 edges
 7. `VersionManager` - 15 edges
-8. `handleDynamicRoutes()` - 15 edges
-9. `TableCache` - 14 edges
-10. `scopeQuery()` - 14 edges
+8. `set()` - 15 edges
+9. `handleDynamicRoutes()` - 15 edges
+10. `TableCache` - 14 edges
 
 ## Surprising Connections (you probably didn't know these)
-- `handleBatchDelete()` --calls--> `withFullscreenLoading()`  [INFERRED]
-  views/production/consumable/ConsumablePackTab.vue → utils/fullscreen-loading.ts
 - `buildInboundMetaFields()` --calls--> `push()`  [INFERRED]
   utils/production-work-order-card-meta.ts → views/operations/storage-facility/index.vue
 - `fmtMoney()` --calls--> `formatMoneyDisplay()`  [INFERRED]
   components/business/clinical-schedule-payment-detail/index.vue → utils/money-format.ts
-- `formatAmount()` --calls--> `formatMoneyDisplay()`  [INFERRED]
-  views/pilot-service/clinical-payment-confirm/index.vue → utils/money-format.ts
 - `subscribeTokenRefresh()` --calls--> `push()`  [INFERRED]
   utils/http/index.ts → views/operations/storage-facility/index.vue
+- `handleUnauthorizedResponse()` --calls--> `fetchRefreshToken()`  [INFERRED]
+  utils/http/index.ts → api/auth.ts
+- `fetchLeaveList()` --calls--> `get()`  [INFERRED]
+  api/leave.ts → views/production/process/ProcessRouteTab.vue
 
 ## Communities
 
 ### Community 0 - "Community 0"
 Cohesion: 0.01
-Nodes (143): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchChannelAccount(), fetchChannelAgreementPrices(), fetchChannelAgreements() (+135 more)
+Nodes (144): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchChannelAccount(), fetchChannelAgreementPrices(), fetchChannelAgreements() (+136 more)
 
 ### Community 1 - "Community 1"
 Cohesion: 0.02
-Nodes (43): fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllConsumableStockLogs(), fetchAllEquipments(), fetchAllOutputTypes(), fetchAllProcessCategories(), fetchAllProcesses(), fetchAllReagents() (+35 more)
+Nodes (101): fetchUploadAttachment(), fetchMyProductionTasks(), fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), reload(), handleReportUpload(), handleReportUpload() (+93 more)
 
 ### Community 2 - "Community 2"
-Cohesion: 0.04
-Nodes (75): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchPilotCheckupDetail(), markPilotCheckupChecked(), savePilotCheckup(), savePilotCheckupActualItems() (+67 more)
+Cohesion: 0.02
+Nodes (42): fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllConsumableStockLogs(), fetchAllEquipments(), fetchAllOutputTypes(), fetchAllProcessCategories(), fetchAllProcesses(), fetchAllReagents() (+34 more)
 
 ### Community 3 - "Community 3"
-Cohesion: 0.03
-Nodes (51): fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionList(), fetchCheckupInstitutionProjects(), fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchCreateCheckupInstitutionProject(), fetchUpdateCheckupInstitution(), fetchUpdateCheckupInstitutionInvoice() (+43 more)
+Cohesion: 0.04
+Nodes (75): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchPilotCheckupDetail(), markPilotCheckupChecked(), savePilotCheckup(), savePilotCheckupActualItems() (+67 more)
 
 ### Community 4 - "Community 4"
 Cohesion: 0.03
-Nodes (54): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), fetchProductionTaskList(), handleAdd(), handleDelete() (+46 more)
+Nodes (52): fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionList(), fetchCheckupInstitutionProjects(), fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchCreateCheckupInstitutionProject(), fetchUpdateCheckupInstitution(), fetchUpdateCheckupInstitutionInvoice() (+44 more)
 
 ### Community 5 - "Community 5"
-Cohesion: 0.05
-Nodes (60): fetchUploadAttachment(), reload(), handleReportUpload(), handleReportUpload(), walk(), handleMenuJump(), openExternalLink(), async() (+52 more)
+Cohesion: 0.03
+Nodes (42): fetchProductionTaskList(), fetchApproveTask(), fetchBusinessAllTasks(), fetchCompletedTasks(), fetchDesignerData(), fetchInstanceDetail(), fetchMyInstances(), fetchPendingTasks() (+34 more)
 
 ### Community 6 - "Community 6"
-Cohesion: 0.03
-Nodes (40): fetchMyProductionTasks(), fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), for(), set(), annotateForkEdges(), chainApiToElements() (+32 more)
+Cohesion: 0.04
+Nodes (30): fetchGetUserInfo(), ComponentLoader, IframeRouteManager, RouteRegistry, RouteTransformer, useCommon(), setupAfterEachGuard(), closeLoading() (+22 more)
 
 ### Community 7 - "Community 7"
 Cohesion: 0.04
-Nodes (30): fetchGetUserInfo(), ComponentLoader, IframeRouteManager, RouteRegistry, RouteTransformer, useCommon(), setupAfterEachGuard(), closeLoading() (+22 more)
+Nodes (44): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), fetchCreateEnvDetectItem(), fetchDeleteEnvDetectItem(), fetchEnvDetectItemDetail(), fetchEnvDetectItemList() (+36 more)
 
 ### Community 8 - "Community 8"
 Cohesion: 0.05
-Nodes (35): fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed(), fetchClinicalRefundPending(), fetchOrderAdjusts(), fetchOrderDetail() (+27 more)
+Nodes (34): fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed(), fetchClinicalRefundPending(), fetchOrderAdjusts(), fetchOrderDetail() (+26 more)
 
 ### Community 9 - "Community 9"
-Cohesion: 0.05
-Nodes (29): collectIds(), useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), collectAllPostBindDeptIds() (+21 more)
-
-### Community 10 - "Community 10"
 Cohesion: 0.06
 Nodes (11): fetchGetLatestUpgradeLog(), getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager (+3 more)
 
-### Community 11 - "Community 11"
+### Community 10 - "Community 10"
 Cohesion: 0.06
 Nodes (30): buildBaseFields(), buildInboundBasicSection(), buildInboundCellStorageProductionViewSections(), buildInboundResearchDonationProductionViewSections(), buildOutboundBasicExperimentProductionViewSections(), buildOutboundClinicalProductionViewSections(), buildOutboundDetail(), buildOutboundPilotProductionViewSections() (+22 more)
 
+### Community 11 - "Community 11"
+Cohesion: 0.05
+Nodes (29): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), collectAllPostBindDeptIds(), collectPostBindDeptSubtreeIds() (+21 more)
+
 ### Community 12 - "Community 12"
 Cohesion: 0.05
-Nodes (27): fetchAttachmentDownloadUrl(), qcAttachmentFullUrl(), qcDownloadAttachment(), qcPreviewAttachment(), formatHandoverUserLabel(), formatNowDatetime(), fullFileUrl(), handleDownloadAttachment() (+19 more)
+Nodes (28): handleBlur(), handleFocus(), handleInput(), fetchEthnicList(), formatAmount(), formatAmount(), formatProtocolAmount(), buildFeeSection() (+20 more)
 
 ### Community 13 - "Community 13"
 Cohesion: 0.05
@@ -151,23 +148,23 @@ Nodes (13): fmtMoney(), auditorDisplay(), dash(), ensureUnitsInOptions(), expres
 
 ### Community 14 - "Community 14"
 Cohesion: 0.05
-Nodes (27): handleBlur(), handleFocus(), handleInput(), fetchEthnicList(), formatAmount(), formatProtocolAmount(), buildFeeSection(), applyDonationBundleToForm() (+19 more)
+Nodes (28): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList(), fetchPaymentDetailList(), fetchReceiptConfirmedList(), fetchReceiptConfirmList() (+20 more)
 
 ### Community 15 - "Community 15"
-Cohesion: 0.05
-Nodes (28): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList(), fetchPaymentDetailList(), fetchReceiptConfirmedList(), fetchReceiptConfirmList() (+20 more)
+Cohesion: 0.07
+Nodes (23): fetchGetMenuList(), fetchGetMenuCodes(), fetchLogin(), fetchRefreshToken(), fetchUpdateProfile(), fetchUploadProfileAvatar(), MenuProcessor, useAppMode() (+15 more)
 
 ### Community 16 - "Community 16"
-Cohesion: 0.06
-Nodes (29): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), buildInboundBasicSection(), buildInboundCellStorageViewSections(), buildInboundResearchDonationViewSections(), buildReceptionSection() (+21 more)
+Cohesion: 0.07
+Nodes (33): fetchUserList(), fetchAddTaskStep(), fetchCopyTaskStep(), fetchDeleteTaskStep(), fetchForwardProductionTask(), fetchProductionTaskDetail(), fetchReassignProductionTask(), fetchReorderTaskSteps() (+25 more)
 
 ### Community 17 - "Community 17"
 Cohesion: 0.07
-Nodes (22): fetchGetMenuList(), fetchGetMenuCodes(), fetchLogin(), fetchUpdateProfile(), fetchUploadProfileAvatar(), MenuProcessor, useAppMode(), useAuth() (+14 more)
+Nodes (24): fetchDeleteQcMaterialBatch(), fetchQcMaterialBatchList(), fetchQcMaterialBatchOptions(), fetchQcMaterialList(), fetchQcMaterialOptions(), fetchUpdateQcMaterialBatch(), fetchMarkQcMaterialUsageFullyUsed(), ensureTabMounted() (+16 more)
 
 ### Community 18 - "Community 18"
-Cohesion: 0.07
-Nodes (24): fetchDeleteQcMaterialBatch(), fetchQcMaterialBatchList(), fetchQcMaterialBatchOptions(), fetchQcMaterialList(), fetchQcMaterialOptions(), fetchUpdateQcMaterialBatch(), fetchMarkQcMaterialUsageFullyUsed(), ensureTabMounted() (+16 more)
+Cohesion: 0.06
+Nodes (24): fetchAttachmentDownloadUrl(), qcAttachmentFullUrl(), qcDownloadAttachment(), qcPreviewAttachment(), handleDownloadAttachment(), fullFileUrl(), handleDownloadAttachment(), handlePreviewAttachment() (+16 more)
 
 ### Community 19 - "Community 19"
 Cohesion: 0.1
@@ -175,27 +172,27 @@ Nodes (2): WebSocketClient, TableCache
 
 ### Community 20 - "Community 20"
 Cohesion: 0.08
-Nodes (33): fetchRefreshToken(), toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url() (+25 more)
+Nodes (28): fetchUserOptions(), fetchSampleReceptionCheckItemList(), fetchSampleReceptionCheckItemsActive(), fetchAllocateLabStorageCodes(), fetchSampleReceptionBySampleCode(), fetchSampleReceptionDetail(), fetchSampleReceptionPendingList(), fetchSampleReceptionReceivedList() (+20 more)
 
 ### Community 21 - "Community 21"
 Cohesion: 0.08
-Nodes (28): fetchUserOptions(), fetchSampleReceptionCheckItemList(), fetchSampleReceptionCheckItemsActive(), fetchAllocateLabStorageCodes(), fetchSampleReceptionBySampleCode(), fetchSampleReceptionDetail(), fetchSampleReceptionPendingList(), fetchSampleReceptionReceivedList() (+20 more)
+Nodes (32): toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes() (+24 more)
 
 ### Community 22 - "Community 22"
 Cohesion: 0.09
-Nodes (28): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), clearTableSelection(), handleBatchComplete(), handleBatchStart() (+20 more)
+Nodes (26): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), handleDelete(), handleDropdownCommand(), handleEdit() (+18 more)
 
 ### Community 23 - "Community 23"
-Cohesion: 0.08
-Nodes (16): fetchDeleteMaterialBatch(), fetchMaterialBatchList(), fetchMaterialBatchOptions(), fetchMaterialList(), fetchMaterialOptions(), fetchUpdateMaterialBatch(), fetchMaterialUsageList(), fetchMyMaterialUsageList() (+8 more)
+Cohesion: 0.09
+Nodes (28): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), clearTableSelection(), handleBatchComplete(), handleBatchStart() (+20 more)
 
 ### Community 24 - "Community 24"
-Cohesion: 0.1
-Nodes (27): fetchUserList(), fetchAddTaskStep(), fetchCopyTaskStep(), fetchDeleteTaskStep(), fetchForwardProductionTask(), fetchProductionTaskDetail(), fetchReassignProductionTask(), fetchReorderTaskSteps() (+19 more)
+Cohesion: 0.08
+Nodes (16): fetchDeleteMaterialBatch(), fetchMaterialBatchList(), fetchMaterialBatchOptions(), fetchMaterialList(), fetchMaterialOptions(), fetchUpdateMaterialBatch(), fetchMaterialUsageList(), fetchMyMaterialUsageList() (+8 more)
 
 ### Community 25 - "Community 25"
-Cohesion: 0.12
-Nodes (24): fetchCellProductSpecList(), fetchCellProductTypeList(), applyProductCodeToLines(), calcExpiryFromFreeze(), createEmptyProductLine(), createQuantityValue(), getLineStorageSlotOptions(), getOtherLineStorageSlotIds() (+16 more)
+Cohesion: 0.11
+Nodes (26): fetchCellProductSpecList(), fetchCellProductTypeList(), handleAdd(), resetForm(), applyProductCodeToLines(), calcExpiryFromFreeze(), createEmptyProductLine(), createQuantityValue() (+18 more)
 
 ### Community 26 - "Community 26"
 Cohesion: 0.13
@@ -206,89 +203,89 @@ Cohesion: 0.12
 Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
 
 ### Community 28 - "Community 28"
-Cohesion: 0.13
-Nodes (18): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchDeleteCellSampleType(), fetchUpdateCellSampleType(), handleAdd(), handleDelete(), handleDropdownCommand(), handleEdit() (+10 more)
+Cohesion: 0.11
+Nodes (11): fetchOutboundReleaseMaterial(), fetchOutboundReleaseReviewDetail(), fetchOutboundReleaseReviewList(), fetchReleaseReviewList(), handleReset(), handleSearch(), handleToggleSelect(), loadData() (+3 more)
 
 ### Community 29 - "Community 29"
-Cohesion: 0.12
-Nodes (12): fetchApproveTask(), fetchBusinessAllTasks(), fetchCompletedTasks(), fetchDesignerData(), fetchInstanceDetail(), fetchMyInstances(), fetchPendingTasks(), fetchProcessDefList() (+4 more)
+Cohesion: 0.13
+Nodes (18): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchDeleteCellSampleType(), fetchUpdateCellSampleType(), handleAdd(), handleDelete(), handleDropdownCommand(), handleEdit() (+10 more)
 
 ### Community 30 - "Community 30"
-Cohesion: 0.14
-Nodes (9): fetchServiceOrderTxnList(), handleReset(), handleSearch(), handleTabChange(), loadData(), switchTab(), formatLocalDate(), getDefaultLast30DaysRange() (+1 more)
+Cohesion: 0.16
+Nodes (10): useTable(), useTableImpl(), getColumnChecks(), useTableColumns(), createErrorHandler(), createSmartDebounce(), defaultResponseAdapter(), extractPagination() (+2 more)
 
 ### Community 31 - "Community 31"
-Cohesion: 0.16
-Nodes (14): fetchCreateEnvDetectItem(), fetchDeleteEnvDetectItem(), fetchEnvDetectItemDetail(), fetchEnvDetectItemList(), fetchEnvDetectItemsActive(), fetchUpdateEnvDetectItem(), handleAdd(), handleBatchDelete() (+6 more)
+Cohesion: 0.27
+Nodes (14): useChart(), useChartComponent(), useChartOps(), colourBlend(), getCssVar(), getDarkColor(), getLightColor(), handleElementThemeColor() (+6 more)
 
 ### Community 32 - "Community 32"
-Cohesion: 0.13
-Nodes (8): fetchOutboundReleaseMaterial(), fetchOutboundReleaseReviewDetail(), fetchOutboundReleaseReviewList(), fetchReleaseReviewList(), handleReset(), handleSearch(), loadData(), onReviewSubmitted()
+Cohesion: 0.33
+Nodes (13): buildProtocolPaymentFlowSteps(), dash(), financeReceiptTime(), formatAmount(), hasFinanceReceipt(), hasFinanceRefund(), hasReceiptSubmit(), hasRefundSubmit() (+5 more)
 
 ### Community 33 - "Community 33"
-Cohesion: 0.16
-Nodes (10): useTable(), useTableImpl(), getColumnChecks(), useTableColumns(), createErrorHandler(), createSmartDebounce(), defaultResponseAdapter(), extractPagination() (+2 more)
-
-### Community 34 - "Community 34"
-Cohesion: 0.27
-Nodes (14): useChart(), useChartComponent(), useChartOps(), colourBlend(), getCssVar(), getDarkColor(), getLightColor(), handleElementThemeColor() (+6 more)
+Cohesion: 0.19
+Nodes (6): fetchServiceOrderTxnList(), handleReset(), handleSearch(), handleTabChange(), loadData(), switchTab()
 
 ### Community 35 - "Community 35"
-Cohesion: 0.12
-Nodes (4): fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList(), fetchSampleSmsNotificationList()
+Cohesion: 0.17
+Nodes (3): fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList()
 
 ### Community 36 - "Community 36"
-Cohesion: 0.16
-Nodes (5): canDeleteWorkOrder(), canDispatchTask(), canEditWorkOrder(), handleCardSelect(), hasMoreActions()
-
-### Community 37 - "Community 37"
-Cohesion: 0.33
-Nodes (13): buildProtocolPaymentFlowSteps(), dash(), financeReceiptTime(), formatAmount(), hasFinanceReceipt(), hasFinanceRefund(), hasReceiptSubmit(), hasRefundSubmit() (+5 more)
-
-### Community 39 - "Community 39"
 Cohesion: 0.18
 Nodes (3): normalizeStepSubTables(), parseEquipmentIds(), syncEquipmentNamesFromOptions()
 
-### Community 40 - "Community 40"
+### Community 37 - "Community 37"
 Cohesion: 0.24
 Nodes (6): buildInboundMetaFields(), getCardMetaConfig(), getCardMetaConfigForLegacyTab(), parseReceptionTime(), receptionOver24HoursLabel(), receptionOver24HoursTagType()
 
-### Community 41 - "Community 41"
+### Community 38 - "Community 38"
 Cohesion: 0.42
 Nodes (9): buildPaymentFlowSteps(), dash(), formatAmount(), hasFinanceReceipt(), hasFinanceRefund(), hasReceiptSubmit(), hasRefundSubmit(), receiptSubmitTime() (+1 more)
 
-### Community 42 - "Community 42"
+### Community 39 - "Community 39"
+Cohesion: 0.29
+Nodes (5): canConfigureWorkOrder(), canDeleteWorkOrder(), canEditRemarkWorkOrder(), canEditTemporaryWorkOrder(), hasMoreWorkOrderActions()
+
+### Community 40 - "Community 40"
+Cohesion: 0.25
+Nodes (2): handleTouchEnd(), setTransition()
+
+### Community 41 - "Community 41"
 Cohesion: 0.28
 Nodes (1): FireworkSystem
 
 ### Community 43 - "Community 43"
-Cohesion: 0.25
-Nodes (2): handleTouchEnd(), setTransition()
+Cohesion: 0.31
+Nodes (4): annotateForkEdges(), chainApiToElements(), walkAncestorBranch(), walkAncestorParents()
 
 ### Community 45 - "Community 45"
 Cohesion: 0.28
 Nodes (4): fetchMyProductionMaterialConsumptions(), handleReset(), handleSearch(), loadData()
 
-### Community 47 - "Community 47"
+### Community 46 - "Community 46"
 Cohesion: 0.39
 Nodes (6): isIgnorableScriptError(), normalizeErrorMessage(), registerPromiseErrorHandler(), registerResourceErrorHandler(), scriptErrorHandler(), setupErrorHandle()
 
-### Community 48 - "Community 48"
+### Community 47 - "Community 47"
 Cohesion: 0.36
 Nodes (1): TableHeightCalculator
 
-### Community 51 - "Community 51"
+### Community 50 - "Community 50"
 Cohesion: 0.33
 Nodes (2): logApiCryptoBootInfo(), maskSecret()
 
-### Community 52 - "Community 52"
+### Community 51 - "Community 51"
 Cohesion: 0.29
 Nodes (2): fetchLeaveDetail(), fetchLeaveList()
 
-### Community 53 - "Community 53"
+### Community 52 - "Community 52"
 Cohesion: 0.47
 Nodes (3): isPaymentDueWithinWarnWindow(), parsePaymentDueYmd(), startOfLocalDay()
 
+### Community 54 - "Community 54"
+Cohesion: 0.33
+Nodes (2): fetchQcLabTestItemList(), fetchQcLabTestItemsActive()
+
 ### Community 55 - "Community 55"
 Cohesion: 0.5
 Nodes (2): formatProtocolDocDeleteConfirm(), formatProtocolDocSubject()
@@ -301,38 +298,28 @@ Nodes (2): focusInput(), handleKeydown()
 Cohesion: 0.67
 Nodes (2): if(), logSidebarMenu()
 
-### Community 60 - "Community 60"
-Cohesion: 0.5
-Nodes (1): fetchStorageEntrySmsList()
-
-### Community 61 - "Community 61"
-Cohesion: 0.5
-Nodes (1): fetchQcSmsList()
-
 ### Community 63 - "Community 63"
-Cohesion: 0.83
-Nodes (3): formatLocalDate(), getDefaultLast30DaysRange(), useProductionWorkOrderTabPage()
-
-### Community 66 - "Community 66"
 Cohesion: 1.0
 Nodes (2): getSettingDefaults(), resetToDefaults()
 
-### Community 68 - "Community 68"
+### Community 65 - "Community 65"
 Cohesion: 1.0
 Nodes (2): copyTextToClipboard(), copyTextWithFallback()
 
 ## Knowledge Gaps
 - **Thin community `Community 19`** (42 nodes): `WebSocketClient`, `.calculateReconnectDelay()`, `.clearAllTimers()`, `.clearConnectionTimers()`, `.clearTimer()`, `.close()`, `.closeCurrentSocketForReconnect()`, `.connect()`, `.connectionStatusText()`, `.constructor()`, `.destroyInstance()`, `.flushMessageQueue()`, `.getInstance()`, `.getReadyStateText()`, `.handleClose()`, `.handleConnectionTimeout()`, `.handleError()`, `.handleMessage()`, `.handleOpen()`, `.init()`, `.isWebSocketConnected()`, `.reconnect()`, `.resetHeartbeat()`, `.send()`, `.startHeartbeat()`, `.startPing()`, `TableCache`, `.cleanupExpired()`, `.clear()`, `.clearByTags()`, `.clearCurrentSearch()`, `.clearPagination()`, `.constructor()`, `.evictLRU()`, `.generateKey()`, `.generateTags()`, `.get()`, `.getStats()`, `.log()`, `.set()`, `index.ts`, `tableCache.ts`
   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`
+- **Thin community `Community 40`** (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 43`** (9 nodes): `cleanupEventListeners()`, `handleTouchEnd()`, `handleTouchMove()`, `handleTouchStart()`, `handleWheelScroll()`, `if()`, `setTransition()`, `setupEventListeners()`, `index.vue`
+- **Thin community `Community 41`** (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`
+- **Thin community `Community 47`** (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 51`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
+- **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`
+- **Thin community `Community 51`** (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 54`** (6 nodes): `fetchCreateQcLabTestItem()`, `fetchDeleteQcLabTestItem()`, `fetchQcLabTestItemList()`, `fetchQcLabTestItemsActive()`, `fetchUpdateQcLabTestItem()`, `qc-lab-test-item.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
 - **Thin community `Community 55`** (5 nodes): `formatProtocolDocBatchDeleteConfirm()`, `formatProtocolDocDeleteConfirm()`, `formatProtocolDocSubject()`, `getProtocolDocTypeLabel()`, `protocol-doc-label.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
@@ -340,28 +327,24 @@ Nodes (2): copyTextToClipboard(), copyTextWithFallback()
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
 - **Thin community `Community 58`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 60`** (4 nodes): `fetchGenerateStorageEntrySms()`, `fetchStorageEntrySmsList()`, `fetchToggleStorageEntrySmsNotified()`, `storage-entry-sms-notification.ts`
-  Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 61`** (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 66`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
+- **Thin community `Community 63`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 68`** (3 nodes): `copyTextToClipboard()`, `copyTextWithFallback()`, `copy-text.ts`
+- **Thin community `Community 65`** (3 nodes): `copyTextToClipboard()`, `copyTextWithFallback()`, `copy-text.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
 
 ## Suggested Questions
 _Questions this graph is uniquely positioned to answer:_
 
-- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 18`, `Community 21`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 35`, `Community 45`, `Community 52`, `Community 60`, `Community 61`?**
-  _High betweenness centrality (0.393) - this node is a cross-community bridge._
-- **Why does `push()` connect `Community 5` to `Community 0`, `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 6`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 16`, `Community 19`, `Community 20`, `Community 22`, `Community 25`, `Community 40`, `Community 42`?**
-  _High betweenness centrality (0.183) - this node is a cross-community bridge._
-- **Why does `emit()` connect `Community 4` to `Community 2`, `Community 3`, `Community 36`, `Community 14`, `Community 21`, `Community 24`, `Community 29`?**
-  _High betweenness centrality (0.035) - this node is a cross-community bridge._
-- **Are the 258 inferred relationships involving `get()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
-  _`get()` has 258 INFERRED edges - model-reasoned connections that need verification._
-- **Are the 59 inferred relationships involving `push()` (e.g. with `collectLeafFacilityNodesInTreeOrder()` and `formatDetectMethods()`) actually correct?**
-  _`push()` has 59 INFERRED edges - model-reasoned connections that need verification._
+- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 11`, `Community 12`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 20`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 28`, `Community 29`, `Community 33`, `Community 35`, `Community 43`, `Community 45`, `Community 51`, `Community 54`?**
+  _High betweenness centrality (0.368) - this node is a cross-community bridge._
+- **Why does `push()` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 7`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 16`, `Community 19`, `Community 21`, `Community 23`, `Community 25`, `Community 37`, `Community 41`?**
+  _High betweenness centrality (0.188) - this node is a cross-community bridge._
+- **Why does `emit()` connect `Community 5` to `Community 3`, `Community 4`, `Community 12`, `Community 16`, `Community 20`, `Community 22`, `Community 25`?**
+  _High betweenness centrality (0.043) - this node is a cross-community bridge._
+- **Are the 259 inferred relationships involving `get()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
+  _`get()` has 259 INFERRED edges - model-reasoned connections that need verification._
+- **Are the 62 inferred relationships involving `push()` (e.g. with `collectLeafFacilityNodesInTreeOrder()` and `formatDetectMethods()`) actually correct?**
+  _`push()` has 62 INFERRED edges - model-reasoned connections that need verification._
 - **Are the 26 inferred relationships involving `emit()` (e.g. with `handleSubmit()` and `handleBlur()`) actually correct?**
   _`emit()` has 26 INFERRED edges - model-reasoned connections that need verification._
 - **Should `Community 0` be split into smaller, more focused modules?**

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
web-admin/graphify-out/graph.html


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 153 - 117
web-admin/graphify-out/graph.json


+ 64 - 63
web-admin/graphify-out/manifest.json

@@ -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": 1781592426.9017382,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1781592338.8734117,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1781600240.744298,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1781599999.934328,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/store/index.ts": 1781272556.364766,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/router/index.ts": 1781272556.3652694,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/locales/index.ts": 1781272556.3657222,
@@ -42,23 +42,23 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/enums/appEnum.ts": 1781272556.3784597,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/patch-el-select-filterable.ts": 1781272556.3791182,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/storage-slot-options.ts": 1781534662.3091736,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-tabs.ts": 1781583180.239002,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-tabs.ts": 1781600464.3251936,
   "/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/qc-material-ui.ts": 1781525352.6976836,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-tabs.ts": 1781582340.4840112,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts": 1781589268.1070106,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-tabs.ts": 1781600462.9964879,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts": 1781595914.1273482,
   "/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": 1781583493.924234,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-mine-task-groups.ts": 1781581216.9582837,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-mine-task-groups.ts": 1781595945.3450615,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-payment-labels.ts": 1781272556.3878465,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts": 1781590344.2129211,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts": 1781583236.4287024,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts": 1781595872.8488274,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/fetch-paged-list.ts": 1781272556.3903377,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/sort-order.ts": 1781272556.3913012,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/outbound-qc-pilot-view-sections.ts": 1781566346.7618802,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-groups.ts": 1781272556.394584,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-groups.ts": 1781595881.1878915,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/equipment-select.ts": 1781524048.96866,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/clinical-payment-flow-steps.ts": 1781566916.7893076,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/copy-text.ts": 1781272556.4018052,
@@ -198,16 +198,16 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-payment-confirm-timeline/index.vue": 1781585388.635286,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/dialog-form-body/index.vue": 1781272556.6276903,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-payment-submit-readonly/index.vue": 1781566692.993364,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-cards/index.vue": 1781590356.8505912,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-cards/index.vue": 1781596037.4093332,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/order-operate-local-dialog/index.vue": 1781272556.6297834,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/product-view-dialog/index.vue": 1781563767.2879,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-production-info-cards/index.vue": 1781585388.6388853,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-storage-release-info/index.vue": 1781585388.6396642,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue": 1781585388.6402879,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue": 1781595984.8103893,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/work-order-remark-dialog/index.vue": 1781563767.2910764,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-grouped-panel/index.vue": 1781589676.758837,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-grouped-panel/index.vue": 1781596014.9588113,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue": 1781585388.6415968,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-form-sections/index.vue": 1781585388.6421032,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-form-sections/index.vue": 1781598316.2599268,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/protocol-payment-detail-readonly/index.vue": 1781440987.1200492,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/system-view-dialog/index.vue": 1781592191.1258788,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue": 1781272556.644192,
@@ -230,7 +230,7 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception-check-item.ts": 1781272556.654672,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts": 1781497438.3206656,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/infusion-schedule-handover.ts": 1781272556.6558568,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts": 1781272556.6563854,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts": 1781597289.1718442,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-third-party-item.ts": 1781272556.6567156,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/env-detect-record.ts": 1781272556.6569912,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts": 1781536765.5084789,
@@ -265,53 +265,53 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material.ts": 1781346022.817811,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts": 1781496419.5874305,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/auth.ts": 1781272556.6719868,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts": 1781581196.5778718,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts": 1781596860.828625,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/auth/login/index.vue": 1781272556.6735966,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/refund-confirm/index.vue": 1781272556.6742516,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/my-material-usage/index.vue": 1781518736.690082,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/index.vue": 1781272556.6752698,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/index.vue": 1781600343.1604354,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue": 1781440943.514069,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue": 1781592190.3803153,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue": 1781599760.586079,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue": 1781585388.6583154,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue": 1781585388.659485,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue": 1781599762.361165,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolAuditDialog.vue": 1781440939.3081548,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-info/index.vue": 1781585388.6613626,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-info/index.vue": 1781599990.94571,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-reception-info/index.vue": 1781272556.6985002,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-info/index.vue": 1781272556.6988573,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/storage-cert/index.vue": 1781272556.6992679,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/index.vue": 1781585388.662044,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/StorageEntryInfoTab.vue": 1781272556.7007048,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/index.vue": 1781599996.9031687,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/StorageEntryInfoTab.vue": 1781600376.7402449,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/SampleCollectionInfoTab.vue": 1781272556.7014923,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/SampleQcInfoTab.vue": 1781272556.7023191,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/SampleReceptionInfoTab.vue": 1781272556.703238,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/StorageCertTab.vue": 1781585388.664579,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/FullmoonTodoTab.vue": 1781585388.6669154,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/ProtocolAuditTab.vue": 1781585411.4355936,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/PaymentInfoTab.vue": 1781585388.6679676,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/SampleQcInfoTab.vue": 1781600375.004251,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/SampleReceptionInfoTab.vue": 1781600372.1736586,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/StorageCertTab.vue": 1781600388.1296115,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/FullmoonTodoTab.vue": 1781600384.5577803,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/ProtocolAuditTab.vue": 1781600358.1818085,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/PaymentInfoTab.vue": 1781600466.0076118,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue": 1781563767.3149889,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/MaterialUsageTab.vue": 1781503550.8574874,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/MaterialUsageTab.vue": 1781598316.645277,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/MaterialStockCheckTab.vue": 1781578349.395239,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue": 1781272556.719875,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/storage-entry-info/index.vue": 1781272556.7201529,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-confirm/index.vue": 1781568150.9471092,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-confirm/RefundConfirmTab.vue": 1781568153.9830499,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-confirm/index.vue": 1781600401.4995606,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-confirm/RefundConfirmTab.vue": 1781600413.8415418,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material-stock-log/index.vue": 1781346115.5701284,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/outside/Iframe.vue": 1781272556.7246568,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/operations/demo/index.vue": 1781272556.7266567,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/operations/clean-room/index.vue": 1781585388.6729288,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/operations/storage-facility/index.vue": 1781594230.0853102,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/operations/exhibition-appointment/index.vue": 1781563767.3254354,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/audit/index.vue": 1781591411.3496523,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/operations/exhibition-appointment/index.vue": 1781600464.861937,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/audit/index.vue": 1781600355.3898988,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/sample-info/index.vue": 1781518738.227001,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/sample-info/DonationSampleCollectionInfoTab.vue": 1781272556.7362974,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/index.vue": 1781272556.7375543,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/index.vue": 1781600353.1619346,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationAuditDialog.vue": 1781563767.3746796,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue": 1781592190.9459805,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue": 1781585388.6780984,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue": 1781599799.1281025,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue": 1781599783.436885,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue": 1781563767.3753123,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/dashboard/console/index.vue": 1781272556.7480726,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/tenant/index.vue": 1781563767.3820128,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/order/index.vue": 1781585388.6803534,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/order/index.vue": 1781599786.579335,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/unit/index.vue": 1781563767.3823607,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/role/index.vue": 1781563767.3808904,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/post/index.vue": 1781563767.37969,
@@ -355,7 +355,7 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/CompleteProductionTaskDialog.vue": 1781563767.3525257,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskInputEnhancedTable.vue": 1781585388.6972075,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchQcWorkOrderDialog.vue": 1781585388.6976979,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/SampleReceptionDialog.vue": 1781585388.6982691,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/SampleReceptionDialog.vue": 1781599793.4040868,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue": 1781588551.0654483,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue": 1781577178.2471955,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskOutputList.vue": 1781585388.699347,
@@ -375,7 +375,7 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/tabs/OutboundClinicalTab.vue": 1781583382.4319067,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/production-view-sections.ts": 1781583319.8749113,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/useProductionViewDialog.ts": 1781587764.7598283,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/useProductionWorkOrderTabPage.ts": 1781583356.0458994,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/useProductionWorkOrderTabPage.ts": 1781600314.4294987,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/InboundResearchDonationProductionViewDialog.vue": 1781583332.0303154,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/OutboundClinicalProductionViewDialog.vue": 1781583335.85169,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/InboundCellStorageProductionViewDialog.vue": 1781583329.8775995,
@@ -397,22 +397,22 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/sample-reception-completion/index.vue": 1781272556.844081,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/my-production-task/index.vue": 1781583391.5411932,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/equipment/index.vue": 1781563767.347355,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process/index.vue": 1781526289.043476,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process/index.vue": 1781599788.6457248,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process/ProcessRouteTab.vue": 1781588546.7932389,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process-category/index.vue": 1781585388.7112913,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process-category/OutputTypeTab.vue": 1781563767.348404,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/index/index.vue": 1781272556.8548205,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue": 1781592807.1040754,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskResultPanel.vue": 1781589482.0890527,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSingleCard.vue": 1781589271.5066688,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSingleCard.vue": 1781595993.2583652,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderFeeSummaryBar.vue": 1781585388.7152023,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSampleGroup.vue": 1781585388.716047,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSampleGroup.vue": 1781599843.890257,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue": 1781590356.5447705,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderCardList.vue": 1781584243.5730777,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderCardList.vue": 1781595924.5325,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderProtocolPaymentPanel.vue": 1781588255.9076052,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/OutboundPilotTab.vue": 1781582034.0446215,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/InboundCellStorageTab.vue": 1781582031.9110096,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/QcWorkOrderTabPanel.vue": 1781584494.5134242,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/QcWorkOrderTabPanel.vue": 1781595942.9077249,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/OutboundBasicExperimentTab.vue": 1781582033.9975233,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/InboundResearchDonationTab.vue": 1781582033.9975069,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/TemporaryTab.vue": 1781582036.0799434,
@@ -423,7 +423,7 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useInboundQcViewDialog.ts": 1781589515.800703,
   "/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/inbound-view-sections.ts": 1781581785.95148,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts": 1781582179.1727624,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts": 1781600311.9968688,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/QcWorkOrderSystemViewDialog.vue": 1781589553.6371684,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundQcProductTable.vue": 1781588255.5778198,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundQcDiagnosisAttachments.vue": 1781581843.4276094,
@@ -441,7 +441,7 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue": 1781578449.997224,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialStockCheckTab.vue": 1781563767.3635929,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue": 1781525390.91805,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue": 1781585388.7336364,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue": 1781600467.5571728,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/SampleReceptionCardList.vue": 1781585388.7346976,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/my-qc-task/index.vue": 1781582341.1215634,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/env-detect-record/index.vue": 1781585388.736309,
@@ -462,29 +462,30 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-institution/index.vue": 1781563767.334401,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-institution/CheckupPackagePanel.vue": 1781563767.3335872,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/index.vue": 1781272556.9129293,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/InfusionScheduleHandoverDialog.vue": 1781585388.7500947,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleViewDialog.vue": 1781585388.7510092,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/InfusionScheduleHandoverDialog.vue": 1781598379.1921296,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleViewDialog.vue": 1781595979.906165,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleCancelDialog.vue": 1781566676.0091887,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/infusion-schedule-management/ScheduleEditDialog.vue": 1781585388.7521496,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue": 1781272556.9223943,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnTable.vue": 1781272556.9230614,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnTable.vue": 1781599314.0203812,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue": 1781585388.7532763,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue": 1781585388.7547998,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelViewDialog.vue": 1781585388.7555263,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelServiceOrderTab.vue": 1781585388.7567787,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue": 1781599738.8971999,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelViewDialog.vue": 1781599756.9191692,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelServiceOrderTab.vue": 1781600424.9531324,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-refund-confirm/index.vue": 1781272556.946893,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/index.vue": 1781585388.7576923,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue": 1781585388.758139,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue": 1781566364.5341365,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseViewDialog.vue": 1781585388.7590504,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue": 1781585388.7596958,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseMaterialDialog.vue": 1781585388.7602465,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/index.vue": 1781585388.760662,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationDetailDialog.vue": 1781585388.7617104,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/index.vue": 1781600465.6143773,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseViewDialog.vue": 1781596823.2469816,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewDialog.vue": 1781596862.0797033,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseMaterialDialog.vue": 1781597037.1667814,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseReviewCardList.vue": 1781598589.824023,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/index.vue": 1781600006.408287,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationDetailDialog.vue": 1781599768.7755723,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/PilotApplicationTab.vue": 1781272557.1928792,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue": 1781586000.558457,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/InfusionScheduleTab.vue": 1781566659.2158477,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue": 1781585388.764479,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue": 1781599765.8567426,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/InfusionScheduleTab.vue": 1781600431.8481567,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationFormDialog.vue": 1781599780.0277336,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/CheckupManagementTab.vue": 1781435201.7785301,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ClinicalPaymentTab.vue": 1781585388.765392,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-price/index.vue": 1781272557.4568446,
@@ -494,10 +495,10 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupRegisterDialog.vue": 1781585388.7670863,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupDetailDialog.vue": 1781585388.7674935,
   "/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": 1781563767.3352747,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupMarkCheckedDialog.vue": 1781585388.7684867,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupFillDialog.vue": 1781594573.8421357,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-management/CheckupMarkCheckedDialog.vue": 1781594629.8261228,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/clinical-payment-info/index.vue": 1781272558.0460358,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue": 1781585388.7694304,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue": 1781600445.1879845,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/project-price-system/index.vue": 1781272558.2950988,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-spec/index.vue": 1781272558.3464932,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue": 1781272558.356484,
@@ -505,7 +506,7 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/cell-sample-type/SampleCodeTab.vue": 1781563767.3067288,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/insurance-company/index.vue": 1781563767.3120062,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue": 1781272558.4055521,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue": 1781563767.3112528,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue": 1781600332.4914014,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue": 1781563767.310876,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/CollectionProtocolNoTab.vue": 1781563767.3099859,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/assets/svg/loading.ts": 1781272558.486104,

+ 2 - 0
web-admin/src/api/outbound-release-review.ts

@@ -25,6 +25,7 @@ export type OutboundReleaseReview = {
   patientName?: string
   cellType?: string
   specText?: string
+  products?: OutboundQcDetailProduct[]
   infusionTime?: string
   scheduleStatus?: string
   scheduleStatusLabel?: string
@@ -102,6 +103,7 @@ export type OutboundReleaseReviewDetail = {
   products?: OutboundQcDetailProduct[]
   productionInfo?: OutboundProductionInfo
   qcInfo?: OutboundQcInfo
+  processQcInfoList?: OutboundQcInfo[]
   reviewInfo?: OutboundReviewInfo
   outboundMaterial?: OutboundReleaseMaterialDetail
 }

+ 6 - 0
web-admin/src/api/qc-work-order.ts

@@ -248,6 +248,12 @@ export type OutboundQcDetailApplication = {
   applicationName?: string
   applicationStatus?: string
   channelName?: string
+  bizType?: string
+  bizTypeLabel?: string
+  projectTitle?: string
+  customerName?: string
+  customerContact?: string
+  customerPhone?: string
 }
 
 export type OutboundQcDetailPatient = {

+ 220 - 19
web-admin/src/assets/styles/core/app.scss

@@ -417,7 +417,7 @@ body {
   }
 }
 
-// 面板级胶囊分段 Tab(居中,对齐 docs/panel-tab-demos/02-pill-segmented)
+// 面板级胶囊分段 Tab(薄荷绿渐变轨道 + 主色选中,对齐渠道管理等页)
 .panel-pill-tabs {
   // 自定义按钮结构(质检物料库等)
   &:not(.el-tabs) {
@@ -451,8 +451,8 @@ body {
     display: inline-flex;
     gap: 4px;
     padding: 4px;
-    background: #f1f5f9;
-    border: 1px solid var(--mint-border, #e2e8f0);
+    background: linear-gradient(180deg, var(--primary-bg, #ecfdf5) 0%, #fff 100%);
+    border: 1px solid #d1fae5;
     border-radius: 8px;
   }
 
@@ -479,15 +479,19 @@ body {
       box-shadow 0.15s;
 
     &:hover:not(.is-active) {
-      color: var(--mint-text-muted, #334155);
-      background: rgba(255, 255, 255, 0.6);
+      color: #065f46;
     }
 
     &.is-active {
-      background: #fff;
-      color: var(--primary-dark, #059669);
-      box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08);
-      font-weight: 600;
+      background: var(--primary, #10b981);
+      color: #fff;
+      box-shadow: 0 1px 3px rgba(16, 185, 129, 0.28);
+      font-weight: 500;
+
+      &:hover {
+        color: #fff;
+        background: var(--primary, #10b981);
+      }
     }
   }
 
@@ -507,13 +511,13 @@ body {
     font-size: 11px;
     font-weight: 600;
     line-height: 1;
-    border: 2px solid #f1f5f9;
+    border: 2px solid #d1fae5;
     pointer-events: none;
     box-sizing: border-box;
   }
 
   &__btn.is-active &__badge {
-    border-color: #fff;
+    border-color: var(--primary, #10b981);
   }
 
   // el-tabs 结构
@@ -544,8 +548,8 @@ body {
       gap: 4px;
       float: none;
       padding: 4px;
-      background: #f1f5f9;
-      border: 1px solid var(--mint-border, #e2e8f0);
+      background: linear-gradient(180deg, var(--primary-bg, #ecfdf5) 0%, #fff 100%);
+      border: 1px solid #d1fae5;
       border-radius: 8px;
     }
 
@@ -575,15 +579,19 @@ body {
         box-shadow 0.15s;
 
       &:hover:not(.is-active) {
-        color: var(--mint-text-muted, #334155);
-        background: rgba(255, 255, 255, 0.6);
+        color: #065f46;
       }
 
       &.is-active {
-        background: #fff;
-        color: var(--primary-dark, #059669);
-        box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08);
-        font-weight: 600;
+        background: var(--primary, #10b981);
+        color: #fff;
+        box-shadow: 0 1px 3px rgba(16, 185, 129, 0.28);
+        font-weight: 500;
+
+        &:hover {
+          color: #fff;
+          background: var(--primary, #10b981);
+        }
       }
     }
   }
@@ -618,6 +626,199 @@ body {
   }
 }
 
+// 弹窗内 Sticky 胶囊 Tab(detail-tabs / detail-tab,与 panel-pill-tabs 视觉一致)
+.detail-tabs {
+  display: flex;
+  gap: 4px;
+  padding: 4px;
+  background: linear-gradient(180deg, var(--primary-bg, #ecfdf5) 0%, #fff 100%);
+  border: 1px solid #d1fae5;
+  border-radius: 8px;
+  width: fit-content;
+  box-shadow: none;
+}
+
+.dialog-form-body > .detail-tabs,
+.protocol-view-body > .detail-tabs,
+.application-detail-body > .detail-tabs,
+.donation-view-body > .detail-tabs,
+.channel-view-body > .detail-tabs,
+.channel-dialog-body > .detail-tabs,
+.dialog-scroll > .detail-tabs {
+  position: sticky;
+  top: 0;
+  z-index: 1000;
+  margin: 0 28px 16px;
+  isolation: isolate;
+}
+
+.detail-tab {
+  padding: 10px 20px;
+  cursor: pointer;
+  border-radius: 6px;
+  font-size: 14px;
+  color: #606266;
+  transition:
+    background 0.15s,
+    color 0.15s,
+    box-shadow 0.15s;
+
+  &.active {
+    background: var(--primary, #10b981);
+    color: #fff;
+    font-weight: 500;
+    box-shadow: 0 1px 3px rgba(16, 185, 129, 0.28);
+  }
+
+  &:hover:not(.active):not(.is-disabled) {
+    color: #065f46;
+  }
+
+  &.is-disabled {
+    cursor: default;
+    opacity: 0.65;
+    pointer-events: none;
+  }
+}
+
+// 面板级步骤胶囊 Tab(样本信息管理 / 采集协议单 / 中试·基础实验申请单等)
+.pill-tab-nav {
+  padding: 16px 20px 0;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.pill-tab-nav__rail {
+  display: flex;
+  align-items: center;
+  width: 70%;
+  max-width: 100%;
+  margin-inline: auto;
+  background: linear-gradient(180deg, var(--primary-bg, #ecfdf5) 0%, #fff 100%);
+  border: 1px solid #d1fae5;
+  border-radius: 10px;
+  padding: 6px;
+  position: relative;
+  overflow: hidden;
+  box-shadow: 0 1px 2px rgb(15 23 42 / 4%);
+}
+
+.pill-tab-nav__progress {
+  position: absolute;
+  top: 6px;
+  bottom: 6px;
+  left: 6px;
+  background: var(--primary, #10b981);
+  border: 1px solid var(--primary-dark, #059669);
+  border-radius: 8px;
+  box-shadow: 0 1px 3px rgb(16 185 129 / 24%);
+  transition:
+    transform 0.25s ease,
+    width 0.25s ease;
+  z-index: 0;
+}
+
+.pill-tab-nav__step {
+  flex: 1;
+  position: relative;
+  z-index: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 8px;
+  min-width: 0;
+  min-height: 44px;
+  padding: 8px 10px;
+  border: none;
+  background: transparent;
+  cursor: pointer;
+  border-radius: 8px;
+  transition: color 0.2s ease;
+}
+
+.pill-tab-nav__index {
+  width: 22px;
+  height: 22px;
+  border-radius: 50%;
+  background: #e2e8f0;
+  color: var(--mint-text-muted, #334155);
+  font-size: 11px;
+  font-weight: 700;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-shrink: 0;
+  transition: all 0.2s ease;
+}
+
+.pill-tab-nav__text {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-start;
+  min-width: 0;
+  text-align: left;
+}
+
+.pill-tab-nav__title {
+  font-size: 13px;
+  font-weight: 600;
+  color: var(--mint-text-muted, #64748b);
+  white-space: nowrap;
+}
+
+.pill-tab-nav__desc {
+  font-size: 11px;
+  color: var(--mint-text-muted, #334155);
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  max-width: 100%;
+}
+
+.pill-tab-nav__step.is-active .pill-tab-nav__index {
+  background: #fff;
+  color: var(--primary-dark, #059669);
+}
+
+.pill-tab-nav__step.is-active .pill-tab-nav__title,
+.pill-tab-nav__step.is-active .pill-tab-nav__desc {
+  color: #fff;
+}
+
+.pill-tab-nav__step.is-done .pill-tab-nav__index {
+  background: var(--primary-bg, #ecfdf5);
+  color: var(--primary-dark, #059669);
+  border: 1px solid var(--mint-border, #c5e0d4);
+}
+
+.pill-tab-nav__step.is-done .pill-tab-nav__title {
+  color: var(--text, #1e293b);
+}
+
+@media (width <= 960px) {
+  .pill-tab-nav__desc {
+    display: none;
+  }
+
+  .pill-tab-nav__text {
+    align-items: center;
+  }
+}
+
+@media (width <= 720px) {
+  .pill-tab-nav {
+    overflow-x: auto;
+    -webkit-overflow-scrolling: touch;
+    align-items: stretch;
+  }
+
+  .pill-tab-nav__rail {
+    width: 100%;
+    min-width: 680px;
+  }
+}
+
 // 面板级左对齐下划线 Tab(对齐 docs/my-material-usage-tab-demos/04-left-underline)
 .panel-underline-tabs {
   &:not(.el-tabs) {

+ 9 - 2
web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue

@@ -9,7 +9,14 @@
 
       <div class="outbound-chain-section">
         <div class="section-subtitle">出库质检工单 + 任务</div>
-        <SampleQcInfoCards :qc-info="detail?.qcInfo" hide-sample-context />
+        <SampleQcInfoGroupedPanel
+          :gate-qc-info="detail?.qcInfo"
+          :process-qc-info-list="detail?.processQcInfoList"
+          gate-section-label="计划质检(出库门禁)"
+          process-section-label="生产过程质检"
+          :show-section-label="false"
+          hide-sample-context
+        />
       </div>
 
       <div class="outbound-chain-section">
@@ -316,7 +323,7 @@
   import { ref, computed, watch } from 'vue'
   import { Document, Download, View, VideoPlay } from '@element-plus/icons-vue'
   import SampleProductionInfoCards from '@/components/business/sample-production-info-cards/index.vue'
-  import SampleQcInfoCards from '@/components/business/sample-qc-info-cards/index.vue'
+  import SampleQcInfoGroupedPanel from '@/components/business/sample-qc-info-grouped-panel/index.vue'
   import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
   import { fetchInfusionScheduleMgmtDetail } from '@/api/admin'
   import {

+ 9 - 6
web-admin/src/components/business/outbound-material-form-sections/index.vue

@@ -141,7 +141,7 @@
             </template>
           </el-table-column>
         </el-table>
-        <p v-else class="section-empty-hint">点击「添加物料」从质检物料库勾选并填写计划用量</p>
+        <p v-else class="section-empty-hint">点击「添加物料」从市场物料库勾选并填写计划用量</p>
       </section>
 
       <!-- 纸质材料 -->
@@ -406,7 +406,7 @@
   } from '@element-plus/icons-vue'
   import { fetchUploadAttachment } from '@/api/business'
   import { fetchCellProductList } from '@/api/cell-product'
-  import { fetchQcMaterialList, type QcMaterialOption } from '@/api/qc-material'
+  import { fetchMaterialList, type MaterialOption } from '@/api/material'
   import type { OutboundReleaseCellRow } from '@/api/outbound-release-review'
   import { downloadAttachmentFile } from '@/utils/download-attachment'
   import { cellProductStatusLabel, cellProductStatusTagType } from '@/utils/status-tag-registry'
@@ -461,7 +461,7 @@
   const cellRows = ref<OutboundReleaseCellRow[]>([])
   const materialRows = ref<MaterialRow[]>([])
   const paperRows = ref<PaperRow[]>([])
-  const materialOptions = ref<QcMaterialOption[]>([])
+  const materialOptions = ref<MaterialOption[]>([])
   const materialOptionsLoading = ref(false)
 
   const cellSelectVisible = ref(false)
@@ -516,12 +516,13 @@
     )
   }
 
-  function mapMaterialListToOptions(list: Array<Record<string, any>>): QcMaterialOption[] {
+  function mapMaterialListToOptions(list: Array<Record<string, any>>): MaterialOption[] {
     return (list || []).map((m) => ({
       id: String(m.id || ''),
       label: `${m.materialName || ''}${m.materialCode ? ` (${m.materialCode})` : ''}`.trim(),
       materialCode: String(m.materialCode || ''),
       materialName: String(m.materialName || ''),
+      category: String(m.category || ''),
       specModel: String(m.specModel || ''),
       unit: String(m.unit || ''),
       stockQty: Number(m.stockQty ?? 0)
@@ -538,6 +539,7 @@
         label: row.materialName || id,
         materialCode: '',
         materialName: row.materialName || '',
+        category: '',
         specModel: row.specModel || '',
         unit: row.unit || '',
         stockQty: 0
@@ -549,10 +551,11 @@
   async function remoteSearchMaterials(query: string) {
     materialOptionsLoading.value = true
     try {
-      const res = await fetchQcMaterialList({
+      const res = await fetchMaterialList({
         page: 1,
         pageSize: 100,
-        keyword: query?.trim() || undefined
+        keyword: query?.trim() || undefined,
+        status: '1'
       })
       materialOptions.value = mapMaterialListToOptions(res.list || [])
       ensureMaterialsInOptions(materialRows.value)

+ 1 - 0
web-admin/src/components/business/sample-qc-info-cards/index.vue

@@ -175,6 +175,7 @@
   const emptyHint = computed(() => {
     const rec = props.sampleReception
     if (!rec) {
+      if (props.hideSampleContext) return '暂无质检工单'
       return '暂未接收样本,接收结论为「接收」后将自动生成质检工单'
     }
     if (rec.acceptConclusion === 'bj') {

+ 44 - 40
web-admin/src/components/business/sample-qc-info-grouped-panel/index.vue

@@ -6,46 +6,46 @@
   >
     <div v-if="showSectionLabel" class="sample-card__section-label">质检信息</div>
     <div class="sample-qc-grouped-panel">
-    <section class="sample-qc-grouped-panel__block">
-      <h4 class="sample-qc-grouped-panel__subtitle">样本接收质检(入库门禁)</h4>
-      <SampleQcInfoCards
-        embedded
-        :qc-info="gateQcInfo"
-        :sample-reception="sampleReception"
-        :hide-sample-context="hideSampleContext"
-      />
-    </section>
-
-    <section class="sample-qc-grouped-panel__block">
-      <h4 class="sample-qc-grouped-panel__subtitle">生产过程质检</h4>
-
-      <div v-if="!processQcInfoList?.length" class="sample-qc-grouped-panel__empty">
-        暂无生产过程质检工单
-      </div>
-
-      <div v-else class="sample-qc-grouped-panel__process-list">
-        <article
-          v-for="(item, idx) in processQcInfoList"
-          :key="item.workOrderNo || String(idx)"
-          class="sample-qc-grouped-panel__process-item"
-        >
-          <div class="process-qc-meta">
-            <el-tag type="success" size="small" class="process-qc-meta__tag">生产过程</el-tag>
-            <div class="qc-kv">
-              <span class="qc-kv__label">质检对象</span>
-              <span class="qc-kv__value">{{ formatQcTarget(item) }}</span>
+      <section class="sample-qc-grouped-panel__block">
+        <h4 class="sample-qc-grouped-panel__subtitle">{{ gateSectionLabel }}</h4>
+        <SampleQcInfoCards
+          embedded
+          :qc-info="gateQcInfo"
+          :sample-reception="sampleReception"
+          :hide-sample-context="hideSampleContext"
+        />
+      </section>
+
+      <section class="sample-qc-grouped-panel__block">
+        <h4 class="sample-qc-grouped-panel__subtitle">{{ processSectionLabel }}</h4>
+
+        <div v-if="!processQcInfoList?.length" class="sample-qc-grouped-panel__empty">
+          暂无生产过程质检工单
+        </div>
+
+        <div v-else class="sample-qc-grouped-panel__process-list">
+          <article
+            v-for="(item, idx) in processQcInfoList"
+            :key="item.workOrderNo || String(idx)"
+            class="sample-qc-grouped-panel__process-item"
+          >
+            <div class="process-qc-meta">
+              <el-tag type="success" size="small" class="process-qc-meta__tag">生产过程</el-tag>
+              <div class="qc-kv">
+                <span class="qc-kv__label">质检对象</span>
+                <span class="qc-kv__value">{{ formatQcTarget(item) }}</span>
+              </div>
+              <div v-if="item.productionWorkOrderNo" class="qc-kv">
+                <span class="qc-kv__label">生产工单</span>
+                <span class="qc-kv__value qc-kv__value--code">{{
+                  item.productionWorkOrderNo
+                }}</span>
+              </div>
             </div>
-            <div v-if="item.productionWorkOrderNo" class="qc-kv">
-              <span class="qc-kv__label">生产工单</span>
-              <span class="qc-kv__value qc-kv__value--code">{{
-                item.productionWorkOrderNo
-              }}</span>
-            </div>
-          </div>
-          <SampleQcInfoCards embedded :qc-info="item" :hide-sample-context="hideSampleContext" />
-        </article>
-      </div>
-    </section>
+            <SampleQcInfoCards embedded :qc-info="item" :hide-sample-context="hideSampleContext" />
+          </article>
+        </div>
+      </section>
     </div>
   </div>
 </template>
@@ -66,10 +66,14 @@
       hideSampleContext?: boolean
       /** 协议/捐赠样本卡内展示外层「质检信息」标题 */
       showSectionLabel?: boolean
+      gateSectionLabel?: string
+      processSectionLabel?: string
     }>(),
     {
       processQcInfoList: () => [],
-      showSectionLabel: true
+      showSectionLabel: true,
+      gateSectionLabel: '样本接收质检(入库门禁)',
+      processSectionLabel: '生产过程质检'
     }
   )
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/00d400955a62e83d40a52b3cd9debde813d8139e4c7347f78d56529ea8577b28.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/041e5b6eea36082aef31b456e3f3452fda034a13e1e3a362f9652a9ac5d2fb97.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_audit_storageentryinfotab_vue", "label": "StorageEntryInfoTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/StorageEntryInfoTab.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/06c0b5b8453611137332aab18062a5261b21c0f069f35171b49a2ad7911368ed.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/09be959089c5a1259c6797fdec2718d20a026361b0875c1292e6810f1220d48e.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/130e78d331d0fc642283c4aa2647e5b634cea40f98d7d6ded3b465c8a7434ebb.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_audit_storagecerttab_vue", "label": "StorageCertTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/StorageCertTab.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/173a225e66c378635376adce467f56ff95d39dd799d2e320f0b4ea5f711513d1.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_audit_samplereceptioninfotab_vue", "label": "SampleReceptionInfoTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/SampleReceptionInfoTab.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/18a594816c6e89957a83f856c71e9a6d14b92226a6d16def761c1e14d4423e45.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/1c56b81482396e3aceb3051dba7cec42f6ee5c1eff159e590a3bebdf60816c57.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_operations_exhibition_appointment_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/operations/exhibition-appointment/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/1cb4b69d3ca69cee91a2758dd505cad427618c6752545bdadd8ebedcf5022e72.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/1fa3950e774787977360e3d61c0b2fcf1612c95a4f146198ca66e9858e7d9fdc.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/2ba83168b702d44f8d92439a4b9ecc150d16cee01103fa07674d8918db01a63c.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_sample_info_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-info/index.vue", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_sample_info_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_audit_samplereceptioninfotab_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-info/index.vue", "source_location": "L40", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_sample_info_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_audit_sampleqcinfotab_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-info/index.vue", "source_location": "L41", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_sample_info_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_audit_storageentryinfotab_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-info/index.vue", "source_location": "L42", "weight": 1.0}], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/2c6f5f15436cf42ed22dea3ec6946f85a5b8c06f0ada2aa06fcdf5187bdbe513.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/30bcc0a66a8c7357652ca6d70c7407f425d1c54201aad8a56fa310c8ce9e4c15.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/30c59d440a6872e8166410b047a919e4fa8d4f1ea80c45a3e96437a943cacf56.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/33b08f1faecf3140a52477d55f835f889ee0f704558388a8b68caf26bece603d.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/3770b8f2348484a7a9940b567e5b2089008625ea1936ae0f2e5586bf283e028f.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/384ce5249283a3d2a46158a4ac6df87f1c522cac7cb180b379cb37d78975e031.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/396ddb8c02c71a1e2e2fa357a3c7f6c1a7b3fbb8d65698561aca8c75705dbbd7.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/3af1c66117392690e36e73263684a59248ff2c759fe4d14178059f196d55f697.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_channelserviceordertab_vue", "label": "ChannelServiceOrderTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelServiceOrderTab.vue", "source_location": "L1"}, {"id": "channel_channelserviceordertab_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelServiceOrderTab.vue", "source_location": "L1329"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_channelserviceordertab_vue", "target": "channel_channelserviceordertab_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelServiceOrderTab.vue", "source_location": "L1329", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_channelserviceordertab_vue", "target": "channel_channelserviceordertab_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelServiceOrderTab.vue", "source_location": "L1609", "weight": 1.0}], "raw_calls": [{"caller_nid": "channel_channelserviceordertab_if", "callee": "handleChannelSearch", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelServiceOrderTab.vue", "source_location": "L1330"}, {"caller_nid": "channel_channelserviceordertab_if", "callee": "error", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelServiceOrderTab.vue", "source_location": "L1610"}]}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/3e738b9cfef74ba6e8e5e89727ec771e3e24f4632cbb8121ef67a822833ed7ee.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_qc_info_grouped_panel_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-grouped-panel/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/45771d50ec2df425a694aefb97bb9b823c6228a84ac2ff6d4e411214c3e12cb9.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/494cfd6995ffa31172179478f2729f4e43f00bf353bb16861b3aed6d4c7e0d27.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleasematerialdialog_vue", "label": "OutboundReleaseMaterialDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseMaterialDialog.vue", "source_location": "L1"}, {"id": "outbound_release_review_outboundreleasematerialdialog_return", "label": "return()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseMaterialDialog.vue", "source_location": "L777"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleasematerialdialog_vue", "target": "outbound_release_review_outboundreleasematerialdialog_return", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseMaterialDialog.vue", "source_location": "L777", "weight": 1.0}], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/4b4ad7c6acb524b90d1324a2580788f8553ff9ba83e8fed8d69d96bba8a75053.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_outbound_release_review_outboundreleaseviewdialog_vue", "label": "OutboundReleaseViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/outbound-release-review/OutboundReleaseViewDialog.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/5280ad16c1dd0eb472561a1a28b5dde65ae625c2fce95d7556bafa7530a25828.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_outbound_material_form_sections_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-form-sections/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/53330f8f92ac42a69f7308ff6942dff5084d51752257fc7d034d8fedd62449a9.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_payment_confirm_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-confirm/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/55c124b3e54db58de69afef1ddd1dad032fe00c409d77c731569a7c71bf6d7ff.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/61fd1ff27201c7bea915f68110a35f17f7810ce84f9f82f4d17f6618ab09aa5d.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_sample_reception_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue", "source_location": "L1"}, {"id": "sample_reception_index_pad", "label": "pad()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue", "source_location": "L1023"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_sample_reception_index_vue", "target": "sample_reception_index_pad", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue", "source_location": "L1023", "weight": 1.0}], "raw_calls": [{"caller_nid": "sample_reception_index_pad", "callee": "padStart", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue", "source_location": "L1023"}, {"caller_nid": "sample_reception_index_pad", "callee": "String", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue", "source_location": "L1023"}]}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/64ab9f30e87b365813bd12bb63a951483e0fd8d26e7ae3092d8071fd7c704463.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/67f9f5f46d9c949db0435ea2455d18ea2f4894d396f664b421f928e85b04d193.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/6965fd9f880af2878674a155edc5d17fdd92fbbdb5eac4c114325364064632c4.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_infusion_schedule_outbound_chain_view_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/infusion-schedule-outbound-chain-view/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/707f82b5aa5697b356a0c435cf3c919b0fba12a37373b8e7ef1f1c852f05bcdb.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_qcworkordersamplegroup_vue", "label": "QcWorkOrderSampleGroup.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSampleGroup.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/75944460e46ef27212fa7afccf5bc73d0b0fa502b0bbf9f3224c4022f968c2d6.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/75f0a0134f5772c1d32c5be1b194eb6003c7cd983f41b8680d973541dcc7ca0e.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/76e4eb9cfc7b336e6dac097aa3fe05932d1713d45ba86e3bcbd23ba1f6fc95b3.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/771e1acf4e2a7750272e7a350200d4d7ed2abcb86a091d6887665e59acb79722.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/7be99455eb3b3873d076644d5d3d5506bde7f9d8ae1940b636c85cb50b931573.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/7fef75f59527a909b8868a0d9c75209260f0c3c0fd647c5214056df6262589c4.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_applicationviewdialog_vue", "label": "ApplicationViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L1"}, {"id": "pilot_application_applicationviewdialog_for", "label": "for()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L1082"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_pilot_application_applicationviewdialog_vue", "target": "pilot_application_applicationviewdialog_for", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L1082", "weight": 1.0}], "raw_calls": [{"caller_nid": "pilot_application_applicationviewdialog_for", "callee": "trim", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L1083"}, {"caller_nid": "pilot_application_applicationviewdialog_for", "callee": "Number", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L1086"}, {"caller_nid": "pilot_application_applicationviewdialog_for", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L1087"}, {"caller_nid": "pilot_application_applicationviewdialog_for", "callee": "set", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationViewDialog.vue", "source_location": "L1089"}]}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/848b570bbd3a09b44fcb96a0863231b9076ac5e8edd3a09baf48f5c8228f27c2.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/8508cda6e23c47dce4251e3ca96eca4b237275eb47200c9049e1ca0cdb2012b9.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/86b9f8187b3798a28a113bd16483a4845a50710dede1c6e0d81b7f682e7f2b36.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/89110193ec193ba0e3f825809af8cf324185524922c92c3fca72598de9e9488f.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_payment_confirm_refundconfirmtab_vue", "label": "RefundConfirmTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-confirm/RefundConfirmTab.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/9ab8112557bb3323eef8ab53b7c35e9eb93610bb178714fc847b38ff11712472.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/9f0b9588a2eee159514775f95ddc891d2123dd716b883813749c0d36df6a0b25.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/a0c0afa7bb284d1939002cb55e870b3a82fa267a23b24f21a1008a41db2bb748.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_sample_info_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-info/index.vue", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_sample_info_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_audit_samplereceptioninfotab_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-info/index.vue", "source_location": "L40", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_sample_info_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_audit_sampleqcinfotab_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-info/index.vue", "source_location": "L41", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_sample_info_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_audit_storageentryinfotab_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-info/index.vue", "source_location": "L42", "weight": 1.0}], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/a0f0c8011045baf2401c8a75226f844c95b8c7351a58a7c969646b15ca71201b.json

@@ -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": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/a1adcd2a84f506fbf814c728bf05ed7f7ad497f5b2c4023f02cf0ef3c1a21c05.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/a4825f88608a4281634df573f530a899d42ee189037b2ab2bc7aaa2983083942.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/a948a5a61d367bf15f86067a4b0ed26279513e89af19c61c095440719fc39414.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/a9bc9afa400193997fd49f72eefd3d0aa24360385bf4b7d4b2c1e8c096e44121.json

@@ -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": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/ac17fe7b02f680fc1127c51c132b637fd51ab00a5286c7704fe4a4b7bf2c01db.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/b7e1c76a9591a8c32f983074c63cba294e198c3f1337f96afd58bec9a89729d5.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_audit_sampleqcinfotab_vue", "label": "SampleQcInfoTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/SampleQcInfoTab.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/b88baee832990513f2f36b79c8aced0fff2f91e2b712bc2b01f0fa07d62b3fd0.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_audit_protocolaudittab_vue", "label": "ProtocolAuditTab.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/ProtocolAuditTab.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/ba341174c25128f0e296962de19aea41e23e50ea212500f05a6648a2bac8ba1c.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_audit_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/audit/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/bacf2089fe890969d977c2733641e6779966638f2b0f4491b5210d679cf86016.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/c1011a236780c8788382cdd431c174659d2912c0764c57a644ea4de9c21aa10c.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
web-admin/src/graphify-out/cache/ast/c9c3998fc006ef16fdd6a476202e3779b3aac1b868d6e3e70bb7bbd6d0cf0c6e.json


+ 1 - 0
web-admin/src/graphify-out/cache/ast/c9fe7190a53ace0c56c079d77509c57fd1e7f978957de3a6c9f75400448aa2dd.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_system_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/order/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/cb66f03371e5c5b4eb2d48298236196567c2c96c7a8fbf9db05a96baa56ba69d.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}

+ 1 - 0
web-admin/src/graphify-out/cache/ast/d0278637a57cacbe1934040a5176515e10207a6dec4d33a8f895d1e879291043.json

@@ -0,0 +1 @@
+{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác