提交
This commit is contained in:
1 parent
0e60b88cba
commit
87f7f6bf38
34 files changed
+18326
-6165
No files matched your search
+1
-1
@@ -1 +1 @@
|
||||
24017
|
||||
92494
|
||||
@@ -225,6 +225,7 @@ def list_plans(
|
||||
transport_status: Optional[str] = Query(default=None, alias="transportStatus", description="运输状态"),
|
||||
archive_status: Optional[str] = Query(default=None, alias="archiveStatus", description="归档状态"),
|
||||
customer_name: Optional[str] = Query(default=None, alias="customerName", description="客户名称"),
|
||||
product_name: Optional[str] = Query(default=None, alias="productName", description="产品名称"),
|
||||
plan_date_from: Optional[date] = Query(default=None, alias="planDateFrom", description="计划日期开始"),
|
||||
plan_date_to: Optional[date] = Query(default=None, alias="planDateTo", description="计划日期结束"),
|
||||
page: int = Query(default=1, ge=1),
|
||||
@@ -264,6 +265,20 @@ def list_plans(
|
||||
if customer_name:
|
||||
query = query.filter(func.lower(PlPlan.customer_name).contains(customer_name.lower()))
|
||||
|
||||
if product_name:
|
||||
product_name_kw = product_name.strip()
|
||||
if product_name_kw:
|
||||
query = query.filter(
|
||||
db.query(PlPlanProduct.id)
|
||||
.filter(
|
||||
PlPlanProduct.plan_id == PlPlan.id,
|
||||
PlPlanProduct.tenant_no == tenant_no,
|
||||
PlPlanProduct.del_flag == 0,
|
||||
func.lower(PlPlanProduct.product_name).contains(product_name_kw.lower()),
|
||||
)
|
||||
.exists()
|
||||
)
|
||||
|
||||
if plan_date_from:
|
||||
query = query.filter(PlPlan.plan_date >= plan_date_from)
|
||||
|
||||
|
||||
@@ -19,8 +19,14 @@ SELF_TRAILER_REQUIRED = ("行驶证", "营运证", "保险单", "罐检报告")
|
||||
CARRIER_HEAD_REQUIRED = ("行驶证", "营运证")
|
||||
CARRIER_TRAILER_REQUIRED = ("行驶证", "营运证")
|
||||
|
||||
PERSONNEL_DRIVER_REQUIRED = ("身份证", "驾驶证", "从业资格证")
|
||||
PERSONNEL_ESCORT_REQUIRED = ("身份证", "从业资格证")
|
||||
PERSONNEL_DRIVER_REQUIRED = ("身份证", "驾驶证", "驾驶员从业资格证")
|
||||
PERSONNEL_ESCORT_REQUIRED = ("身份证", "押运员从业资格证")
|
||||
PERSONNEL_BOTH_REQUIRED = (
|
||||
"身份证",
|
||||
"驾驶证",
|
||||
"驾驶员从业资格证",
|
||||
"押运员从业资格证",
|
||||
)
|
||||
|
||||
VEHICLE_PART_HEAD = "head"
|
||||
VEHICLE_PART_TRAILER = "trailer"
|
||||
@@ -30,31 +36,23 @@ def match_required_cert_name(actual_name: str | None, required_name: str) -> boo
|
||||
name = (actual_name or "").strip()
|
||||
if not name:
|
||||
return False
|
||||
if required_name == "从业资格证":
|
||||
return (
|
||||
name == "从业资格证"
|
||||
or name == "危化品从业资格证"
|
||||
or "从业资格证" in name
|
||||
)
|
||||
if required_name == "押运员从业资格证":
|
||||
return name == "押运员从业资格证" or name == "押运员证"
|
||||
return name == required_name
|
||||
|
||||
|
||||
def _cert_row_complete(cert: CertRow | dict, required_name: str) -> bool:
|
||||
if isinstance(cert, dict):
|
||||
cert_name = cert.get("cert_name") or cert.get("certName")
|
||||
cert_no = cert.get("cert_no") or cert.get("certNo")
|
||||
expire_date = cert.get("expire_date") or cert.get("expireDate")
|
||||
attachment_urls = cert.get("attachment_urls") or cert.get("attachmentUrls")
|
||||
else:
|
||||
cert_name = cert.cert_name
|
||||
cert_no = cert.cert_no
|
||||
expire_date = cert.expire_date
|
||||
attachment_urls = cert.attachment_urls
|
||||
|
||||
if not match_required_cert_name(cert_name, required_name):
|
||||
return False
|
||||
if not (cert_no or "").strip():
|
||||
return False
|
||||
if not expire_date:
|
||||
return False
|
||||
if not (attachment_urls or "").strip():
|
||||
@@ -84,23 +82,19 @@ def _find_cert_for_required(
|
||||
|
||||
def _missing_field_labels(cert: CertRow | dict | None, required_name: str) -> list[str]:
|
||||
if cert is None:
|
||||
return ["证号", "有效期", "附件"]
|
||||
return ["有效期", "附件"]
|
||||
missing: list[str] = []
|
||||
if isinstance(cert, dict):
|
||||
cert_no = cert.get("cert_no") or cert.get("certNo")
|
||||
expire_date = cert.get("expire_date") or cert.get("expireDate")
|
||||
attachment_urls = cert.get("attachment_urls") or cert.get("attachmentUrls")
|
||||
cert_name = cert.get("cert_name") or cert.get("certName")
|
||||
else:
|
||||
cert_no = cert.cert_no
|
||||
expire_date = cert.expire_date
|
||||
attachment_urls = cert.attachment_urls
|
||||
cert_name = cert.cert_name
|
||||
|
||||
if not match_required_cert_name(cert_name, required_name):
|
||||
return ["证号", "有效期", "附件"]
|
||||
if not (cert_no or "").strip():
|
||||
missing.append("证号")
|
||||
return ["有效期", "附件"]
|
||||
if not expire_date:
|
||||
missing.append("有效期")
|
||||
if not (attachment_urls or "").strip():
|
||||
@@ -137,9 +131,11 @@ def get_required_personnel_cert_names(personnel_type: str | None) -> tuple[str,
|
||||
ptype = (personnel_type or "").strip()
|
||||
if ptype == "escort":
|
||||
return PERSONNEL_ESCORT_REQUIRED
|
||||
if ptype in ("driver", "both"):
|
||||
if ptype == "driver":
|
||||
return PERSONNEL_DRIVER_REQUIRED
|
||||
return PERSONNEL_DRIVER_REQUIRED
|
||||
if ptype == "both":
|
||||
return PERSONNEL_BOTH_REQUIRED
|
||||
return PERSONNEL_BOTH_REQUIRED
|
||||
|
||||
|
||||
def validate_personnel_type_role_compat(personnel_type: str | None, role: str | None) -> None:
|
||||
|
||||
@@ -153,31 +153,11 @@
|
||||
"151": "Community 151",
|
||||
"152": "Community 152",
|
||||
"153": "Community 153",
|
||||
"154": "Community 154",
|
||||
"155": "Community 155",
|
||||
"156": "Community 156",
|
||||
"157": "Community 157",
|
||||
"158": "Community 158",
|
||||
"159": "Community 159",
|
||||
"160": "Community 160",
|
||||
"161": "Community 161",
|
||||
"162": "Community 162",
|
||||
"163": "Community 163",
|
||||
"164": "Community 164",
|
||||
"165": "Community 165",
|
||||
"166": "Community 166",
|
||||
"167": "Community 167",
|
||||
"168": "Community 168",
|
||||
"169": "Community 169",
|
||||
"170": "Community 170",
|
||||
"171": "Community 171",
|
||||
"172": "Community 172",
|
||||
"173": "Community 173",
|
||||
"174": "Community 174",
|
||||
"175": "Community 175",
|
||||
"176": "Community 176",
|
||||
"177": "Community 177",
|
||||
"178": "Community 178",
|
||||
"179": "Community 179",
|
||||
"180": "Community 180"
|
||||
"176": "Community 176"
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
# Graph Report - backend (2026-07-13)
|
||||
|
||||
## Corpus Check
|
||||
- 261 files · ~186,595 words
|
||||
- 269 files · ~198,836 words
|
||||
- Verdict: corpus is large enough that graph structure adds value.
|
||||
|
||||
## Summary
|
||||
- 5750 nodes · 39893 edges · 181 communities (178 shown, 3 thin omitted)
|
||||
- Extraction: 52% EXTRACTED · 48% INFERRED · 0% AMBIGUOUS · INFERRED: 19089 edges (avg confidence: 0.5)
|
||||
- 5967 nodes · 40753 edges · 161 communities (159 shown, 2 thin omitted)
|
||||
- Extraction: 53% EXTRACTED · 47% INFERRED · 0% AMBIGUOUS · INFERRED: 19152 edges (avg confidence: 0.5)
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Graph Freshness
|
||||
- Built from commit: `3520f9ce`
|
||||
- Built from commit: `0e60b88c`
|
||||
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
||||
- Run `graphify update .` after code changes (no API cost).
|
||||
|
||||
@@ -159,33 +159,13 @@
|
||||
- [[_COMMUNITY_Community 151|Community 151]]
|
||||
- [[_COMMUNITY_Community 152|Community 152]]
|
||||
- [[_COMMUNITY_Community 153|Community 153]]
|
||||
- [[_COMMUNITY_Community 154|Community 154]]
|
||||
- [[_COMMUNITY_Community 155|Community 155]]
|
||||
- [[_COMMUNITY_Community 156|Community 156]]
|
||||
- [[_COMMUNITY_Community 157|Community 157]]
|
||||
- [[_COMMUNITY_Community 158|Community 158]]
|
||||
- [[_COMMUNITY_Community 159|Community 159]]
|
||||
- [[_COMMUNITY_Community 160|Community 160]]
|
||||
- [[_COMMUNITY_Community 161|Community 161]]
|
||||
- [[_COMMUNITY_Community 162|Community 162]]
|
||||
- [[_COMMUNITY_Community 163|Community 163]]
|
||||
- [[_COMMUNITY_Community 164|Community 164]]
|
||||
- [[_COMMUNITY_Community 165|Community 165]]
|
||||
- [[_COMMUNITY_Community 166|Community 166]]
|
||||
- [[_COMMUNITY_Community 167|Community 167]]
|
||||
- [[_COMMUNITY_Community 168|Community 168]]
|
||||
- [[_COMMUNITY_Community 169|Community 169]]
|
||||
- [[_COMMUNITY_Community 170|Community 170]]
|
||||
- [[_COMMUNITY_Community 171|Community 171]]
|
||||
- [[_COMMUNITY_Community 172|Community 172]]
|
||||
- [[_COMMUNITY_Community 173|Community 173]]
|
||||
- [[_COMMUNITY_Community 174|Community 174]]
|
||||
- [[_COMMUNITY_Community 175|Community 175]]
|
||||
- [[_COMMUNITY_Community 176|Community 176]]
|
||||
- [[_COMMUNITY_Community 177|Community 177]]
|
||||
- [[_COMMUNITY_Community 178|Community 178]]
|
||||
- [[_COMMUNITY_Community 179|Community 179]]
|
||||
- [[_COMMUNITY_Community 180|Community 180]]
|
||||
|
||||
## God Nodes (most connected - your core abstractions)
|
||||
1. `Session` - 1551 edges
|
||||
@@ -200,10 +180,10 @@
|
||||
10. `success_response()` - 260 edges
|
||||
|
||||
## Surprising Connections (you probably didn't know these)
|
||||
- `Namespace` --uses--> `Settings` [INFERRED]
|
||||
scripts/migrate_users.py → app/core/config.py
|
||||
- `BackfillRule` --uses--> `Settings` [INFERRED]
|
||||
scripts/migrate_crm_sys_oss.py → app/core/config.py
|
||||
- `int` --uses--> `Settings` [INFERRED]
|
||||
scripts/refresh_business_role_menus.py → app/core/config.py
|
||||
- `bool` --uses--> `DbUserContext` [INFERRED]
|
||||
scripts/migrate_dibang_data.py → app/core/db_auth.py
|
||||
- `date` --uses--> `DbUserContext` [INFERRED]
|
||||
@@ -211,71 +191,71 @@
|
||||
- `int` --uses--> `DbUserContext` [INFERRED]
|
||||
scripts/run_db_auto_generate_plans.py → app/core/db_auth.py
|
||||
|
||||
## Communities (181 total, 3 thin omitted)
|
||||
## Communities (161 total, 2 thin omitted)
|
||||
|
||||
### Community 0 - "Community 0"
|
||||
Cohesion: 0.35
|
||||
Nodes (220): Any, bool, str, UploadFile, CRM 线索管理 Pydantic Schemas, CRM 客户管理 Pydantic Schemas, CRM 商机管理 Pydantic Schemas, CRM 客户公海池规则 Pydantic Schemas (+212 more)
|
||||
Nodes (219): Any, bool, str, UploadFile, CRM 线索管理 Pydantic Schemas, CRM 客户管理 Pydantic Schemas, CRM 商机管理 Pydantic Schemas, CRM 客户公海池规则 Pydantic Schemas (+211 more)
|
||||
|
||||
### Community 1 - "Community 1"
|
||||
Cohesion: 0.08
|
||||
Nodes (29): BaseModel, AdvanceApplyOut, AdvanceApprovalCreate, AttachmentOut, _coerce_optional_id(), WorkflowDefCreate, WorkflowDefUpdate, WorkflowNodeCreate (+21 more)
|
||||
Cohesion: 0.15
|
||||
Nodes (21): Path, bytes, int, str, download_file_bytes(), file_stream(), get_access_url(), get_download_url() (+13 more)
|
||||
|
||||
### Community 2 - "Community 2"
|
||||
Cohesion: 0.07
|
||||
Nodes (169): _apply_default_invoice_info_to_customers(), category_add(), category_delete(), category_tree(), category_update(), clue_assign(), clue_check_convert(), clue_check_duplicate() (+161 more)
|
||||
|
||||
### Community 3 - "Community 3"
|
||||
Cohesion: 0.12
|
||||
Nodes (56): Any, Any, CRM 合同 CRUD — 对照 CrmContractServiceImpl.java(列表/详情 P1), Decimal, _apply_contract_entity_fields(), _apply_contract_scalar_fields(), _build_customer_address(), _calc_amount_with_tax() (+48 more)
|
||||
Cohesion: 0.08
|
||||
Nodes (24): PlInventoryWarning, 运费结算表 pl_freight_settlement, 结算单-运输关联表 pl_freight_settlement_transport, 汇款凭证表 pl_remittance_voucher, 库存预警表 pl_inventory_warning, 库存预警表 pl_inventory_warning, 汇款凭证表 pl_remittance_voucher, 库存预警表 pl_inventory_warning (+16 more)
|
||||
|
||||
### Community 4 - "Community 4"
|
||||
Cohesion: 0.21
|
||||
Nodes (31): apply_biz_backfill(), BackfillRule, BizRef, build_biz_index(), count_target_rows(), derive_source_url(), fetch_portal_admin_id(), fetch_source_rows() (+23 more)
|
||||
|
||||
### Community 5 - "Community 5"
|
||||
Cohesion: 0.09
|
||||
Nodes (28): 运输计划管理 - 基础数据 Schema(承运商、车辆、人员、证书), CarrierAuditReject, CarrierBase, CarrierCreate, CarrierListResponse, CarrierQualificationBase, CarrierRead, CarrierUpdate (+20 more)
|
||||
Cohesion: 0.21
|
||||
Nodes (20): DbUserContext, Session, str, Session, str, int, Session, str (+12 more)
|
||||
|
||||
### Community 6 - "Community 6"
|
||||
Cohesion: 0.03
|
||||
Nodes (134): Decimal, PlPlanProduct, Session, str, PlPlanChange, 计划变更记录表 pl_plan_change, 计划产品明细表 pl_plan_product, 计划变更记录表 pl_plan_change (+126 more)
|
||||
Cohesion: 0.05
|
||||
Nodes (138): bool, Decimal, int, PlanCreateFull, PlanSiteFeedbackUpdateBody, PlPlan, PlPlanProduct, PlTransport (+130 more)
|
||||
|
||||
### Community 7 - "Community 7"
|
||||
Cohesion: 0.04
|
||||
Nodes (48): PlInventoryTransaction, PlInventoryWarning, 计划-运输关联表 pl_plan_transport, 运费结算表 pl_freight_settlement, 库存流水表 pl_inventory_transaction, 运费结算表 pl_freight_settlement, 结算单-运输关联表 pl_freight_settlement_transport, 结算单-运输关联表 pl_freight_settlement_transport (+40 more)
|
||||
Cohesion: 0.21
|
||||
Nodes (39): clear_portal_workflow(), _dec(), derive_source_url(), fetch_portal_admin_id(), fetch_source_rows(), legacy_id_to_str(), load_bx_user_mapping(), load_runtime_settings() (+31 more)
|
||||
|
||||
### Community 8 - "Community 8"
|
||||
Cohesion: 0.07
|
||||
Nodes (124): DbUserContext, FreightSettlementDisburseBody, FreightSettlementSubmitApprovalBody, FreightSettlementUpdate, int, Session, str, datetime (+116 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (123): DbUserContext, FreightSettlementDisburseBody, FreightSettlementSubmitApprovalBody, FreightSettlementUpdate, int, Session, str, FreightSettlementDisburseBody (+115 more)
|
||||
|
||||
### Community 9 - "Community 9"
|
||||
Cohesion: 0.19
|
||||
Nodes (39): ProcessDefCreateBody, ProcessDefUpdateBody, PublishVersionBody, StartInstanceBody, Any, bool, WfProcessInstance, bool (+31 more)
|
||||
Cohesion: 0.08
|
||||
Nodes (83): approve_task(), _assert_wf_instance_in_scope(), _business_type_label(), create_process_def(), delete_process_def(), _enrich_task_list(), get_business_all_tasks(), _get_business_form_fields() (+75 more)
|
||||
|
||||
### Community 10 - "Community 10"
|
||||
Cohesion: 0.10
|
||||
Nodes (109): date, DbUserContext, int, Session, str, VehicleRechargeApplyCreate, VehicleRechargeApplyRead, VehicleRechargeApplyUpdate (+101 more)
|
||||
Nodes (107): date, DbUserContext, int, Session, str, VehicleRechargeApplyCreate, VehicleRechargeApplyRead, VehicleRechargeApplyUpdate (+99 more)
|
||||
|
||||
### Community 11 - "Community 11"
|
||||
Cohesion: 0.06
|
||||
Nodes (81): bool, DbUserContext, PlPlan, PlTransport, Session, str, Session, str (+73 more)
|
||||
Cohesion: 0.08
|
||||
Nodes (136): bool, PlCarrier, VehicleCreate, VehicleUpdate, bool, DbUserContext, float, int (+128 more)
|
||||
|
||||
### Community 12 - "Community 12"
|
||||
Cohesion: 0.22
|
||||
Nodes (32): _dec(), derive_source_url(), fetch_portal_admin_id(), fetch_source_rows(), legacy_id_to_str(), load_oss_id_to_url(), load_runtime_settings(), load_settings_env() (+24 more)
|
||||
|
||||
### Community 13 - "Community 13"
|
||||
Cohesion: 0.10
|
||||
Nodes (111): date, DbUserContext, int, Session, str, VehicleMaintenanceApplyCreate, VehicleMaintenanceApplyRead, VehicleMaintenanceApplyReminder (+103 more)
|
||||
Cohesion: 0.11
|
||||
Nodes (103): date, DbUserContext, int, Session, str, VehicleMaintenanceApplyCreate, VehicleMaintenanceApplyRead, VehicleMaintenanceApplyReminder (+95 more)
|
||||
|
||||
### Community 14 - "Community 14"
|
||||
Cohesion: 0.06
|
||||
Nodes (89): Any, bool, Decimal, Session, str, _advance_after_approval(), _approval_to_dict(), can_user_approve_settlement() (+81 more)
|
||||
Nodes (92): Any, bool, datetime, Decimal, PlTransport, Session, str, PlFreightSettlement (+84 more)
|
||||
|
||||
### Community 15 - "Community 15"
|
||||
Cohesion: 0.13
|
||||
Nodes (56): Any, int, Session, str, Any, bool, CRM 客户 CRUD(客户主表 + 转移/成交/公海池操作), CrmCustomer (+48 more)
|
||||
Nodes (57): Any, int, Session, str, Any, bool, CRM 客户 CRUD(客户主表 + 转移/成交/公海池操作), CrmCustomer (+49 more)
|
||||
|
||||
### Community 16 - "Community 16"
|
||||
Cohesion: 0.16
|
||||
@@ -286,160 +266,160 @@ Cohesion: 0.19
|
||||
Nodes (20): int, str, Any, bool, int, Session, str, business_type_from_path() (+12 more)
|
||||
|
||||
### Community 18 - "Community 18"
|
||||
Cohesion: 0.07
|
||||
Nodes (100): attachment_download_url(), attachment_preview_url(), AttachmentDownloadUrlBody, create_dept(), create_dict_data(), create_dict_type(), create_menu(), create_post() (+92 more)
|
||||
Cohesion: 0.08
|
||||
Nodes (96): attachment_download_url(), attachment_preview_url(), AttachmentDownloadUrlBody, create_dept(), create_dict_data(), create_dict_type(), create_menu(), create_post() (+88 more)
|
||||
|
||||
### Community 19 - "Community 19"
|
||||
Cohesion: 0.15
|
||||
Nodes (35): Any, bool, BxUserContext, BxWorkflowNode, float, int, ReimburseApplyOut, Session (+27 more)
|
||||
Nodes (34): Any, bool, BxUserContext, BxWorkflowNode, float, int, ReimburseApplyOut, Session (+26 more)
|
||||
|
||||
### Community 20 - "Community 20"
|
||||
Cohesion: 0.24
|
||||
Nodes (82): date, DbUserContext, int, Session, str, float, int, ApprovalRecordRead (+74 more)
|
||||
Nodes (72): date, DbUserContext, int, Session, str, DocumentReminderRead, DocumentReminderUpdate, InventoryLedgerResponse (+64 more)
|
||||
|
||||
### Community 21 - "Community 21"
|
||||
Cohesion: 0.20
|
||||
Nodes (46): BxUserContext, int, Session, str, BxUserContext, int, Session, str (+38 more)
|
||||
Cohesion: 0.35
|
||||
Nodes (30): BxUserContext, int, Session, str, ApiResponse, approve_reimburse(), approved_by_me(), _build_details_data() (+22 more)
|
||||
|
||||
### Community 22 - "Community 22"
|
||||
Cohesion: 0.07
|
||||
Nodes (41): AttachmentUploadResponse, ChangePasswordRequest, Config, LoginRequest, LoginResponse, Pydantic schemas - 用户认证, ResetPasswordRequest, UserCreate (+33 more)
|
||||
Nodes (43): AttachmentUploadResponse, ChangePasswordRequest, Config, LoginRequest, LoginResponse, Pydantic schemas - 用户认证, ResetPasswordRequest, UserCreate (+35 more)
|
||||
|
||||
### Community 23 - "Community 23"
|
||||
Cohesion: 0.09
|
||||
Nodes (57): Any, bool, CrmContract, datetime, int, Query, Session, str (+49 more)
|
||||
Nodes (58): Any, bool, CrmContract, datetime, int, Query, Session, str (+50 more)
|
||||
|
||||
### Community 24 - "Community 24"
|
||||
Cohesion: 0.11
|
||||
Nodes (58): Any, bool, int, Session, str, Any, bool, CRM 线索 CRUD(线索主表 + 转化/分配/无效/等级操作) (+50 more)
|
||||
Nodes (57): Any, bool, int, Session, str, Any, bool, CRM 线索 CRUD(线索主表 + 转化/分配/无效/等级操作) (+49 more)
|
||||
|
||||
### Community 25 - "Community 25"
|
||||
Cohesion: 0.09
|
||||
Nodes (46): bool, Session, str, Any, int, Session, str, _append_user_scope_conditions() (+38 more)
|
||||
Nodes (42): bool, Session, str, Any, int, Session, str, _append_user_scope_conditions() (+34 more)
|
||||
|
||||
### Community 26 - "Community 26"
|
||||
Cohesion: 0.10
|
||||
Nodes (57): bool, date, DbInboundOutbound, DbPurchasePlan, float, PlPlan, PlPlanProduct, PlTransport (+49 more)
|
||||
Nodes (58): bool, date, datetime, DbInboundOutbound, DbPurchasePlan, float, PlPlan, PlPlanProduct (+50 more)
|
||||
|
||||
### Community 27 - "Community 27"
|
||||
Cohesion: 0.08
|
||||
Nodes (42): Exception, bool, bytes, int, Path, str, bytes, int (+34 more)
|
||||
Cohesion: 0.09
|
||||
Nodes (21): Exception, bool, bytes, int, str, bytes, BytesIO, BaseStorage (+13 more)
|
||||
|
||||
### Community 28 - "Community 28"
|
||||
Cohesion: 0.08
|
||||
Nodes (181): date, DbUserContext, int, PlanCreateFull, PlanDriverFeedbackUpdateBody, PlanSiteFeedbackUpdateBody, PlPlan, Session (+173 more)
|
||||
Cohesion: 0.19
|
||||
Nodes (81): date, DbUserContext, int, PlanCreateFull, PlanDriverFeedbackUpdateBody, PlanSiteFeedbackUpdateBody, PlPlan, Session (+73 more)
|
||||
|
||||
### Community 29 - "Community 29"
|
||||
Cohesion: 0.11
|
||||
Nodes (38): Any, CRM 报价单 CRUD — 对照 CrmQuoteServiceImpl.java(P2 全量), datetime, Decimal, Query, _build_quote_filters(), calculate_quote_amount(), create_quote() (+30 more)
|
||||
Cohesion: 0.03
|
||||
Nodes (148): register_quote_routes(), Any, bool, CRM 报价单 CRUD — 对照 CrmQuoteServiceImpl.java(P2 全量), date, datetime, Decimal, int (+140 more)
|
||||
|
||||
### Community 30 - "Community 30"
|
||||
Cohesion: 0.18
|
||||
Nodes (50): Any, CRM 商机 CRUD(主表 + 阶段/赢输单/统计/看板/漏斗), CrmOpportunity, date, datetime, Decimal, int, Session (+42 more)
|
||||
Nodes (49): Any, CRM 商机 CRUD(主表 + 阶段/赢输单/统计/看板/漏斗), CrmOpportunity, date, datetime, Decimal, int, Session (+41 more)
|
||||
|
||||
### Community 31 - "Community 31"
|
||||
Cohesion: 0.13
|
||||
Nodes (30): Any, bool, CRM 供方信息 CRUD — 对照 CrmSupplierInfoServiceImpl.java, int, Session, str, _apply_list_filters(), create_supplier_info() (+22 more)
|
||||
Cohesion: 0.22
|
||||
Nodes (35): _dec(), derive_source_url(), fetch_portal_admin_id(), fetch_source_rows(), legacy_id_to_str(), load_oss_id_to_url(), load_runtime_settings(), load_settings_env() (+27 more)
|
||||
|
||||
### Community 32 - "Community 32"
|
||||
Cohesion: 0.14
|
||||
Nodes (40): Any, bool, int, Session, str, SysUser, change_password(), create_user() (+32 more)
|
||||
Cohesion: 0.11
|
||||
Nodes (45): bool, str, Any, bool, int, Session, str, SysUser (+37 more)
|
||||
|
||||
### Community 33 - "Community 33"
|
||||
Cohesion: 0.10
|
||||
Nodes (21): _generate_plan_no(), 生成计划编号 SXDDHYYYYMMDD######, 生成计划编号 SXDDHYYYYMMDD######, 生成计划编号 SXDDHYYYYMMDD######, 生成计划编号 SXDDHYYYYMMDD######, 生成计划编号 SXDDHYYYYMMDD######, 生成计划编号 SXDDHYYYYMMDD######, 生成计划编号 SXDDHYYYYMMDD###### (+13 more)
|
||||
|
||||
### Community 34 - "Community 34"
|
||||
Cohesion: 0.12
|
||||
Nodes (23): datetime, int, str, datetime, 审批轮次过滤 — 驳回后重新提交时,进度接口仅展示当前轮次。, format_datetime(), generate_random_password(), get_current_time() (+15 more)
|
||||
Cohesion: 0.09
|
||||
Nodes (32): datetime, int, str, datetime, int, Session, str, date (+24 more)
|
||||
|
||||
### Community 35 - "Community 35"
|
||||
Cohesion: 0.08
|
||||
Cohesion: 0.07
|
||||
Nodes (40): _db_pool_keepalive_loop(), _error_json(), lifespan(), _mask_secret(), Exception, int, Request, str (+32 more)
|
||||
|
||||
### Community 36 - "Community 36"
|
||||
Cohesion: 0.13
|
||||
Nodes (27): CreateFromContractRequest, HazardCertReadyBody, PlanArchiveBody, PlanDeliverySlipTemplateSave, PlanDriverFeedbackUpdateBody, PlanInboundSlipTemplateSave, PlanListResponse, PlanProductCertItem (+19 more)
|
||||
Cohesion: 0.10
|
||||
Nodes (21): invoice_info_list(), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价) (+13 more)
|
||||
|
||||
### Community 37 - "Community 37"
|
||||
Cohesion: 0.28
|
||||
Nodes (45): InboundOutboundRead, bool, DbPurchasePlan, PurchasePlanRead, PurchasePlanWithFillLink, WeighingSlipRead, bool, date (+37 more)
|
||||
Cohesion: 0.24
|
||||
Nodes (46): InboundOutboundRead, bool, DbPurchasePlan, DbUserContext, PurchasePlanRead, PurchasePlanWithFillLink, Session, str (+38 more)
|
||||
|
||||
### Community 38 - "Community 38"
|
||||
Cohesion: 0.25
|
||||
Nodes (23): Any, bool, int, Session, str, create_role(), get_role(), get_role_data_scope() (+15 more)
|
||||
|
||||
### Community 39 - "Community 39"
|
||||
Cohesion: 0.04
|
||||
Nodes (46): get_plan_arrange_info(), patch_plan_product_certs(), 更新计划危化品产品购买证/运输证(不触发安排运输), 更新计划危化品产品购买证/运输证(不触发安排运输), 更新计划危化品产品购买证/运输证(不触发安排运输), 更新计划危化品产品购买证/运输证(不触发安排运输), 更新计划危化品产品购买证/运输证(不触发安排运输), 更新计划危化品产品购买证/运输证(不触发安排运输) (+38 more)
|
||||
Cohesion: 0.03
|
||||
Nodes (71): _build_driver_url(), cancel_plan(), get_plan_arrange_info(), patch_plan_product_certs(), 作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。, 作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。, 作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。, 作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。 (+63 more)
|
||||
|
||||
### Community 40 - "Community 40"
|
||||
Cohesion: 0.04
|
||||
Nodes (45): 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list (+37 more)
|
||||
Nodes (76): 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list, 分页查询供方列表 — Java: CrmSupplierInfoController.list (+68 more)
|
||||
|
||||
### Community 41 - "Community 41"
|
||||
Cohesion: 0.06
|
||||
Nodes (60): CRM 合同 API 路由 — GET/PUT/DELETE/POST 对齐原 Java CRM, CRM 合同子模块路由 — 变更/模板/审批独立页, register_contract_sub_routes(), CRM 合同 Pydantic Schemas — 对照 CrmContractBo / CrmContractVo, ContractApprovalActionBody, ContractApprovalApproveBody, ContractApprovalByContractBody, ContractApprovalExportBody (+52 more)
|
||||
Nodes (49): CRM 合同 API 路由 — GET/PUT/DELETE/POST 对齐原 Java CRM, CRM 合同 Pydantic Schemas — 对照 CrmContractBo / CrmContractVo, ContractApprovalActionBody, ContractApprovalApproveBody, ContractApprovalByContractBody, ContractApprovalListBody, ContractApprovalPageListBody, ContractApprovalRefreshNamesBody (+41 more)
|
||||
|
||||
### Community 42 - "Community 42"
|
||||
Cohesion: 0.17
|
||||
Nodes (21): Any, bool, BxUserContext, BxWorkflowNode, float, int, Session, str (+13 more)
|
||||
|
||||
### Community 43 - "Community 43"
|
||||
Cohesion: 0.28
|
||||
Nodes (17): DbUserContext, Session, str, int, Session, str, PlMenuBadgeStatsRead, menu_badge_stats() (+9 more)
|
||||
Cohesion: 0.21
|
||||
Nodes (34): _dec(), derive_source_url(), fetch_portal_admin_id(), fetch_source_rows(), legacy_id_to_str(), legacy_parent_id(), load_oss_id_to_url(), load_runtime_settings() (+26 more)
|
||||
|
||||
### Community 44 - "Community 44"
|
||||
Cohesion: 0.08
|
||||
Nodes (26): get_current_user_profile(), get_web_auth_menu_codes(), logout(), public_quote_share(), 登出:吊销 Redis 会话(若已配置 REDIS_HOST)。, 登出:吊销 Redis 会话(若已配置 REDIS_HOST)。, 登出:吊销 Redis 会话(若已配置 REDIS_HOST)。, 登出:吊销 Redis 会话(若已配置 REDIS_HOST)。 (+18 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (38): change_current_user_password(), get_current_user_profile(), get_web_auth_menu_codes(), logout(), public_quote_share(), 登出:吊销 Redis 会话(若已配置 REDIS_HOST)。, 登出:吊销 Redis 会话(若已配置 REDIS_HOST)。, 登出:吊销 Redis 会话(若已配置 REDIS_HOST)。 (+30 more)
|
||||
|
||||
### Community 45 - "Community 45"
|
||||
Cohesion: 0.11
|
||||
Nodes (38): str, T, bool, date, datetime, int, Session, str (+30 more)
|
||||
Nodes (37): str, T, bool, date, datetime, int, Session, str (+29 more)
|
||||
|
||||
### Community 46 - "Community 46"
|
||||
Cohesion: 0.21
|
||||
Nodes (37): DbInboundOutbound, DbUserContext, Session, str, CreateLinkForPlanPayload, _apply_inventory_product_update(), _apply_inventory_update(), _base_query() (+29 more)
|
||||
Cohesion: 0.19
|
||||
Nodes (44): DbInboundOutbound, DbUserContext, Session, str, CreateLinkForPlanPayload, _apply_inventory_product_update(), _apply_inventory_update(), _base_query() (+36 more)
|
||||
|
||||
### Community 47 - "Community 47"
|
||||
Cohesion: 0.09
|
||||
Nodes (27): str, ContactDetailBody, ContactSetPrimaryBody, ContractApprovalPageListBody, ContractChangeSubmitBody, ContractProductPriceTierItem, 全局审批记录分页(approval/index.vue), CustomerCheckDuplicateBody (+19 more)
|
||||
Cohesion: 0.02
|
||||
Nodes (194): CRM 报价单 API 路由 — 挂接到 crm.router, str, CRM 报价单 Pydantic Schemas, 运输计划管理 - 基础数据 Schema(承运商、车辆、人员、证书), Decimal, Decimal, str, BaseModel (+186 more)
|
||||
|
||||
### Community 48 - "Community 48"
|
||||
Cohesion: 0.06
|
||||
Nodes (129): bool, DbUserContext, int, 运输计划管理 - 基础数据 API(承运商、车辆、人员), PlCarrier, PlVehicle, Session, str (+121 more)
|
||||
Cohesion: 0.10
|
||||
Nodes (69): DbUserContext, int, 运输计划管理 - 基础数据 API(承运商、车辆、人员), PlVehicle, Session, str, VehicleRead, date (+61 more)
|
||||
|
||||
### Community 49 - "Community 49"
|
||||
Cohesion: 0.13
|
||||
Nodes (40): 公共接口(Web 登录、刷新 Token、登出;用户模型对齐 docs/sql/shanxia2.0.sql 基线), refresh_token(), bool, Redis, Request, Session, str, _T (+32 more)
|
||||
Cohesion: 0.10
|
||||
Nodes (52): 公共接口(Web 登录、刷新 Token、登出;用户模型对齐 docs/sql/shanxia2.0.sql 基线), refresh_token(), bool, Redis, Request, Session, str, _T (+44 more)
|
||||
|
||||
### Community 50 - "Community 50"
|
||||
Cohesion: 0.14
|
||||
Nodes (25): bool, BxUserContext, int, Session, str, Any, bool, int (+17 more)
|
||||
Cohesion: 0.41
|
||||
Nodes (8): bool, BxUserContext, int, Session, str, AttachmentService, BxAttachment, BxAttachment
|
||||
|
||||
### Community 51 - "Community 51"
|
||||
Cohesion: 0.13
|
||||
Nodes (37): Any, bool, Decimal, int, Session, str, batch_insert_quote_products(), calculate_subtotal() (+29 more)
|
||||
|
||||
### Community 52 - "Community 52"
|
||||
Cohesion: 0.15
|
||||
Nodes (30): Any, bool, int, Session, str, approve_quote(), can_user_approve(), create_approval_records() (+22 more)
|
||||
Cohesion: 0.14
|
||||
Nodes (29): Any, bool, int, Session, str, approve_quote(), can_user_approve(), create_approval_records() (+21 more)
|
||||
|
||||
### Community 53 - "Community 53"
|
||||
Cohesion: 0.30
|
||||
Nodes (32): AdvanceIssueRequest, BxUserContext, int, ReimburseApplyOut, Session, str, BatchOffsetRequest, AdvanceFinanceIssueStatsOut (+24 more)
|
||||
Nodes (34): AdvanceIssueRequest, BxUserContext, int, ReimburseApplyOut, Session, str, BatchOffsetRequest, AdvanceFinanceIssueStatsOut (+26 more)
|
||||
|
||||
### Community 54 - "Community 54"
|
||||
Cohesion: 0.13
|
||||
Nodes (15): Any, bool, int, str, get_wechat_pay_client(), get_wechat_pay_v2(), 微信支付工具模块 支持微信支付 V3 API 文档参考: https://pay.weixin.qq.com/docs/v3/apis/index.html, 统一下单接口 (V3) Args: out_trade_no: 商户订单号 total_amo (+7 more)
|
||||
|
||||
### Community 55 - "Community 55"
|
||||
Cohesion: 0.21
|
||||
Nodes (28): bool, CRM 产品模块 CRUD(产品分类 + 产品 + 附件), int, Session, str, barcode_exists(), category_code_exists(), create_category() (+20 more)
|
||||
Cohesion: 0.23
|
||||
Nodes (26): bool, CRM 产品模块 CRUD(产品分类 + 产品 + 附件), int, Session, str, barcode_exists(), category_code_exists(), create_category() (+18 more)
|
||||
|
||||
### Community 56 - "Community 56"
|
||||
Cohesion: 0.16
|
||||
Nodes (31): Any, bool, CrmContractProductPriceTier, date, Decimal, int, Session, str (+23 more)
|
||||
Nodes (33): Any, bool, CrmContractProductPriceTier, date, Decimal, int, Session, str (+25 more)
|
||||
|
||||
### Community 57 - "Community 57"
|
||||
Cohesion: 0.36
|
||||
@@ -451,71 +431,71 @@ Nodes (16): Any, bool, int, Session, str, create_tenant(), get_tenant(), list_te
|
||||
|
||||
### Community 59 - "Community 59"
|
||||
Cohesion: 0.03
|
||||
Nodes (61): 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll (+53 more)
|
||||
Nodes (60): 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll, 供方全量列表(下拉)— Java: CrmSupplierInfoController.listAll (+52 more)
|
||||
|
||||
### Community 60 - "Community 60"
|
||||
Cohesion: 0.21
|
||||
Nodes (27): approve_task(), _assert_wf_instance_in_scope(), _business_type_label(), create_process_def(), delete_process_def(), _enrich_task_list(), get_business_all_tasks(), _get_business_form_fields() (+19 more)
|
||||
Cohesion: 0.13
|
||||
Nodes (18): Any, _build_category_tree(), _collect_category_with_ancestors(), list_category_tree(), list_oss_by_biz(), list_product_options(), _oss_row_to_dict(), 获取产品分类树(嵌套 children,供树形表格/树选择器使用) (+10 more)
|
||||
|
||||
### Community 61 - "Community 61"
|
||||
Cohesion: 0.21
|
||||
Nodes (30): Engine, Path, build_id_maps(), clip_text(), count_rows(), export_mapping(), fetch_rows(), legacy_id_to_str() (+22 more)
|
||||
Cohesion: 0.22
|
||||
Nodes (29): Engine, build_id_maps(), clip_text(), count_rows(), export_mapping(), fetch_rows(), legacy_id_to_str(), main() (+21 more)
|
||||
|
||||
### Community 62 - "Community 62"
|
||||
Cohesion: 0.16
|
||||
Nodes (31): DbUserContext, float, Session, str, Session, _auto_fill_create_dept_id(), get_db(), ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID (+23 more)
|
||||
Cohesion: 0.30
|
||||
Nodes (22): DbUserContext, float, Session, str, Session, str, DashboardCargoStat, DashboardPartnerCargoStat (+14 more)
|
||||
|
||||
### Community 63 - "Community 63"
|
||||
Cohesion: 0.40
|
||||
Nodes (4): Any, str, 供 get_tenant_no 等门户工具使用。, 与门户 JWT / apply_data_scope 所需的 user_info 字段对齐。
|
||||
Cohesion: 0.33
|
||||
Nodes (15): BxUserContext, int, Session, str, create_workflow(), delete_workflow(), get_workflow(), get_workflow_by_biz_type() (+7 more)
|
||||
|
||||
### Community 64 - "Community 64"
|
||||
Cohesion: 0.22
|
||||
Nodes (29): Any, int, Session, str, create_instance(), create_process_def(), create_task(), get_all_tasks_for_business() (+21 more)
|
||||
Cohesion: 0.18
|
||||
Nodes (35): Any, int, Session, str, str, 解析列表查询参数,供 API 与 CRUD 共用。, create_instance(), create_process_def() (+27 more)
|
||||
|
||||
### Community 65 - "Community 65"
|
||||
Cohesion: 0.10
|
||||
Nodes (23): API 路由包 — 山峡化工生产一体化门户, get_menu_list(), 运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,14 个一级菜单), operlog_detail(), operlog_list(), 操作日志分页列表(基于 API 请求日志适配 RuoYi OperLog 结构), 操作日志分页列表(基于 API 请求日志适配 RuoYi OperLog 结构), _user_info() (+15 more)
|
||||
Cohesion: 0.12
|
||||
Nodes (31): API 路由包 — 山峡化工生产一体化门户, create_leave(), delete_leave(), get_leave(), _leave_local_callback(), leave_workflow_callback(), list_leaves(), submit_leave() (+23 more)
|
||||
|
||||
### Community 66 - "Community 66"
|
||||
Cohesion: 0.08
|
||||
Nodes (25): 技术栈, 1. 创建虚拟环境, 项目结构, 1. 创建虚拟环境, 2. 安装依赖, 2. 安装依赖, 3. 配置环境变量, 快速开始 (+17 more)
|
||||
|
||||
### Community 67 - "Community 67"
|
||||
Cohesion: 0.20
|
||||
Nodes (30): DbUserContext, DbWeighingSlip, Session, str, Session, str, datetime_end_of_day(), parse_datetime_str() (+22 more)
|
||||
Cohesion: 0.21
|
||||
Nodes (29): DbUserContext, DbWeighingSlip, Session, str, Session, str, datetime_end_of_day(), weighing_to_read() (+21 more)
|
||||
|
||||
### Community 68 - "Community 68"
|
||||
Cohesion: 0.22
|
||||
Nodes (9): download_contract_pdf(), Java: downloadContractPdf — 返回合同文件 URL/路径, Java: batchAssignOwner, Java: downloadContractPdf — 返回合同文件 URL/路径, Java: downloadContractPdf — 返回合同文件 URL/路径, Java: downloadContractPdf — 返回合同文件 URL/路径, Java: downloadContractPdf — 返回合同文件 URL/路径, Java: downloadContractPdf — 返回合同文件 URL/路径 (+1 more)
|
||||
Cohesion: 0.08
|
||||
Nodes (25): batch_assign_owner(), download_contract_pdf(), Java: batchAssignOwner, Java: downloadContractPdf — 返回合同文件 URL/路径, Java: batchAssignOwner, Java: batchAssignOwner, Java: batchAssignOwner, Java: batchAssignOwner (+17 more)
|
||||
|
||||
### Community 69 - "Community 69"
|
||||
Cohesion: 0.21
|
||||
Nodes (16): Any, int, str, BusinessException, InvalidStatusTransitionException, log_api_request(), log_delivery_operation(), log_operation() (+8 more)
|
||||
|
||||
### Community 70 - "Community 70"
|
||||
Cohesion: 0.17
|
||||
Nodes (12): generate_product_no(), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001) (+4 more)
|
||||
Cohesion: 0.22
|
||||
Nodes (31): _dec(), derive_source_url(), fetch_portal_admin_id(), fetch_source_rows(), legacy_id_to_str(), load_oss_id_to_url(), load_runtime_settings(), load_settings_env() (+23 more)
|
||||
|
||||
### Community 71 - "Community 71"
|
||||
Cohesion: 0.26
|
||||
Nodes (22): Any, bool, datetime, int, Session, str, BizSampleCode, batch_generate_sample_codes() (+14 more)
|
||||
|
||||
### Community 72 - "Community 72"
|
||||
Cohesion: 0.31
|
||||
Cohesion: 0.33
|
||||
Nodes (11): bool, BxUserContext, BxWorkflowNode, int, Session, str, 按业务类型获取工作流;已知类型不存在时自动创建空定义(无节点)。, 按业务类型获取工作流;已知类型不存在时自动创建空定义(无节点)。 (+3 more)
|
||||
|
||||
### Community 73 - "Community 73"
|
||||
Cohesion: 0.09
|
||||
Nodes (26): Any, _build_category_tree(), _category_row_to_dict(), _collect_category_with_ancestors(), list_categories(), list_category_tree(), list_oss_by_biz(), _oss_row_to_dict() (+18 more)
|
||||
Cohesion: 0.33
|
||||
Nodes (14): Any, int, Session, str, create_dict_data(), get_dict_data(), list_dict_data(), list_dict_data_options() (+6 more)
|
||||
|
||||
### Community 74 - "Community 74"
|
||||
Cohesion: 0.06
|
||||
Nodes (92): bool, DbInboundOutbound, int, PublicInventoryFeedback, PublicInventoryPageRead, Session, str, UploadFile (+84 more)
|
||||
Cohesion: 0.05
|
||||
Nodes (123): bool, DbInboundOutbound, int, PublicInventoryFeedback, PublicInventoryPageRead, Session, str, UploadFile (+115 more)
|
||||
|
||||
### Community 75 - "Community 75"
|
||||
Cohesion: 0.09
|
||||
Nodes (22): cancel_plan(), 作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。, 作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。, 作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。, 作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。, 作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。, 作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。, 作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。 (+14 more)
|
||||
Cohesion: 0.20
|
||||
Nodes (10): Decimal, VehicleUreaApplyCreate, VehicleUreaApplyListResponse, VehicleUreaApplyRead, VehicleUreaApplyUpdate, VehicleUreaDisburseBoardListResponse, VehicleUreaDisburseCreate, VehicleUreaDisburseListResponse (+2 more)
|
||||
|
||||
### Community 76 - "Community 76"
|
||||
Cohesion: 0.09
|
||||
@@ -523,7 +503,7 @@ Nodes (23): product_delete(), 删除产品(支持单条 body.id 和批量 body
|
||||
|
||||
### Community 77 - "Community 77"
|
||||
Cohesion: 0.11
|
||||
Nodes (101): date, DbUserContext, int, Session, str, VehicleUreaApplyCreate, VehicleUreaApplyRead, VehicleUreaApplyUpdate (+93 more)
|
||||
Nodes (100): date, DbUserContext, int, Session, str, VehicleUreaApplyCreate, VehicleUreaApplyRead, VehicleUreaApplyUpdate (+92 more)
|
||||
|
||||
### Community 78 - "Community 78"
|
||||
Cohesion: 0.32
|
||||
@@ -534,8 +514,8 @@ Cohesion: 0.38
|
||||
Nodes (22): DbUserContext, int, Session, str, PlTransportAddress, 运输通用地址库 pl_transport_address, 运输通用地址库 pl_transport_address, 运输通用地址库 pl_transport_address (+14 more)
|
||||
|
||||
### Community 80 - "Community 80"
|
||||
Cohesion: 0.22
|
||||
Nodes (19): Any, bool, str, _actor_ids(), _actor_names(), assert_rows_deletable_by_creator(), can_delete_by_creator(), is_super_admin() (+11 more)
|
||||
Cohesion: 0.15
|
||||
Nodes (35): Any, bool, str, Any, bool, int, Session, str (+27 more)
|
||||
|
||||
### Community 81 - "Community 81"
|
||||
Cohesion: 0.27
|
||||
@@ -558,8 +538,8 @@ Cohesion: 0.34
|
||||
Nodes (19): check_python(), create_venv(), ensure_dirs(), ensure_valid_venv(), ensure_venv_and_runtime(), install_dependencies(), is_running(), log_error() (+11 more)
|
||||
|
||||
### Community 86 - "Community 86"
|
||||
Cohesion: 0.16
|
||||
Nodes (16): bool, date, Session, str, get_last_month_range(), month_range(), 地磅计划按月自动生成 — 迁移自 simple-dibang-xiaoshou/auto-create-plan/auto_create_monthly_pla, 按月自动生成采购计划。 - 默认仅在每月 1 日执行(force=True 时跳过该限制,供手动触发验收) - 遍历所有租户,按上月计划模板生 (+8 more)
|
||||
Cohesion: 0.11
|
||||
Nodes (22): bool, date, Session, str, get_last_month_range(), month_range(), 地磅计划按月自动生成 — 迁移自 simple-dibang-xiaoshou/auto-create-plan/auto_create_monthly_pla, 按月自动生成采购计划。 - 默认仅在每月 1 日执行(force=True 时跳过该限制,供手动触发验收) - 遍历所有租户,按上月计划模板生 (+14 more)
|
||||
|
||||
### Community 87 - "Community 87"
|
||||
Cohesion: 0.28
|
||||
@@ -570,12 +550,12 @@ Cohesion: 0.21
|
||||
Nodes (17): bool, int, Redis, Request, str, _claims_from_auth(), _coerce_post_method_override_to_get(), _get_redis_client() (+9 more)
|
||||
|
||||
### Community 89 - "Community 89"
|
||||
Cohesion: 0.35
|
||||
Nodes (17): Any, bool, int, Session, str, _build_tree(), _cascade_soft_delete(), create_menu() (+9 more)
|
||||
Cohesion: 0.09
|
||||
Nodes (44): list_roles_for_select(), 返回运营端角色下拉选项(label=库中角色名,value=Web 角色码)。, 返回运营端角色下拉选项(label=库中角色名,value=Web 角色码)。, 返回运营端角色下拉选项(label=库中角色名,value=Web 角色码)。, Session, str, Any, bool (+36 more)
|
||||
|
||||
### Community 90 - "Community 90"
|
||||
Cohesion: 0.22
|
||||
Nodes (17): Any, bool, Session, str, list_share_logs(), _parse_user_agent(), CRM 报价单分享访问日志 CRUD — 对照 CrmQuoteShareLogServiceImpl.java, Java: statisticsVisits (+9 more)
|
||||
Cohesion: 0.12
|
||||
Nodes (26): Any, bool, Session, str, Java: viewByShareCode, Java: viewByShareCode, Java: viewByShareCode, Java: viewByShareCode (+18 more)
|
||||
|
||||
### Community 91 - "Community 91"
|
||||
Cohesion: 0.17
|
||||
@@ -594,8 +574,8 @@ Cohesion: 0.29
|
||||
Nodes (16): Any, int, Session, str, BizLeaveRequest, create_leave(), get_leave(), list_leaves() (+8 more)
|
||||
|
||||
### Community 95 - "Community 95"
|
||||
Cohesion: 0.38
|
||||
Nodes (15): Any, bool, int, Session, str, create_post(), get_post(), list_posts() (+7 more)
|
||||
Cohesion: 0.44
|
||||
Nodes (13): bool, date, PlCarrier, str, PlCarrier, assert_carrier_eligible_for_transport(), carrier_agreement_expired(), carrier_audit_approved() (+5 more)
|
||||
|
||||
### Community 96 - "Community 96"
|
||||
Cohesion: 0.38
|
||||
@@ -606,8 +586,8 @@ Cohesion: 0.30
|
||||
Nodes (21): Any, bool, CrmOpportunity, datetime, int, Session, str, ensure_crm_create_by_row_in_scope() (+13 more)
|
||||
|
||||
### Community 98 - "Community 98"
|
||||
Cohesion: 0.22
|
||||
Nodes (28): register_quote_routes(), bool, int, Session, str, accept_quote(), _ensure_quote_in_scope(), generate_pdf() (+20 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (92): CertRead, Any, bool, CertRow, Session, str, VehiclePersonnelRow, CertRead (+84 more)
|
||||
|
||||
### Community 99 - "Community 99"
|
||||
Cohesion: 0.29
|
||||
@@ -618,40 +598,40 @@ Cohesion: 0.28
|
||||
Nodes (13): int, Session, str, _allocate_inbound_outbound_id(), _ensure_sequence_row(), max_numeric_inbound_outbound_id(), next_inbound_outbound_id(), 出入库单 id 生成 — 租户内纯数字自增,并发安全。 (+5 more)
|
||||
|
||||
### Community 101 - "Community 101"
|
||||
Cohesion: 0.21
|
||||
Nodes (26): CrmContract, CrmContractProductPriceTier, date, datetime, int, Query, _parse_letter_oss_ids_from_tier(), Java: validateFrameworkContractForSubmitApproval (+18 more)
|
||||
Cohesion: 0.07
|
||||
Nodes (30): create_plan_full(), 创建运输计划(完整表单:合同产品 + 可选运输安排), 创建运输计划(完整表单:合同产品 + 可选运输安排), 创建运输计划(完整表单:合同产品 + 可选运输安排), 创建运输计划(完整表单:合同产品 + 可选预选车辆,不自动安排运输), 创建运输计划(完整表单:合同产品 + 可选预选车辆,不自动安排运输), 创建运输计划(完整表单:合同产品 + 可选预选车辆,不自动安排运输), 创建运输计划(完整表单:合同产品 + 可选预选车辆,不自动安排运输) (+22 more)
|
||||
|
||||
### Community 102 - "Community 102"
|
||||
Cohesion: 0.33
|
||||
Nodes (3): 地磅 API 路由聚合 — REST 风格,协议对齐原 simple-dibang-xiaoshou。, 地磅(db)Pydantic schemas — 对齐原 simple-dibang-xiaoshou 契约。, 地磅 API 路由聚合 — REST 风格,协议对齐原 simple-dibang-xiaoshou。
|
||||
Cohesion: 0.17
|
||||
Nodes (12): generate_auto_product_no(), Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符 (+4 more)
|
||||
|
||||
### Community 103 - "Community 103"
|
||||
Cohesion: 0.41
|
||||
Nodes (11): Any, str, build_quote_html(), _default_value(), _format_date(), _format_discount(), _format_money(), generate_quote_pdf() (+3 more)
|
||||
|
||||
### Community 104 - "Community 104"
|
||||
Cohesion: 0.29
|
||||
Nodes (10): datetime, int, Session, str, BizNoKind, allocate_next_biz_no(), _format_biz_no(), _prefix_for() (+2 more)
|
||||
Cohesion: 0.17
|
||||
Nodes (12): generate_product_no(), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001), 生成产品编号(格式:CP + yyyyMMdd + 3位序号,如 CP20260530001) (+4 more)
|
||||
|
||||
### Community 105 - "Community 105"
|
||||
Cohesion: 0.10
|
||||
Nodes (21): invoice_info_list(), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价), 按客户ID查询开票信息(与 by-customer 等价) (+13 more)
|
||||
Cohesion: 0.23
|
||||
Nodes (28): derive_source_url(), fetch_portal_admin_id(), fetch_source_rows(), legacy_id_to_str(), load_oss_id_to_url(), load_runtime_settings(), load_settings_env(), load_user_mapping() (+20 more)
|
||||
|
||||
### Community 106 - "Community 106"
|
||||
Cohesion: 0.39
|
||||
Nodes (6): _inject_user_info_after_tenant(), patch_contract_routes(), patch_quote_routes(), patch_route_file(), Path, str
|
||||
|
||||
### Community 107 - "Community 107"
|
||||
Cohesion: 0.19
|
||||
Nodes (23): load_runtime_settings(), load_settings_env(), main(), int, str, verify_user_menu_codes(), assign_user_roles(), collect_subtree_menu_ids() (+15 more)
|
||||
Cohesion: 0.14
|
||||
Nodes (28): BaseSettings, Config, Settings, load_runtime_settings(), load_settings_env(), main(), int, str (+20 more)
|
||||
|
||||
### Community 108 - "Community 108"
|
||||
Cohesion: 0.33
|
||||
Nodes (8): Decimal, str, derive_legacy_status_from_three(), derive_three_status_from_legacy(), 阶段A兼容:从旧 status 推导三字段。 约束:旧 status 本身混合了支付/配送/订单生命周期,因此只能尽力推断; 若业务侧已有更精确, 阶段A兼容:从三字段反推旧 status(用于旧前端/旧筛选参数兼容)。, ThreeStatus, _to_decimal()
|
||||
|
||||
### Community 109 - "Community 109"
|
||||
Cohesion: 0.18
|
||||
Nodes (10): Any, Request, str, str, parse_admin_request_json(), 运营 Web(/web/admin)JSON 请求体解析。 与 ApiCryptoMiddleware 配合:中间件未改写 body 时,在路由内解密 `{, 读取 JSON body;dict 时走 resolve_request_payload(明文 / 密文 / data 包装)。 Returns:, 统一解析接口请求载荷(明文 / 密文信封)。 (+2 more)
|
||||
Cohesion: 0.17
|
||||
Nodes (12): _get_quote_item_field(), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配) (+4 more)
|
||||
|
||||
### Community 110 - "Community 110"
|
||||
Cohesion: 0.28
|
||||
@@ -666,8 +646,8 @@ Cohesion: 0.17
|
||||
Nodes (20): Any, int, str, get_oper_log_meta(), OperLogMeta, 请求级操作日志元数据(ContextVar), 供异步落库线程使用,避免 ContextVar 跨线程丢失。, set_oper_log_meta() (+12 more)
|
||||
|
||||
### Community 113 - "Community 113"
|
||||
Cohesion: 0.18
|
||||
Nodes (9): 报销(bx)API 路由聚合 — REST 风格,协议对齐 bx 原系统。, 报销(bx)Pydantic 模型 — 响应协议与 bx 原系统保持一致, bx_health(), 报销(bx)API 路由聚合 — REST 风格,协议对齐 bx 原系统。, P0 健康检查:验证 bx 路由已挂载且响应协议为 code=0。, P0 健康检查:验证 bx 路由已挂载且响应协议为 code=0。, P0 健康检查:验证 bx 路由已挂载且响应协议为 code=0。, P0 健康检查:验证 bx 路由已挂载且响应协议为 code=0。 (+1 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (25): 报销(bx)API 路由聚合 — REST 风格,协议对齐 bx 原系统。, 地磅 API 路由聚合 — REST 风格,协议对齐原 simple-dibang-xiaoshou。, Session, 报销(bx)Pydantic 模型 — 响应协议与 bx 原系统保持一致, 地磅(db)Pydantic schemas — 对齐原 simple-dibang-xiaoshou 契约。, bx_health(), 报销(bx)API 路由聚合 — REST 风格,协议对齐 bx 原系统。, P0 健康检查:验证 bx 路由已挂载且响应协议为 code=0。 (+17 more)
|
||||
|
||||
### Community 114 - "Community 114"
|
||||
Cohesion: 0.60
|
||||
@@ -678,12 +658,12 @@ Cohesion: 0.36
|
||||
Nodes (10): add_scope_before_order(), ensure_import(), patch_base_data(), patch_get_helper(), patch_inventory(), patch_plan(), patch_transport(), str (+2 more)
|
||||
|
||||
### Community 116 - "Community 116"
|
||||
Cohesion: 0.07
|
||||
Nodes (28): _build_contract_filters(), export_contracts(), ORM → camelCase(单点真相), ORM → camelCase(单点真相), ORM → camelCase(单点真相), ORM → camelCase(单点真相), ORM → camelCase(单点真相), Java: queryList for export (+20 more)
|
||||
Cohesion: 0.10
|
||||
Nodes (20): Query, _build_contract_filters(), export_contracts(), Java: queryList for export, Java: queryList for export, Java: queryList for export, Java: queryList for export, Java: buildQueryWrapper (+12 more)
|
||||
|
||||
### Community 117 - "Community 117"
|
||||
Cohesion: 0.13
|
||||
Nodes (40): Any, bool, date, int, Session, str, Session, str (+32 more)
|
||||
Nodes (41): Any, bool, date, int, Session, str, Session, str (+33 more)
|
||||
|
||||
### Community 118 - "Community 118"
|
||||
Cohesion: 0.38
|
||||
@@ -698,8 +678,8 @@ Cohesion: 0.22
|
||||
Nodes (9): generate_template_no(), Java: generateTemplateNo — TMPL{yyyyMMdd}{4位序号}, Java: generateTemplateNo — TMPL{yyyyMMdd}{4位序号}, Java: generateTemplateNo — TMPL{yyyyMMdd}{4位序号}, Java: generateTemplateNo — TMPL{yyyyMMdd}{4位序号}, Java: generateTemplateNo — TMPL{yyyyMMdd}{4位序号}, Java: generateTemplateNo — TMPL{yyyyMMdd}{4位序号}, Java: generateTemplateNo — TMPL{yyyyMMdd}{4位序号} (+1 more)
|
||||
|
||||
### Community 121 - "Community 121"
|
||||
Cohesion: 0.12
|
||||
Nodes (31): CRM 报价单 API 路由 — 挂接到 crm.router, CRM 报价单 Pydantic Schemas, QuoteAcceptBody, QuoteApprovalApproveBody, QuoteApprovalListBody, QuoteApprovalRefreshNamesBody, QuoteApprovalWithdrawBody, QuoteCreateBody (+23 more)
|
||||
Cohesion: 0.40
|
||||
Nodes (10): SysOss, int, Session, str, SysOss, create_oss(), create_oss(), get_oss_by_url() (+2 more)
|
||||
|
||||
### Community 122 - "Community 122"
|
||||
Cohesion: 0.32
|
||||
@@ -711,132 +691,92 @@ Nodes (4): str, _coerce_id(), ExpenseItemCreate, ExpenseItemUpdate
|
||||
|
||||
### Community 124 - "Community 124"
|
||||
Cohesion: 0.16
|
||||
Nodes (26): Any, bool, bytes, int, Request, str, bool, int (+18 more)
|
||||
Nodes (25): Any, bool, bytes, int, Request, str, bool, int (+17 more)
|
||||
|
||||
### Community 125 - "Community 125"
|
||||
Cohesion: 0.15
|
||||
Nodes (37): build_merged_users(), bx_role_labels(), check_minio(), check_mysql(), check_redis(), _clip(), crm_role_labels(), derive_source_url() (+29 more)
|
||||
Nodes (38): Namespace, build_merged_users(), bx_role_labels(), check_minio(), check_mysql(), check_redis(), _clip(), crm_role_labels() (+30 more)
|
||||
|
||||
### Community 126 - "Community 126"
|
||||
Cohesion: 0.17
|
||||
Nodes (12): generate_auto_product_no(), Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符, Java: generateAutoProductNo — SXWL + 8位随机大写字符 (+4 more)
|
||||
Cohesion: 0.23
|
||||
Nodes (27): count_source_rows(), derive_source_url(), fetch_portal_admin_id(), fetch_source_rows(), legacy_id_to_str(), load_runtime_settings(), load_settings_env(), load_user_mapping() (+19 more)
|
||||
|
||||
### Community 127 - "Community 127"
|
||||
Cohesion: 0.20
|
||||
Nodes (10): Decimal, VehicleUreaApplyCreate, VehicleUreaApplyListResponse, VehicleUreaApplyRead, VehicleUreaApplyUpdate, VehicleUreaDisburseBoardListResponse, VehicleUreaDisburseCreate, VehicleUreaDisburseListResponse (+2 more)
|
||||
Cohesion: 0.19
|
||||
Nodes (18): str, Any, bool, Session, str, CRM 模块 Excel 导出列定义(字段与字典类型对齐 Java *Vo @ExcelDictFormat)。, _yes_no(), _build_workbook() (+10 more)
|
||||
|
||||
### Community 129 - "Community 129"
|
||||
Cohesion: 0.18
|
||||
Nodes (11): Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配), Java: resolveProductIdForQuoteItem(CrmProduct 无 tax_rate,跳过税率匹配) (+3 more)
|
||||
Cohesion: 0.20
|
||||
Nodes (10): Java: deleteWithValidByIds — 软删除, Java: deleteWithValidByIds — 软删除, Java: deleteWithValidByIds — 软删除, Java: deleteWithValidByIds — 软删除, Java: deleteWithValidByIds — 软删除, Java: deleteWithValidByIds — 软删除, Java: deleteWithValidByIds, Java: deleteWithValidByIds — 软删除 (+2 more)
|
||||
|
||||
### Community 140 - "Community 140"
|
||||
Cohesion: 0.18
|
||||
Nodes (28): compute_level(), count_target_rows(), derive_source_url(), fetch_portal_admin_id(), fetch_source_rows(), legacy_id_to_str(), load_runtime_settings(), load_settings_env() (+20 more)
|
||||
|
||||
### Community 141 - "Community 141"
|
||||
Cohesion: 0.40
|
||||
Nodes (10): SysOss, int, Session, str, SysOss, create_oss(), create_oss(), get_oss_by_url() (+2 more)
|
||||
Cohesion: 0.41
|
||||
Nodes (13): BxUserContext, Session, str, UploadFile, bind_biz(), delete_attachment(), download_file(), list_by_biz() (+5 more)
|
||||
|
||||
### Community 142 - "Community 142"
|
||||
Cohesion: 0.14
|
||||
Nodes (35): BxUserContext, Session, str, UploadFile, BxUserContext, Session, str, bool (+27 more)
|
||||
Cohesion: 0.09
|
||||
Nodes (43): BxUserContext, Session, str, Any, str, Any, bool, int (+35 more)
|
||||
|
||||
### Community 143 - "Community 143"
|
||||
Cohesion: 0.06
|
||||
Nodes (92): CertRead, Any, bool, CertRow, Session, str, VehiclePersonnelRow, CertRead (+84 more)
|
||||
Cohesion: 0.08
|
||||
Nodes (26): PlDocumentReminder, 运输审批记录表 pl_transport_approval, 汇款凭证表 pl_remittance_voucher, 结算单-运输关联表 pl_freight_settlement_transport, 结算单-运输关联表 pl_freight_settlement_transport, 汇款凭证表 pl_remittance_voucher, 汇款凭证表 pl_remittance_voucher, 证件到期提醒表 pl_document_reminder (+18 more)
|
||||
|
||||
### Community 144 - "Community 144"
|
||||
Cohesion: 0.18
|
||||
Nodes (21): BaseSettings, Config, Settings, Namespace, apply_renumber(), build_mapping(), fetch_products(), format_new_product_no() (+13 more)
|
||||
Cohesion: 0.32
|
||||
Nodes (15): apply_renumber(), build_mapping(), fetch_products(), format_new_product_no(), load_settings_env(), main(), product_id_sort_key(), Engine (+7 more)
|
||||
|
||||
### Community 145 - "Community 145"
|
||||
Cohesion: 0.24
|
||||
Nodes (24): count_target_rows(), _dec(), derive_source_url(), fetch_portal_admin_id(), fetch_source_rows(), legacy_id_to_str(), load_runtime_settings(), load_settings_env() (+16 more)
|
||||
|
||||
### Community 146 - "Community 146"
|
||||
Cohesion: 0.18
|
||||
Nodes (11): generate_contract_no(), Java: generateContractNo — {供方编码}/X-JT + yyyyMMdd + 3位流水, Java: generateContractNo — {供方编码}/X-JT + yyyyMMdd + 3位流水, Java: generateContractNo — {供方编码}/X-JT{yyyyMMdd}{3位序号}, Java: generateContractNo — {供方编码}/X-JT{yyyyMMdd}{3位序号}, Java: generateContractNo — {供方编码}/X-JT{yyyyMMdd}{3位序号}, Java: generateContractNo — {供方编码}/X-JT{yyyyMMdd}{3位序号}, Java: generateContractNo — {供方编码}/X-JT{yyyyMMdd}{3位序号} (+3 more)
|
||||
Cohesion: 0.17
|
||||
Nodes (12): date, generate_contract_no(), Java: generateContractNo — {供方编码}/X-JT + yyyyMMdd + 3位流水, Java: generateContractNo — {供方编码}/X-JT + yyyyMMdd + 3位流水, Java: generateContractNo — {供方编码}/X-JT{yyyyMMdd}{3位序号}, Java: generateContractNo — {供方编码}/X-JT{yyyyMMdd}{3位序号}, Java: generateContractNo — {供方编码}/X-JT{yyyyMMdd}{3位序号}, Java: generateContractNo — {供方编码}/X-JT{yyyyMMdd}{3位序号} (+4 more)
|
||||
|
||||
### Community 147 - "Community 147"
|
||||
Cohesion: 0.29
|
||||
Nodes (7): _product_row_to_dict(), 产品 ORM 对象转 dict(camelCase 键名), 产品 ORM 对象转 dict(camelCase 键名), 产品 ORM 对象转 dict(camelCase 键名), 产品 ORM 对象转 dict(camelCase 键名), 产品 ORM 对象转 dict(camelCase 键名), 产品 ORM 对象转 dict(camelCase 键名)
|
||||
Cohesion: 0.20
|
||||
Nodes (10): generate_barcode(), 生成唯一条码(纯数字:yyyyMMdd + 6位序号,如 20260606000001), 生成唯一条码(纯数字:yyyyMMdd + 6位序号,如 20260606000001), 生成唯一条码(纯数字:yyyyMMdd + 6位序号,如 20260606000001), 生成唯一条码(纯数字:yyyyMMdd + 6位序号,如 20260606000001), 取当前租户下 SXWL 前缀且后缀为纯数字的产品编号最大流水值, 生成唯一条码(纯数字:yyyyMMdd + 6位序号,如 20260606000001), 生成产品编号(格式:SXWL + 6位递增流水号,如 SXWL000001) (+2 more)
|
||||
|
||||
### Community 148 - "Community 148"
|
||||
Cohesion: 0.09
|
||||
Nodes (63): register_contract_routes(), bool, Session, str, bool, batch_assign_owner(), batch_submit_approval(), _enrich_owner_names() (+55 more)
|
||||
Cohesion: 0.07
|
||||
Nodes (132): Any, register_contract_routes(), CRM 合同子模块路由 — 变更/模板/审批独立页, register_contract_sub_routes(), Any, bool, CRM 合同 CRUD — 对照 CrmContractServiceImpl.java(列表/详情 P1), CrmContract (+124 more)
|
||||
|
||||
### Community 149 - "Community 149"
|
||||
Cohesion: 0.16
|
||||
Nodes (12): Decimal, str, VehicleRechargeApplyCreate, VehicleRechargeApplyListResponse, VehicleRechargeApplyOption, VehicleRechargeApplyRead, VehicleRechargeApplyUpdate, VehicleRechargeDisburseBoardListResponse (+4 more)
|
||||
Cohesion: 0.22
|
||||
Nodes (9): batch_submit_contract_approval(), Java: batchSubmitApproval, Java: batchSubmitApproval, Java: batchSubmitApproval, Java: batchSubmitApproval, Java: batchSubmitApproval, Java: batchSubmitApproval, Java: batchSubmitApproval (+1 more)
|
||||
|
||||
### Community 150 - "Community 150"
|
||||
Cohesion: 0.23
|
||||
Nodes (10): Any, bool, int, Session, str, camel_to_snake(), CRUDBase, get_model_attr() (+2 more)
|
||||
|
||||
### Community 151 - "Community 151"
|
||||
Cohesion: 0.28
|
||||
Nodes (8): date, datetime, str, _date_to_str(), _dt_to_str(), PagedQuery, PagedResponse, bx 原系统 API 响应包装(code=0 / msg / data.rows),与门户 success_response 分离。
|
||||
Cohesion: 0.22
|
||||
Nodes (9): _category_row_to_dict(), list_categories(), 分类 ORM 对象转 dict(camelCase 键名), 分类 ORM 对象转 dict(camelCase 键名), 分类 ORM 对象转 dict(camelCase 键名), 分类 ORM 对象转 dict(camelCase 键名), 获取分类(扁平列表,支持名称模糊与状态筛选), 获取分类(扁平列表,支持名称模糊与状态筛选) (+1 more)
|
||||
|
||||
### Community 152 - "Community 152"
|
||||
Cohesion: 0.12
|
||||
Nodes (37): DbUserContext, Session, str, Session, str, plan_to_read(), plan_to_read_with_fill_link(), _apply_plan_product_update() (+29 more)
|
||||
Cohesion: 0.14
|
||||
Nodes (29): str, fmt_date(), fmt_datetime(), inventory_date_to_api(), is_empty_inventory_date(), parse_date_str(), parse_datetime_str(), _parse_site_feedback_images() (+21 more)
|
||||
|
||||
### Community 153 - "Community 153"
|
||||
Cohesion: 0.10
|
||||
Nodes (21): Java: createNewVersion — 返回新报价单 id, Java: CrmQuoteServiceImpl.withdrawApproval(校验创建人), Java: CrmQuoteServiceImpl.withdrawApproval(校验创建人), Java: CrmQuoteServiceImpl.withdrawApproval(校验创建人), Java: CrmQuoteServiceImpl.withdrawApproval(校验创建人), Java: CrmQuoteServiceImpl.withdrawApproval(校验创建人), Java: CrmQuoteServiceImpl.withdrawApproval(校验创建人), Java: statisticsOverview (+13 more)
|
||||
|
||||
### Community 154 - "Community 154"
|
||||
Cohesion: 0.20
|
||||
Nodes (19): bool, Session, str, _expand_with_ancestor_menu_ids(), _granted_menu_ids_for_user(), iter_user_menu_perm_codes(), _map_role_name_to_web(), Web 管理端登录:基于 V0.3 sys_user / sys_user_role / sys_role 的角色与菜单权限解析 (+11 more)
|
||||
|
||||
### Community 155 - "Community 155"
|
||||
Cohesion: 0.27
|
||||
Nodes (17): create_leave(), delete_leave(), get_leave(), _leave_local_callback(), leave_workflow_callback(), list_leaves(), submit_leave(), update_leave() (+9 more)
|
||||
|
||||
### Community 156 - "Community 156"
|
||||
Cohesion: 0.35
|
||||
Nodes (5): Any, str, WfProcessInstance, WorkflowEngine, WfProcessInstance
|
||||
Cohesion: 0.29
|
||||
Nodes (7): _product_row_to_dict(), 产品 ORM 对象转 dict(camelCase 键名), 产品 ORM 对象转 dict(camelCase 键名), 产品 ORM 对象转 dict(camelCase 键名), 产品 ORM 对象转 dict(camelCase 键名), 产品 ORM 对象转 dict(camelCase 键名), 产品 ORM 对象转 dict(camelCase 键名)
|
||||
|
||||
### Community 157 - "Community 157"
|
||||
Cohesion: 0.33
|
||||
Nodes (6): Web 端登录用 RSA 公钥(PKCS#1 v1.5,与 JSEncrypt 一致), Web 端登录用 RSA 公钥(PKCS#1 v1.5,与 JSEncrypt 一致), Web 端登录用 RSA 公钥(PKCS#1 v1.5,与 JSEncrypt 一致), Web 端登录用 RSA 公钥(PKCS#1 v1.5,与 JSEncrypt 一致), Web 端登录用 RSA 公钥(PKCS#1 v1.5,与 JSEncrypt 一致), web_login_rsa_public_key()
|
||||
|
||||
### Community 158 - "Community 158"
|
||||
Cohesion: 0.13
|
||||
Nodes (15): date, generate_quote_no(), Java: toContract — 返回 contractId, Java: toContract — 返回 contractId, Java: toContract — 返回 contractId, Java: generateQuoteNo — {供方编码}DD-yyyyMMdd + 3位序号, Java: generateQuoteNo — {供方编码}DD-yyyyMMdd + 3位序号, Java: generateQuoteNo — {供方编码}DD-yyyyMMdd + 3位序号 (+7 more)
|
||||
|
||||
### Community 159 - "Community 159"
|
||||
Cohesion: 0.14
|
||||
Nodes (39): pool_rule_toggle(), Any, bool, CRM 公海池规则 CRUD + 规则执行逻辑, int, Session, str, create_pool_rule() (+31 more)
|
||||
Cohesion: 0.13
|
||||
Nodes (41): pool_rule_toggle(), Any, bool, CRM 公海池规则 CRUD + 规则执行逻辑, int, Session, str, create_pool_rule() (+33 more)
|
||||
|
||||
### Community 160 - "Community 160"
|
||||
Cohesion: 0.30
|
||||
Nodes (13): Any, bool, bytes, int, str, ApiCryptoError, _b64url_decode(), _b64url_encode() (+5 more)
|
||||
|
||||
### Community 161 - "Community 161"
|
||||
Cohesion: 0.22
|
||||
Nodes (12): Any, bool, str, WfProcessInstance, _LocalCallbackFn, _dispatch_local(), 工作流回调服务 —— 流程状态变更时通知业务系统, 注册本地回调函数。当 callback_url 以 path 开头时直接调用 fn。 (+4 more)
|
||||
|
||||
### Community 162 - "Community 162"
|
||||
Cohesion: 0.15
|
||||
Nodes (13): ORM → camelCase(单点真相), ORM → camelCase(单点真相), ORM → camelCase(单点真相), ORM → camelCase(单点真相), Java: viewByShareCode, Java: viewByShareCode, Java: viewByShareCode, Java: viewByShareCode (+5 more)
|
||||
|
||||
### Community 163 - "Community 163"
|
||||
Cohesion: 0.33
|
||||
Nodes (10): bool, Redis, get_redis_client(), get_sync_redis_client(), 共享 Redis 客户端(同步:会话鉴权;异步:API 加密 nonce)。, 同步 Redis(auth 会话等,在线程池中调用)。, 异步 Redis(API 加密 nonce 等中间件)。, _redis_common_kwargs() (+2 more)
|
||||
|
||||
### Community 164 - "Community 164"
|
||||
Cohesion: 0.33
|
||||
Nodes (10): Any, int, Session, str, list_ethnics(), 民族码表 CRUD(全局 sys_ethnic), _row_to_dict(), 民族码表 sys_ethnic(国标 GB/T 3304,全局) (+2 more)
|
||||
|
||||
### Community 165 - "Community 165"
|
||||
Cohesion: 0.18
|
||||
Nodes (11): Java: statisticsStatus, Java: statisticsStatus, Java: statisticsStatus, Java: statisticsStatus, Java: statisticsStatus, Java: statisticsStatus, Java: statisticsStatus, Java: statisticsStatus (+3 more)
|
||||
|
||||
### Community 166 - "Community 166"
|
||||
Cohesion: 0.18
|
||||
Nodes (11): Java: statisticsTrend, Java: statisticsTrend, Java: statisticsTrend, Java: statisticsTrend, Java: statisticsTrend, Java: statisticsTrend, Java: statisticsTrend, Java: statisticsTrend (+3 more)
|
||||
|
||||
### Community 167 - "Community 167"
|
||||
Cohesion: 0.49
|
||||
Nodes (9): compare_data(), item_key(), load_portal_dicts(), load_sx_dicts(), main(), parse_insert_values(), Path, str (+1 more)
|
||||
@@ -845,60 +785,24 @@ Nodes (9): compare_data(), item_key(), load_portal_dicts(), load_sx_dicts(), mai
|
||||
Cohesion: 0.20
|
||||
Nodes (10): create_from_opportunity(), _opportunity_products_to_contract_products(), Java: createFromOpportunity — 返回合同 id, Java: createFromOpportunity — 返回合同 id, Java: createFromOpportunity — 返回合同 id, Java: createFromOpportunity — 返回合同 id, Java: createFromOpportunity — 返回合同 id, Java: createFromOpportunity — 返回合同 id (+2 more)
|
||||
|
||||
### Community 169 - "Community 169"
|
||||
Cohesion: 0.20
|
||||
Nodes (10): generate_barcode(), 生成唯一条码(纯数字:yyyyMMdd + 6位序号,如 20260606000001), 生成唯一条码(纯数字:yyyyMMdd + 6位序号,如 20260606000001), 生成唯一条码(纯数字:yyyyMMdd + 6位序号,如 20260606000001), 生成唯一条码(纯数字:yyyyMMdd + 6位序号,如 20260606000001), 取当前租户下 SXWL 前缀且后缀为纯数字的产品编号最大流水值, 生成唯一条码(纯数字:yyyyMMdd + 6位序号,如 20260606000001), 生成产品编号(格式:SXWL + 6位递增流水号,如 SXWL000001) (+2 more)
|
||||
|
||||
### Community 170 - "Community 170"
|
||||
Cohesion: 0.22
|
||||
Nodes (9): batch_submit_contract_approval(), Java: batchSubmitApproval, Java: batchSubmitApproval, Java: batchSubmitApproval, Java: batchSubmitApproval, Java: batchSubmitApproval, Java: batchSubmitApproval, Java: batchSubmitApproval (+1 more)
|
||||
|
||||
### Community 171 - "Community 171"
|
||||
Cohesion: 0.22
|
||||
Nodes (9): create_new_version(), Java: createNewVersion — 返回新报价单 id, Java: createNewVersion — 返回新报价单 id, Java: createNewVersion — 返回新报价单 id, Java: createNewVersion — 返回新报价单 id, Java: createNewVersion — 返回新报价单 id, Java: createNewVersion — 返回新报价单 id, Java: createNewVersion — 返回新报价单 id (+1 more)
|
||||
|
||||
### Community 172 - "Community 172"
|
||||
Cohesion: 0.40
|
||||
Nodes (5): bool, str, get_password_hash(), 验证密码(哈希非 bcrypt 或损坏时返回 False,避免抛错), verify_password()
|
||||
|
||||
### Community 173 - "Community 173"
|
||||
Cohesion: 0.20
|
||||
Nodes (7): _coerce_id(), OffsetItem, ReimburseApplyCreate, ReimburseApplyOut, ReimburseApplyUpdate, ReimburseApprovalCreate, ReimburseDetailCreate
|
||||
|
||||
### Community 174 - "Community 174"
|
||||
Cohesion: 0.33
|
||||
Nodes (6): _fill_contract_linked_count(), Java: fillContractLinkedCount, Java: fillContractLinkedCount, Java: fillContractLinkedCount, Java: fillContractLinkedCount, Java: fillContractLinkedCount
|
||||
|
||||
### Community 175 - "Community 175"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): Any, str, 与门户 JWT / apply_data_scope 所需的 user_info 字段对齐。
|
||||
|
||||
### Community 177 - "Community 177"
|
||||
Cohesion: 0.40
|
||||
Nodes (4): str, Config, format_api_error_message(), 将 HTTP/SQLAlchemy 等异常转为可展示的错误文案(避免 str([]) 空列表)。
|
||||
|
||||
### Community 178 - "Community 178"
|
||||
Cohesion: 0.40
|
||||
Nodes (3): AdvanceApplyCreate, AdvanceApplyUpdate, _coerce_optional_id()
|
||||
|
||||
### Community 179 - "Community 179"
|
||||
Cohesion: 0.83
|
||||
Nodes (3): _add_user_info_kwarg(), patch_file(), str
|
||||
|
||||
## Knowledge Gaps
|
||||
- **77 isolated node(s):** `Session`, `Request`, `bool`, `bool`, `Config` (+72 more)
|
||||
These have ≤1 connection - possible missing edges or undocumented components.
|
||||
- **3 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
||||
- **2 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
||||
|
||||
## Suggested Questions
|
||||
_Questions this graph is uniquely positioned to answer:_
|
||||
|
||||
- **Why does `Session` connect `Community 2` to `Community 0`, `Community 1`, `Community 3`, `Community 6`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 13`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 18`, `Community 19`, `Community 20`, `Community 21`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 33`, `Community 37`, `Community 38`, `Community 39`, `Community 40`, `Community 41`, `Community 42`, `Community 43`, `Community 44`, `Community 45`, `Community 46`, `Community 48`, `Community 49`, `Community 50`, `Community 51`, `Community 52`, `Community 53`, `Community 55`, `Community 56`, `Community 57`, `Community 58`, `Community 59`, `Community 60`, `Community 62`, `Community 64`, `Community 65`, `Community 67`, `Community 68`, `Community 70`, `Community 71`, `Community 72`, `Community 73`, `Community 74`, `Community 75`, `Community 76`, `Community 77`, `Community 78`, `Community 79`, `Community 84`, `Community 86`, `Community 87`, `Community 89`, `Community 90`, `Community 91`, `Community 93`, `Community 94`, `Community 95`, `Community 96`, `Community 97`, `Community 98`, `Community 100`, `Community 101`, `Community 104`, `Community 105`, `Community 114`, `Community 116`, `Community 117`, `Community 120`, `Community 124`, `Community 126`, `Community 129`, `Community 141`, `Community 142`, `Community 143`, `Community 146`, `Community 148`, `Community 150`, `Community 152`, `Community 153`, `Community 154`, `Community 155`, `Community 156`, `Community 158`, `Community 159`, `Community 162`, `Community 164`, `Community 165`, `Community 166`, `Community 168`, `Community 169`, `Community 170`, `Community 171`, `Community 174`?**
|
||||
_High betweenness centrality (0.257) - this node is a cross-community bridge._
|
||||
- **Why does `datetime` connect `Community 34` to `Community 0`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 19`, `Community 20`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 35`, `Community 36`, `Community 37`, `Community 38`, `Community 41`, `Community 45`, `Community 46`, `Community 47`, `Community 48`, `Community 49`, `Community 51`, `Community 52`, `Community 53`, `Community 54`, `Community 55`, `Community 56`, `Community 58`, `Community 61`, `Community 62`, `Community 64`, `Community 67`, `Community 69`, `Community 71`, `Community 74`, `Community 77`, `Community 78`, `Community 86`, `Community 87`, `Community 89`, `Community 90`, `Community 93`, `Community 94`, `Community 95`, `Community 96`, `Community 97`, `Community 101`, `Community 103`, `Community 104`, `Community 107`, `Community 114`, `Community 117`, `Community 118`, `Community 121`, `Community 124`, `Community 125`, `Community 127`, `Community 140`, `Community 143`, `Community 144`, `Community 145`, `Community 149`, `Community 151`, `Community 152`, `Community 159`, `Community 176`?**
|
||||
_High betweenness centrality (0.061) - this node is a cross-community bridge._
|
||||
- **Why does `BaseModel` connect `Community 47` to `Community 0`, `Community 1`, `Community 5`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 13`, `Community 142`, `Community 143`, `Community 18`, `Community 19`, `Community 20`, `Community 21`, `Community 149`, `Community 151`, `Community 22`, `Community 155`, `Community 28`, `Community 36`, `Community 37`, `Community 41`, `Community 43`, `Community 173`, `Community 46`, `Community 176`, `Community 178`, `Community 53`, `Community 57`, `Community 60`, `Community 62`, `Community 65`, `Community 74`, `Community 77`, `Community 118`, `Community 121`, `Community 123`, `Community 127`?**
|
||||
_High betweenness centrality (0.048) - this node is a cross-community bridge._
|
||||
- **Why does `Session` connect `Community 2` to `Community 0`, `Community 5`, `Community 6`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 13`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 18`, `Community 19`, `Community 21`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 28`, `Community 29`, `Community 30`, `Community 32`, `Community 33`, `Community 34`, `Community 36`, `Community 37`, `Community 38`, `Community 39`, `Community 40`, `Community 41`, `Community 42`, `Community 44`, `Community 45`, `Community 46`, `Community 47`, `Community 48`, `Community 49`, `Community 50`, `Community 51`, `Community 52`, `Community 53`, `Community 55`, `Community 56`, `Community 57`, `Community 58`, `Community 59`, `Community 60`, `Community 62`, `Community 63`, `Community 64`, `Community 65`, `Community 67`, `Community 68`, `Community 71`, `Community 72`, `Community 73`, `Community 74`, `Community 76`, `Community 77`, `Community 78`, `Community 79`, `Community 80`, `Community 84`, `Community 86`, `Community 87`, `Community 89`, `Community 90`, `Community 91`, `Community 93`, `Community 94`, `Community 96`, `Community 97`, `Community 98`, `Community 100`, `Community 101`, `Community 102`, `Community 104`, `Community 109`, `Community 113`, `Community 114`, `Community 116`, `Community 117`, `Community 120`, `Community 121`, `Community 124`, `Community 127`, `Community 129`, `Community 141`, `Community 142`, `Community 143`, `Community 146`, `Community 147`, `Community 148`, `Community 149`, `Community 150`, `Community 151`, `Community 152`, `Community 159`, `Community 168`?**
|
||||
_High betweenness centrality (0.252) - this node is a cross-community bridge._
|
||||
- **Why does `datetime` connect `Community 34` to `Community 0`, `Community 1`, `Community 2`, `Community 4`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 19`, `Community 20`, `Community 22`, `Community 23`, `Community 24`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 35`, `Community 37`, `Community 38`, `Community 40`, `Community 41`, `Community 43`, `Community 45`, `Community 46`, `Community 47`, `Community 48`, `Community 49`, `Community 51`, `Community 52`, `Community 53`, `Community 54`, `Community 55`, `Community 56`, `Community 58`, `Community 61`, `Community 62`, `Community 64`, `Community 67`, `Community 69`, `Community 70`, `Community 71`, `Community 73`, `Community 74`, `Community 75`, `Community 77`, `Community 78`, `Community 80`, `Community 86`, `Community 87`, `Community 89`, `Community 90`, `Community 93`, `Community 94`, `Community 95`, `Community 96`, `Community 97`, `Community 98`, `Community 103`, `Community 105`, `Community 107`, `Community 114`, `Community 117`, `Community 118`, `Community 124`, `Community 125`, `Community 126`, `Community 140`, `Community 144`, `Community 145`, `Community 148`, `Community 152`, `Community 159`, `Community 176`?**
|
||||
_High betweenness centrality (0.122) - this node is a cross-community bridge._
|
||||
- **Why does `BaseModel` connect `Community 47` to `Community 0`, `Community 5`, `Community 6`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 13`, `Community 142`, `Community 18`, `Community 19`, `Community 148`, `Community 21`, `Community 20`, `Community 22`, `Community 28`, `Community 37`, `Community 41`, `Community 46`, `Community 176`, `Community 53`, `Community 57`, `Community 63`, `Community 65`, `Community 67`, `Community 74`, `Community 75`, `Community 77`, `Community 98`, `Community 118`, `Community 123`?**
|
||||
_High betweenness centrality (0.052) - this node is a cross-community bridge._
|
||||
- **Are the 341 inferred relationships involving `str` (e.g. with `AdvanceApplyCreate` and `AdvanceApplyOut`) actually correct?**
|
||||
_`str` has 341 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 337 inferred relationships involving `Session` (e.g. with `AdvanceApplyCreate` and `AdvanceApplyOut`) actually correct?**
|
||||
@@ -906,4 +810,4 @@ _Questions this graph is uniquely positioned to answer:_
|
||||
- **Are the 225 inferred relationships involving `int` (e.g. with `AdvanceApplyCreate` and `AdvanceApplyOut`) actually correct?**
|
||||
_`int` has 225 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **What connects `定期 ping MySQL,避免远程库/NAT 回收空闲 TCP 后首请求长时间卡住。`, `数据库异常:返回 JSON 并保留 CORS 头,避免浏览器只报跨域错误`, `未捕获异常:统一 JSON 500,确保跨域场景下仍有 Access-Control-Allow-Origin` to the rest of the system?**
|
||||
_1551 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||
_1554 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||
backend/graphify-out/cache/ast/078ad784b087919a6e168850d07bcf66c44b8d6ffe7f90b34530dd44b93fb679.json
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_zlwu_work_00code_shanxia2_0_backend_app_services_pl_cert_required_service_py", "label": "pl_cert_required_service.py", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L1"}, {"id": "services_pl_cert_required_service_match_required_cert_name", "label": "match_required_cert_name()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L35"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L35"}, {"id": "bool", "label": "bool", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L35"}, {"id": "services_pl_cert_required_service_cert_row_complete", "label": "_cert_row_complete()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L44"}, {"id": "certrow", "label": "CertRow", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L44"}, {"id": "services_pl_cert_required_service_find_cert_for_required", "label": "_find_cert_for_required()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L67"}, {"id": "services_pl_cert_required_service_missing_field_labels", "label": "_missing_field_labels()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L87"}, {"id": "services_pl_cert_required_service_collect_required_cert_errors", "label": "collect_required_cert_errors()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L113"}, {"id": "services_pl_cert_required_service_get_required_personnel_cert_names", "label": "get_required_personnel_cert_names()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L138"}, {"id": "services_pl_cert_required_service_validate_personnel_type_role_compat", "label": "validate_personnel_type_role_compat()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L149"}, {"id": "services_pl_cert_required_service_validate_personnel_required_certs", "label": "validate_personnel_required_certs()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L160"}, {"id": "services_pl_cert_required_service_validate_self_vehicle_required_certs", "label": "validate_self_vehicle_required_certs()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L179"}, {"id": "services_pl_cert_required_service_validate_carrier_vehicle_required_certs", "label": "validate_carrier_vehicle_required_certs()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L203"}, {"id": "services_pl_cert_required_service_validate_vehicle_personnel_affiliation", "label": "validate_vehicle_personnel_affiliation()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L227"}, {"id": "session", "label": "Session", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L227"}, {"id": "vehiclepersonnelrow", "label": "VehiclePersonnelRow", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L227"}, {"id": "services_pl_cert_required_service_validate_vehicle_personnel_cert_links", "label": "validate_vehicle_personnel_cert_links()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L261"}, {"id": "services_pl_cert_required_service_validate_vehicle_save_certs", "label": "validate_vehicle_save_certs()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L300"}], "edges": [{"source": "users_zlwu_work_00code_shanxia2_0_backend_app_services_pl_cert_required_service_py", "target": "typing", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/woLine truncated
|
||||
backend/graphify-out/cache/ast/07991890446a106b2d520e5e3c65e27af90c13d00945516ef1ce9bdf2e389879.json
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_zlwu_work_00code_shanxia2_0_backend_app_services_pl_cert_required_service_py", "label": "pl_cert_required_service.py", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L1"}, {"id": "services_pl_cert_required_service_match_required_cert_name", "label": "match_required_cert_name()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L35"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L35"}, {"id": "bool", "label": "bool", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L35"}, {"id": "services_pl_cert_required_service_cert_row_complete", "label": "_cert_row_complete()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L44"}, {"id": "certrow", "label": "CertRow", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L44"}, {"id": "services_pl_cert_required_service_find_cert_for_required", "label": "_find_cert_for_required()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L63"}, {"id": "services_pl_cert_required_service_missing_field_labels", "label": "_missing_field_labels()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L83"}, {"id": "services_pl_cert_required_service_collect_required_cert_errors", "label": "collect_required_cert_errors()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L105"}, {"id": "services_pl_cert_required_service_get_required_personnel_cert_names", "label": "get_required_personnel_cert_names()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L130"}, {"id": "services_pl_cert_required_service_validate_personnel_type_role_compat", "label": "validate_personnel_type_role_compat()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L141"}, {"id": "services_pl_cert_required_service_validate_personnel_required_certs", "label": "validate_personnel_required_certs()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L152"}, {"id": "services_pl_cert_required_service_validate_self_vehicle_required_certs", "label": "validate_self_vehicle_required_certs()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L171"}, {"id": "services_pl_cert_required_service_validate_carrier_vehicle_required_certs", "label": "validate_carrier_vehicle_required_certs()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L195"}, {"id": "services_pl_cert_required_service_validate_vehicle_personnel_affiliation", "label": "validate_vehicle_personnel_affiliation()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L219"}, {"id": "session", "label": "Session", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L219"}, {"id": "vehiclepersonnelrow", "label": "VehiclePersonnelRow", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L219"}, {"id": "services_pl_cert_required_service_validate_vehicle_personnel_cert_links", "label": "validate_vehicle_personnel_cert_links()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L253"}, {"id": "services_pl_cert_required_service_validate_vehicle_save_certs", "label": "validate_vehicle_save_certs()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py", "source_location": "L292"}], "edges": [{"source": "users_zlwu_work_00code_shanxia2_0_backend_app_services_pl_cert_required_service_py", "target": "typing", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/woLine truncated
|
||||
backend/graphify-out/cache/ast/16751fcd542e209535216a0516d78b62eecb81732d7fe0f9ec051fdf811e93b6.json
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_zlwu_work_00code_shanxia2_0_backend_scripts_migrate_bx_data_py", "label": "migrate_bx_data.py", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L1"}, {"id": "scripts_migrate_bx_data_stepstats", "label": "StepStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L61"}, {"id": "scripts_migrate_bx_data_migrationstats", "label": "MigrationStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L68"}, {"id": "scripts_migrate_bx_data_migrationstats_step", "label": ".step()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L72"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L72"}, {"id": "scripts_migrate_bx_data_legacy_id_to_str", "label": "legacy_id_to_str()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L78"}, {"id": "any", "label": "Any", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L78"}, {"id": "scripts_migrate_bx_data_derive_source_url", "label": "derive_source_url()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L87"}, {"id": "scripts_migrate_bx_data_load_settings_env", "label": "load_settings_env()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L91"}, {"id": "scripts_migrate_bx_data_load_runtime_settings", "label": "load_runtime_settings()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L107"}, {"id": "scripts_migrate_bx_data_load_bx_user_mapping", "label": "load_bx_user_mapping()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L113"}, {"id": "path", "label": "Path", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L113"}, {"id": "int", "label": "int", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L113"}, {"id": "scripts_migrate_bx_data_fetch_portal_admin_id", "label": "fetch_portal_admin_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L131"}, {"id": "engine", "label": "Engine", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L131"}, {"id": "scripts_migrate_bx_data_map_bx_user_id", "label": "map_bx_user_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L139"}, {"id": "bool", "label": "bool", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L139"}, {"id": "scripts_migrate_bx_data_str_or_none", "label": "_str_or_none()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L167"}, {"id": "scripts_migrate_bx_data_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L176"}, {"id": "decimal", "label": "Decimal", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L176"}, {"id": "scripts_migrate_bx_data_parse_reimburse_meta", "label": "parse_reimburse_meta()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L182"}, {"id": "date", "label": "date", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L182"}, {"id": "scripts_migrate_bx_data_fetch_source_rows", "label": "fetch_source_rows()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L191"}, {"id": "scripts_migrate_bx_data_target_row_exists", "label": "target_row_exists()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py", "source_location": "L205"}, {"id": "scripts_migrate_bx_data_clear_portal_workflow", "label": "clear_portal_workflow()", "file_type": "code", "source_file": "/UserLine truncated
|
||||
backend/graphify-out/cache/ast/21a1fde9ec4fe47a56fd90b9153c795a000a4e364da74f8414e7c20c34e563b7.json
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "label": "test_pl_personnel_cert_required.py", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L1"}, {"id": "tests_test_pl_personnel_cert_required_test_match_driver_qualification_exact", "label": "test_match_driver_qualification_exact()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L11"}, {"id": "tests_test_pl_personnel_cert_required_test_match_escort_qualification_and_alias", "label": "test_match_escort_qualification_and_alias()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L17"}, {"id": "tests_test_pl_personnel_cert_required_test_required_names_by_personnel_type", "label": "test_required_names_by_personnel_type()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L23"}, {"id": "tests_test_pl_personnel_cert_required_test_both_requires_four_certs", "label": "test_both_requires_four_certs()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L41"}, {"id": "tests_test_pl_personnel_cert_required_test_escort_alias_counts_as_complete", "label": "test_escort_alias_counts_as_complete()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L54"}, {"id": "tests_test_pl_personnel_cert_required_rationale_1", "label": "pl_cert_required_service \u4eba\u5458\u5fc5\u5907\u8bc1\u4e66\u89c4\u5219\u6d4b\u8bd5\u3002", "file_type": "rationale", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L1"}], "edges": [{"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "app_services_pl_cert_required_service", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L4", "weight": 1.0}, {"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "tests_test_pl_personnel_cert_required_test_match_driver_qualification_exact", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L11", "weight": 1.0}, {"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "tests_test_pl_personnel_cert_required_test_match_escort_qualification_and_alias", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L17", "weight": 1.0}, {"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "tests_test_pl_personnel_cert_required_test_required_names_by_personnel_type", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L23", "weight": 1.0}, {"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "tests_test_pl_personnel_cert_required_test_both_requires_four_certs", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L41", "weight": 1.0}, {"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "tests_test_pl_personnel_cert_required_test_escort_alias_counts_as_complete", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L54", "weight": 1.0}, {"source": "tests_test_pl_personnel_cert_required_rationale_1", "target": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L1", "weight": 1.0}], "raw_calls": [{"caller_nid": "tests_test_pl_personnel_cert_required_test_match_driver_qualification_exact", "callee": "match_required_cert_name", "is_member_call": false, "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L12"}, {"caller_nid"Line truncated
|
||||
backend/graphify-out/cache/ast/4ac389eb6cb7437d4f5e8203d9908efec9836046ce8628a5e4be1f8b8ddd52cd.json
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_zlwu_work_00code_shanxia2_0_backend_scripts_migrate_crm_quote_py", "label": "migrate_crm_quote.py", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L1"}, {"id": "scripts_migrate_crm_quote_stepstats", "label": "StepStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L52"}, {"id": "scripts_migrate_crm_quote_migrationstats", "label": "MigrationStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L60"}, {"id": "scripts_migrate_crm_quote_migrationstats_step", "label": ".step()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L64"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L64"}, {"id": "scripts_migrate_crm_quote_legacy_id_to_str", "label": "legacy_id_to_str()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L70"}, {"id": "any", "label": "Any", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L70"}, {"id": "scripts_migrate_crm_quote_legacy_parent_id", "label": "legacy_parent_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L79"}, {"id": "scripts_migrate_crm_quote_derive_source_url", "label": "derive_source_url()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L90"}, {"id": "scripts_migrate_crm_quote_load_settings_env", "label": "load_settings_env()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L94"}, {"id": "scripts_migrate_crm_quote_load_runtime_settings", "label": "load_runtime_settings()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L110"}, {"id": "scripts_migrate_crm_quote_load_user_mapping", "label": "load_user_mapping()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L116"}, {"id": "path", "label": "Path", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L116"}, {"id": "int", "label": "int", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L116"}, {"id": "scripts_migrate_crm_quote_fetch_portal_admin_id", "label": "fetch_portal_admin_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L134"}, {"id": "engine", "label": "Engine", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L134"}, {"id": "scripts_migrate_crm_quote_resolve_portal_user_id", "label": "resolve_portal_user_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L142"}, {"id": "bool", "label": "bool", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L142"}, {"id": "scripts_migrate_crm_quote_load_oss_id_to_url", "label": "load_oss_id_to_url()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L167"}, {"id": "scripts_migrate_crm_quote_normalize_attachment_csv", "label": "normalize_attachment_csv()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L176"}, {"id": "scripts_migrate_crm_quote_normalize_pdf_url", "label": "normalize_pdf_url()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L197"}, {"id": "scripts_migrate_crm_quote_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L207"}, {"id": "decimal", "label": "Decimal", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_location": "L207"}, {"id": "scripts_migrate_crm_quote_str_or_none", "label": "_str_or_none()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py", "source_lLine truncated
|
||||
backend/graphify-out/cache/ast/72b84e497176bc63264c26d891c591c839f9dd9788988043c5752413c1b62a09.json
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_zlwu_work_00code_shanxia2_0_backend_scripts_migrate_crm_clue_py", "label": "migrate_crm_clue.py", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L1"}, {"id": "scripts_migrate_crm_clue_stepstats", "label": "StepStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L76"}, {"id": "scripts_migrate_crm_clue_migrationstats", "label": "MigrationStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L84"}, {"id": "scripts_migrate_crm_clue_migrationstats_step", "label": ".step()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L88"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L88"}, {"id": "scripts_migrate_crm_clue_legacy_id_to_str", "label": "legacy_id_to_str()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L94"}, {"id": "any", "label": "Any", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L94"}, {"id": "scripts_migrate_crm_clue_derive_source_url", "label": "derive_source_url()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L103"}, {"id": "scripts_migrate_crm_clue_load_settings_env", "label": "load_settings_env()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L107"}, {"id": "scripts_migrate_crm_clue_load_runtime_settings", "label": "load_runtime_settings()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L123"}, {"id": "scripts_migrate_crm_clue_load_user_mapping", "label": "load_user_mapping()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L129"}, {"id": "path", "label": "Path", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L129"}, {"id": "int", "label": "int", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L129"}, {"id": "scripts_migrate_crm_clue_fetch_portal_admin_id", "label": "fetch_portal_admin_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L147"}, {"id": "engine", "label": "Engine", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L147"}, {"id": "scripts_migrate_crm_clue_resolve_portal_user_id", "label": "resolve_portal_user_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L155"}, {"id": "scripts_migrate_crm_clue_load_oss_id_to_url", "label": "load_oss_id_to_url()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L177"}, {"id": "scripts_migrate_crm_clue_normalize_customer_type", "label": "normalize_customer_type()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L186"}, {"id": "scripts_migrate_crm_clue_normalize_follow_type", "label": "normalize_follow_type()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L203"}, {"id": "scripts_migrate_crm_clue_str_or_none", "label": "_str_or_none()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L208"}, {"id": "scripts_migrate_crm_clue_fetch_source_rows", "label": "fetch_source_rows()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L217"}, {"id": "bool", "label": "bool", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L217"}, {"id": "scripts_migrate_crm_clue_target_row_exists", "label": "target_row_exists()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py", "source_location": "L224"}, {"id": "scripts_migrate_crm_clue_transform_clue", "label": "transform_clue()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scLine truncated
|
||||
backend/graphify-out/cache/ast/a6269c8eeff19f4ae8ff7d22a3544ebc4a1858aaecd59583e6afd140a7fa766e.json
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_zlwu_work_00code_shanxia2_0_backend_scripts_migrate_crm_contract_py", "label": "migrate_crm_contract.py", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L1"}, {"id": "scripts_migrate_crm_contract_stepstats", "label": "StepStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L53"}, {"id": "scripts_migrate_crm_contract_migrationstats", "label": "MigrationStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L61"}, {"id": "scripts_migrate_crm_contract_migrationstats_step", "label": ".step()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L65"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L65"}, {"id": "scripts_migrate_crm_contract_legacy_id_to_str", "label": "legacy_id_to_str()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L71"}, {"id": "any", "label": "Any", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L71"}, {"id": "scripts_migrate_crm_contract_derive_source_url", "label": "derive_source_url()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L80"}, {"id": "scripts_migrate_crm_contract_load_settings_env", "label": "load_settings_env()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L84"}, {"id": "scripts_migrate_crm_contract_load_runtime_settings", "label": "load_runtime_settings()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L100"}, {"id": "scripts_migrate_crm_contract_load_user_mapping", "label": "load_user_mapping()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L106"}, {"id": "path", "label": "Path", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L106"}, {"id": "int", "label": "int", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L106"}, {"id": "scripts_migrate_crm_contract_fetch_portal_admin_id", "label": "fetch_portal_admin_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L124"}, {"id": "engine", "label": "Engine", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L124"}, {"id": "scripts_migrate_crm_contract_resolve_portal_user_id", "label": "resolve_portal_user_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L132"}, {"id": "bool", "label": "bool", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L132"}, {"id": "scripts_migrate_crm_contract_load_oss_id_to_url", "label": "load_oss_id_to_url()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L157"}, {"id": "scripts_migrate_crm_contract_normalize_attachment_csv", "label": "normalize_attachment_csv()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L166"}, {"id": "scripts_migrate_crm_contract_normalize_contract_attachment_files", "label": "normalize_contract_attachment_files()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L187"}, {"id": "scripts_migrate_crm_contract_normalize_file_path", "label": "normalize_file_path()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L210"}, {"id": "scripts_migrate_crm_contract_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L220"}, {"id": "decimal", "label": "Decimal", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py", "source_location": "L220"}, {"id": "scripts_migrate_crm_contLine truncated
|
||||
backend/graphify-out/cache/ast/a9a876816af12e43b3fa6b9dc748b74b7107f0cae590e68a2a789945617c620e.json
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_zlwu_work_00code_shanxia2_0_backend_app_api_pl_plan_py", "label": "plan.py", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L1"}, {"id": "pl_plan_generate_plan_no", "label": "_generate_plan_no()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L84"}, {"id": "session", "label": "Session", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L84"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L84"}, {"id": "pl_plan_format_subpack_slip_no", "label": "_format_subpack_slip_no()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L116"}, {"id": "int", "label": "int", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L116"}, {"id": "pl_plan_normalize_subpack_slip_no", "label": "_normalize_subpack_slip_no()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L120"}, {"id": "pl_plan_subpack_slip_no_seq", "label": "_subpack_slip_no_seq()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L145"}, {"id": "pl_plan_ensure_subpack_slip_no", "label": "_ensure_subpack_slip_no()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L153"}, {"id": "plplan", "label": "PlPlan", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L153"}, {"id": "pl_plan_determine_plan_type", "label": "_determine_plan_type()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L185"}, {"id": "pl_plan_get_plan_type_label", "label": "_get_plan_type_label()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L190"}, {"id": "pl_plan_generate_notify_message", "label": "_generate_notify_message()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L199"}, {"id": "pl_plan_list_plans", "label": "list_plans()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L220"}, {"id": "date", "label": "date", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L220"}, {"id": "dbusercontext", "label": "DbUserContext", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L220"}, {"id": "planlistresponse", "label": "PlanListResponse", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L220"}, {"id": "pl_plan_count_plans_by_contract", "label": "count_plans_by_contract()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L347"}, {"id": "pl_plan_create_plan", "label": "create_plan()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L375"}, {"id": "plancreate", "label": "PlanCreate", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L375"}, {"id": "planread", "label": "PlanRead", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L375"}, {"id": "pl_plan_create_plan_full", "label": "create_plan_full()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L458"}, {"id": "plancreatefull", "label": "PlanCreateFull", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L458"}, {"id": "planwithproducts", "label": "PlanWithProducts", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L458"}, {"id": "pl_plan_create_from_contract", "label": "create_from_contract()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L565"}, {"id": "createfromcontractrequest", "label": "CreateFromContractRequest", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py", "source_location": "L565"}, {"id": "pl_plan_get_plan", "label": "get_plan()", "file_type": "code",Line truncated
|
||||
backend/graphify-out/cache/ast/c4af77164dac9ba4195c3d239c9679ea367b92f5f7500139f3b59547525af24e.json
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_zlwu_work_00code_shanxia2_0_backend_scripts_migrate_crm_payment_invoice_py", "label": "migrate_crm_payment_invoice.py", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L1"}, {"id": "scripts_migrate_crm_payment_invoice_stepstats", "label": "StepStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L45"}, {"id": "scripts_migrate_crm_payment_invoice_migrationstats", "label": "MigrationStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L52"}, {"id": "scripts_migrate_crm_payment_invoice_migrationstats_step", "label": ".step()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L56"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L56"}, {"id": "scripts_migrate_crm_payment_invoice_legacy_id_to_str", "label": "legacy_id_to_str()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L62"}, {"id": "any", "label": "Any", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L62"}, {"id": "scripts_migrate_crm_payment_invoice_derive_source_url", "label": "derive_source_url()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L71"}, {"id": "scripts_migrate_crm_payment_invoice_load_settings_env", "label": "load_settings_env()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L75"}, {"id": "scripts_migrate_crm_payment_invoice_load_runtime_settings", "label": "load_runtime_settings()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L91"}, {"id": "scripts_migrate_crm_payment_invoice_load_user_mapping", "label": "load_user_mapping()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L97"}, {"id": "path", "label": "Path", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L97"}, {"id": "int", "label": "int", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L97"}, {"id": "scripts_migrate_crm_payment_invoice_fetch_portal_admin_id", "label": "fetch_portal_admin_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L115"}, {"id": "engine", "label": "Engine", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L115"}, {"id": "scripts_migrate_crm_payment_invoice_resolve_portal_user_id", "label": "resolve_portal_user_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L123"}, {"id": "scripts_migrate_crm_payment_invoice_str_or_none", "label": "_str_or_none()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L145"}, {"id": "scripts_migrate_crm_payment_invoice_fetch_source_rows", "label": "fetch_source_rows()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L154"}, {"id": "bool", "label": "bool", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L154"}, {"id": "scripts_migrate_crm_payment_invoice_count_source_rows", "label": "count_source_rows()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L161"}, {"id": "scripts_migrate_crm_payment_invoice_target_table_exists", "label": "target_table_exists()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "source_location": "L169"}, {"id": "scripts_migrate_crm_payment_invoice_target_row_exists", "label": "target_row_exists()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py", "sourceLine truncated
|
||||
backend/graphify-out/cache/ast/e89b3aa798794dc77085af5c4b880cdddcd2c0590c3cc3414f8a5389fd5f6d93.json
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "label": "test_pl_personnel_cert_required.py", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L1"}, {"id": "tests_test_pl_personnel_cert_required_test_match_driver_qualification_exact", "label": "test_match_driver_qualification_exact()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L11"}, {"id": "tests_test_pl_personnel_cert_required_test_match_escort_qualification_and_alias", "label": "test_match_escort_qualification_and_alias()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L17"}, {"id": "tests_test_pl_personnel_cert_required_test_required_names_by_personnel_type", "label": "test_required_names_by_personnel_type()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L23"}, {"id": "tests_test_pl_personnel_cert_required_test_both_requires_four_certs", "label": "test_both_requires_four_certs()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L41"}, {"id": "tests_test_pl_personnel_cert_required_test_escort_alias_counts_as_complete", "label": "test_escort_alias_counts_as_complete()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L54"}, {"id": "tests_test_pl_personnel_cert_required_test_cert_no_optional_for_required_slot", "label": "test_cert_no_optional_for_required_slot()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L66"}, {"id": "tests_test_pl_personnel_cert_required_rationale_1", "label": "pl_cert_required_service \u4eba\u5458\u5fc5\u5907\u8bc1\u4e66\u89c4\u5219\u6d4b\u8bd5\u3002", "file_type": "rationale", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L1"}], "edges": [{"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "app_services_pl_cert_required_service", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L4", "weight": 1.0}, {"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "tests_test_pl_personnel_cert_required_test_match_driver_qualification_exact", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L11", "weight": 1.0}, {"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "tests_test_pl_personnel_cert_required_test_match_escort_qualification_and_alias", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L17", "weight": 1.0}, {"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "tests_test_pl_personnel_cert_required_test_required_names_by_personnel_type", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L23", "weight": 1.0}, {"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "tests_test_pl_personnel_cert_required_test_both_requires_four_certs", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L41", "weight": 1.0}, {"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "tests_test_pl_personnel_cert_required_test_escort_alias_counts_as_complete", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L54", "weight": 1.0}, {"source": "users_zlwu_work_00code_shanxia2_0_backend_tests_test_pl_personnel_cert_required_py", "target": "tests_test_pl_personnel_cert_required_test_cert_no_optional_for_required_slot", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py", "source_location": "L66", "weight": 1.0}Line truncated
|
||||
backend/graphify-out/cache/ast/f98964806f32c3020bdd7d644d930760d6ea3ad5162d5f1d6125494263dd5598.json
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_zlwu_work_00code_shanxia2_0_backend_scripts_migrate_crm_opportunity_py", "label": "migrate_crm_opportunity.py", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L1"}, {"id": "scripts_migrate_crm_opportunity_stepstats", "label": "StepStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L64"}, {"id": "scripts_migrate_crm_opportunity_migrationstats", "label": "MigrationStats", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L72"}, {"id": "scripts_migrate_crm_opportunity_migrationstats_step", "label": ".step()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L76"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L76"}, {"id": "scripts_migrate_crm_opportunity_legacy_id_to_str", "label": "legacy_id_to_str()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L82"}, {"id": "any", "label": "Any", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L82"}, {"id": "scripts_migrate_crm_opportunity_derive_source_url", "label": "derive_source_url()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L91"}, {"id": "scripts_migrate_crm_opportunity_load_settings_env", "label": "load_settings_env()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L95"}, {"id": "scripts_migrate_crm_opportunity_load_runtime_settings", "label": "load_runtime_settings()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L111"}, {"id": "scripts_migrate_crm_opportunity_load_user_mapping", "label": "load_user_mapping()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L117"}, {"id": "path", "label": "Path", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L117"}, {"id": "int", "label": "int", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L117"}, {"id": "scripts_migrate_crm_opportunity_fetch_portal_admin_id", "label": "fetch_portal_admin_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L135"}, {"id": "engine", "label": "Engine", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L135"}, {"id": "scripts_migrate_crm_opportunity_resolve_portal_user_id", "label": "resolve_portal_user_id()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L143"}, {"id": "scripts_migrate_crm_opportunity_load_oss_id_to_url", "label": "load_oss_id_to_url()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L165"}, {"id": "scripts_migrate_crm_opportunity_normalize_follow_type", "label": "normalize_follow_type()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L174"}, {"id": "scripts_migrate_crm_opportunity_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L179"}, {"id": "decimal", "label": "Decimal", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L179"}, {"id": "scripts_migrate_crm_opportunity_str_or_none", "label": "_str_or_none()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L185"}, {"id": "scripts_migrate_crm_opportunity_fetch_source_rows", "label": "fetch_source_rows()", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py", "source_location": "L194"}, {"id": "bool", "label": "bool", "file_type": "code", "source_file": "/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.pyLine truncated
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"/Users/zlwu/work/00code/shanxia2.0/backend/start-prod.sh":{"size":7357,"mtime_ns":1782639355476060453,"hash":"ca89869446be74a2bf2367b3b28f448580220859a39a84ad9613ac5fe35a8433"},"/Users/zlwu/work/00code/shanxia2.0/backend/start.sh":{"size":9548,"mtime_ns":1780114661446983244,"hash":"4d632863e8a0cd81194b491d83a0218a4157435ae812dec76a6f6197b4d48e57"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/__init__.py":{"size":21,"mtime_ns":1780113982281973984,"hash":"60a04ff08fd97084e83ea809fd13feda6d2848be20ebf309e31fc1dad7523230"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/main.py":{"size":6280,"mtime_ns":1782790852770448643,"hash":"8f9da799977bee7134d87a26ff8434ac5ef8eabb0b7368dd537eee49ad7fd00b"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/tasks/__init__.py":{"size":2207,"mtime_ns":1783208067881286091,"hash":"313e6da0e91d743ce891dd283458c79b50b24c4d909dc96ca7b3fd9d2bfa5013"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/auth.py":{"size":7457,"mtime_ns":1782790841500516545,"hash":"34bac56e1c2cb6215f4b5fa2dc32d77d4b4abca51428819eebf4afd269cc51cf"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/api_crypto.py":{"size":1870,"mtime_ns":1780108930724444498,"hash":"c04b748aea86890a5971f749523c7b17dbad1ddd6f9f7f07a5679d159c984e33"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/login_crypto.py":{"size":3858,"mtime_ns":1780108930725155710,"hash":"b82d51afabf2293a9cb1fb2e5f994c383948e7f47ea95fe674686b4f3f3342b1"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/config.py":{"size":6716,"mtime_ns":1783761682571576393,"hash":"bbe64081c9790941eb2fa8f9c18ee39daf151068b3503f1fdb74c2cb9f7b5b45"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/wechat_pay.py":{"size":23585,"mtime_ns":1780108930725768130,"hash":"3d52265ce65d21e7103f94afa1e8547aee0823b5ea6d65c50317436ac81fb4fc"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/api_request_log_middleware.py":{"size":11971,"mtime_ns":1782701669198208175,"hash":"0b84c32828939e6102bb3647691fa8f04b1f68e0e0e9f28127374cc44e19a11c"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/database.py":{"size":1510,"mtime_ns":1782790847265601586,"hash":"8bc9c8ae62e2be2c6920036582ba448dfcd1711c41cebb62274ff6bc6ee14b0b"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/security.py":{"size":728,"mtime_ns":1780108930725470004,"hash":"df0f01115064f7b8de1c81dbe9a6db39360c236610b68c33b3234a51d7f0025b"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/request_payload.py":{"size":2842,"mtime_ns":1780108930725350836,"hash":"e9937151530ab1417ef297aef59111977725cf90be2a8fa76c00a0618789aba0"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/__init__.py":{"size":61,"mtime_ns":1780108930724312414,"hash":"3dd1842ee59b0c804176b03b4b8a323bd4a252b7feb1bbc32db64f3a8928570e"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/response.py":{"size":1824,"mtime_ns":1780108930725412462,"hash":"f1739352d65ea8287d76e282a59553aa8d63c97e35764c64ac378aa5bd9c347e"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/menu_guard.py":{"size":1611,"mtime_ns":1780108930725223002,"hash":"3e26077288c3620a4780038b891a326206b45bffe00aca545bdae30172487235"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/db_collation.py":{"size":548,"mtime_ns":1780108930725025043,"hash":"0c680e25a18244ca839a7de6ed1f4313b33bc8da118d89c463aee1b6af00c6f9"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/context.py":{"size":421,"mtime_ns":1780108930724824458,"hash":"83a10aee67162374993c10a30bf8bb8bd9c4b35cf48f42c832415ccebd91660f"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/utils.py":{"size":1498,"mtime_ns":1780108930725607296,"hash":"09323693661c1d4560458b86a954128ccff82bbaf6522da0b44f24da99ddf9ea"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/storage.py":{"size":14141,"mtime_ns":1782855136810943216,"hash":"3ae2c413c10898a8adb3d6773870bafbfbc18c739c10e0e8b4f765b4b5ca6c08"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/order_status_compat.py":{"size":2828,"mtime_ns":1780108930725284669,"hash":"5349e5a0745ee6734c4a995337779307adefc46f453906171988a77de2081540"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/exceptions.py":{"size":4946,"mtime_ns":1780108930725084335,"hash":"79c997d964bca1a4f12f2b92fb1f181fdb9e2b3cf72eae39f4cc164d23794fd7"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/data_scope.py":{"size":8043,"mtime_ns":1782648925694296304,"hash":"626dff86937e5cacec634ecbc61cd53d3763d760223a1d4ec7cd11f64e59a220"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/admin_request_json.py":{"size":2669,"mtime_ns":1780108930724378914,"hash":"4f68b3cf84291e7bddad6ecf4bb4d29ca5e1ec246a9f7f9c4cf5909d0ec1174a"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/api_crypto_middleware.py":{"size":10876,"mtime_ns":1782790001926627098,"hash":"b39f128b6612589ea6ac5babd30752e9585b3af07b82bb1ad53c9e3c0d90816f"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/wechat_message.py":{"size":11194,"mtime_ns":1780108930725684255,"hash":"5086070deb14d99d1a69e419b2299ec4Line truncated
|
||||
{"/Users/zlwu/work/00code/shanxia2.0/backend/start-prod.sh":{"size":7357,"mtime_ns":1782639355476060453,"hash":"ca89869446be74a2bf2367b3b28f448580220859a39a84ad9613ac5fe35a8433"},"/Users/zlwu/work/00code/shanxia2.0/backend/start.sh":{"size":9548,"mtime_ns":1780114661446983244,"hash":"4d632863e8a0cd81194b491d83a0218a4157435ae812dec76a6f6197b4d48e57"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/__init__.py":{"size":21,"mtime_ns":1780113982281973984,"hash":"60a04ff08fd97084e83ea809fd13feda6d2848be20ebf309e31fc1dad7523230"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/main.py":{"size":6280,"mtime_ns":1782790852770448643,"hash":"8f9da799977bee7134d87a26ff8434ac5ef8eabb0b7368dd537eee49ad7fd00b"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/tasks/__init__.py":{"size":2207,"mtime_ns":1783208067881286091,"hash":"313e6da0e91d743ce891dd283458c79b50b24c4d909dc96ca7b3fd9d2bfa5013"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/auth.py":{"size":7457,"mtime_ns":1782790841500516545,"hash":"34bac56e1c2cb6215f4b5fa2dc32d77d4b4abca51428819eebf4afd269cc51cf"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/api_crypto.py":{"size":1870,"mtime_ns":1780108930724444498,"hash":"c04b748aea86890a5971f749523c7b17dbad1ddd6f9f7f07a5679d159c984e33"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/login_crypto.py":{"size":3858,"mtime_ns":1780108930725155710,"hash":"b82d51afabf2293a9cb1fb2e5f994c383948e7f47ea95fe674686b4f3f3342b1"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/config.py":{"size":6716,"mtime_ns":1783761682571576393,"hash":"bbe64081c9790941eb2fa8f9c18ee39daf151068b3503f1fdb74c2cb9f7b5b45"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/wechat_pay.py":{"size":23585,"mtime_ns":1780108930725768130,"hash":"3d52265ce65d21e7103f94afa1e8547aee0823b5ea6d65c50317436ac81fb4fc"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/api_request_log_middleware.py":{"size":11971,"mtime_ns":1782701669198208175,"hash":"0b84c32828939e6102bb3647691fa8f04b1f68e0e0e9f28127374cc44e19a11c"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/database.py":{"size":1510,"mtime_ns":1782790847265601586,"hash":"8bc9c8ae62e2be2c6920036582ba448dfcd1711c41cebb62274ff6bc6ee14b0b"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/security.py":{"size":728,"mtime_ns":1780108930725470004,"hash":"df0f01115064f7b8de1c81dbe9a6db39360c236610b68c33b3234a51d7f0025b"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/request_payload.py":{"size":2842,"mtime_ns":1780108930725350836,"hash":"e9937151530ab1417ef297aef59111977725cf90be2a8fa76c00a0618789aba0"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/__init__.py":{"size":61,"mtime_ns":1780108930724312414,"hash":"3dd1842ee59b0c804176b03b4b8a323bd4a252b7feb1bbc32db64f3a8928570e"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/response.py":{"size":1824,"mtime_ns":1780108930725412462,"hash":"f1739352d65ea8287d76e282a59553aa8d63c97e35764c64ac378aa5bd9c347e"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/menu_guard.py":{"size":1611,"mtime_ns":1780108930725223002,"hash":"3e26077288c3620a4780038b891a326206b45bffe00aca545bdae30172487235"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/db_collation.py":{"size":548,"mtime_ns":1780108930725025043,"hash":"0c680e25a18244ca839a7de6ed1f4313b33bc8da118d89c463aee1b6af00c6f9"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/context.py":{"size":421,"mtime_ns":1780108930724824458,"hash":"83a10aee67162374993c10a30bf8bb8bd9c4b35cf48f42c832415ccebd91660f"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/utils.py":{"size":1498,"mtime_ns":1780108930725607296,"hash":"09323693661c1d4560458b86a954128ccff82bbaf6522da0b44f24da99ddf9ea"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/storage.py":{"size":14141,"mtime_ns":1782855136810943216,"hash":"3ae2c413c10898a8adb3d6773870bafbfbc18c739c10e0e8b4f765b4b5ca6c08"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/order_status_compat.py":{"size":2828,"mtime_ns":1780108930725284669,"hash":"5349e5a0745ee6734c4a995337779307adefc46f453906171988a77de2081540"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/exceptions.py":{"size":4946,"mtime_ns":1780108930725084335,"hash":"79c997d964bca1a4f12f2b92fb1f181fdb9e2b3cf72eae39f4cc164d23794fd7"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/data_scope.py":{"size":8043,"mtime_ns":1782648925694296304,"hash":"626dff86937e5cacec634ecbc61cd53d3763d760223a1d4ec7cd11f64e59a220"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/admin_request_json.py":{"size":2669,"mtime_ns":1780108930724378914,"hash":"4f68b3cf84291e7bddad6ecf4bb4d29ca5e1ec246a9f7f9c4cf5909d0ec1174a"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/api_crypto_middleware.py":{"size":10876,"mtime_ns":1782790001926627098,"hash":"b39f128b6612589ea6ac5babd30752e9585b3af07b82bb1ad53c9e3c0d90816f"},"/Users/zlwu/work/00code/shanxia2.0/backend/app/core/wechat_message.py":{"size":11194,"mtime_ns":1780108930725684255,"hash":"5086070deb14d99d1a69e419b2299ec4Line truncated
|
||||
+12952
-1762
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,85 @@
|
||||
-- 人员从业资格证拆分:cert_name 重命名(可重复执行)
|
||||
-- 前置 spec: docs/superpowers/specs/2026-07-13-pl-personnel-cert-split-design.md
|
||||
|
||||
-- 1) 押运员证 → 押运员从业资格证(全部 personnel 证书)
|
||||
UPDATE pl_cert c
|
||||
INNER JOIN pl_personnel p ON p.id = c.owner_id AND p.del_flag = 0
|
||||
SET c.cert_name = '押运员从业资格证',
|
||||
c.update_time = NOW()
|
||||
WHERE c.del_flag = 0
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.cert_name = '押运员证';
|
||||
|
||||
-- 2) 泛称从业资格证 → 驾驶员从业资格证(driver / both)
|
||||
UPDATE pl_cert c
|
||||
INNER JOIN pl_personnel p ON p.id = c.owner_id AND p.del_flag = 0
|
||||
SET c.cert_name = '驾驶员从业资格证',
|
||||
c.update_time = NOW()
|
||||
WHERE c.del_flag = 0
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.cert_name = '从业资格证'
|
||||
AND p.personnel_type IN ('driver', 'both');
|
||||
|
||||
-- 3) 泛称从业资格证 → 押运员从业资格证(escort)
|
||||
UPDATE pl_cert c
|
||||
INNER JOIN pl_personnel p ON p.id = c.owner_id AND p.del_flag = 0
|
||||
SET c.cert_name = '押运员从业资格证',
|
||||
c.update_time = NOW()
|
||||
WHERE c.del_flag = 0
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.cert_name = '从业资格证'
|
||||
AND p.personnel_type = 'escort';
|
||||
|
||||
-- 4) both 人员:若迁移后仍缺驾/押任一从业证,供运营补录(验证查询,不修改数据)
|
||||
SELECT
|
||||
p.id AS personnel_id,
|
||||
p.personnel_name,
|
||||
p.personnel_type,
|
||||
GROUP_CONCAT(c.cert_name ORDER BY c.cert_name SEPARATOR '、') AS cert_names
|
||||
FROM pl_personnel p
|
||||
LEFT JOIN pl_cert c
|
||||
ON c.owner_id = p.id
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.del_flag = 0
|
||||
WHERE p.del_flag = 0
|
||||
AND p.personnel_type = 'both'
|
||||
GROUP BY p.id, p.personnel_name, p.personnel_type
|
||||
HAVING SUM(CASE WHEN c.cert_name IN ('驾驶员从业资格证') THEN 1 ELSE 0 END) = 0
|
||||
OR SUM(CASE WHEN c.cert_name IN ('押运员从业资格证', '押运员证') THEN 1 ELSE 0 END) = 0;
|
||||
|
||||
-- 5) 危化品从业资格证:不自动迁移(人工清单)
|
||||
SELECT
|
||||
p.id AS personnel_id,
|
||||
p.personnel_name,
|
||||
p.personnel_type,
|
||||
c.id AS cert_id,
|
||||
c.cert_name
|
||||
FROM pl_cert c
|
||||
INNER JOIN pl_personnel p ON p.id = c.owner_id AND p.del_flag = 0
|
||||
WHERE c.del_flag = 0
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.cert_name = '危化品从业资格证';
|
||||
|
||||
-- 6) both + 仍保留泛称「从业资格证」的歧义记录(需人工处理,不自动改)
|
||||
SELECT
|
||||
p.id AS personnel_id,
|
||||
p.personnel_name,
|
||||
c.id AS cert_id,
|
||||
c.cert_name
|
||||
FROM pl_cert c
|
||||
INNER JOIN pl_personnel p ON p.id = c.owner_id AND p.del_flag = 0
|
||||
WHERE c.del_flag = 0
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.cert_name = '从业资格证'
|
||||
AND p.personnel_type = 'both';
|
||||
|
||||
-- 7) 字典 pl_cert_name 增量(可选,可重复执行)
|
||||
INSERT INTO sys_dict_data (id, dict_label, dict_value, tag_type, dict_type, tenant_no, order_num, del_flag, create_time, update_time)
|
||||
SELECT 'PL_CERT_DRIVER_QUAL', '驾驶员从业资格证', '驾驶员从业资格证', 'primary', 'pl_cert_name', 'shanxia2.0', 6, 0, NOW(), NOW()
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_dict_data WHERE id = 'PL_CERT_DRIVER_QUAL');
|
||||
|
||||
INSERT INTO sys_dict_data (id, dict_label, dict_value, tag_type, dict_type, tenant_no, order_num, del_flag, create_time, update_time)
|
||||
SELECT 'PL_CERT_ESCORT_QUAL', '押运员从业资格证', '押运员从业资格证', 'warning', 'pl_cert_name', 'shanxia2.0', 7, 0, NOW(), NOW()
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_dict_data WHERE id = 'PL_CERT_ESCORT_QUAL');
|
||||
@@ -0,0 +1,75 @@
|
||||
"""pl_cert_required_service 人员必备证书规则测试。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from app.services.pl_cert_required_service import (
|
||||
collect_required_cert_errors,
|
||||
get_required_personnel_cert_names,
|
||||
match_required_cert_name,
|
||||
)
|
||||
|
||||
|
||||
def test_match_driver_qualification_exact():
|
||||
assert match_required_cert_name("驾驶员从业资格证", "驾驶员从业资格证") is True
|
||||
assert match_required_cert_name("从业资格证", "驾驶员从业资格证") is False
|
||||
assert match_required_cert_name("危化品从业资格证", "驾驶员从业资格证") is False
|
||||
|
||||
|
||||
def test_match_escort_qualification_and_alias():
|
||||
assert match_required_cert_name("押运员从业资格证", "押运员从业资格证") is True
|
||||
assert match_required_cert_name("押运员证", "押运员从业资格证") is True
|
||||
assert match_required_cert_name("从业资格证", "押运员从业资格证") is False
|
||||
|
||||
|
||||
def test_required_names_by_personnel_type():
|
||||
assert get_required_personnel_cert_names("driver") == (
|
||||
"身份证",
|
||||
"驾驶证",
|
||||
"驾驶员从业资格证",
|
||||
)
|
||||
assert get_required_personnel_cert_names("escort") == (
|
||||
"身份证",
|
||||
"押运员从业资格证",
|
||||
)
|
||||
assert get_required_personnel_cert_names("both") == (
|
||||
"身份证",
|
||||
"驾驶证",
|
||||
"驾驶员从业资格证",
|
||||
"押运员从业资格证",
|
||||
)
|
||||
|
||||
|
||||
def test_both_requires_four_certs():
|
||||
cert_rows = [
|
||||
{"certName": "身份证", "certNo": "1", "expireDate": "2030-01-01", "attachmentUrls": "http://a"},
|
||||
{"certName": "驾驶证", "certNo": "2", "expireDate": "2030-01-01", "attachmentUrls": "http://b"},
|
||||
{"certName": "驾驶员从业资格证", "certNo": "3", "expireDate": "2030-01-01", "attachmentUrls": "http://c"},
|
||||
]
|
||||
errors = collect_required_cert_errors(
|
||||
cert_rows,
|
||||
get_required_personnel_cert_names("both"),
|
||||
)
|
||||
assert any("押运员从业资格证" in e for e in errors)
|
||||
|
||||
|
||||
def test_escort_alias_counts_as_complete():
|
||||
cert_rows = [
|
||||
{"certName": "身份证", "expireDate": "2030-01-01", "attachmentUrls": "http://a"},
|
||||
{"certName": "押运员证", "expireDate": "2030-01-01", "attachmentUrls": "http://b"},
|
||||
]
|
||||
errors = collect_required_cert_errors(
|
||||
cert_rows,
|
||||
get_required_personnel_cert_names("escort"),
|
||||
)
|
||||
assert errors == []
|
||||
|
||||
|
||||
def test_cert_no_optional_for_required_slot():
|
||||
cert_rows = [
|
||||
{"certName": "身份证", "expireDate": "2030-01-01", "attachmentUrls": "http://a"},
|
||||
{"certName": "押运员从业资格证", "expireDate": "2030-01-01", "attachmentUrls": "http://b"},
|
||||
]
|
||||
errors = collect_required_cert_errors(
|
||||
cert_rows,
|
||||
get_required_personnel_cert_names("escort"),
|
||||
)
|
||||
assert errors == []
|
||||
@@ -0,0 +1,524 @@
|
||||
# 人员从业资格证拆分 — Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 将驾押人员必备证书从泛称「从业资格证」拆分为「驾驶员从业资格证」与「押运员从业资格证」;兼岗须 4 证齐全;徽章显示「业」「押」;押运员证作为押运员从业资格证别名。
|
||||
|
||||
**Architecture:** 规则单一来源为 `pl-personnel-cert.ts`(前端)与 `pl_cert_required_service.py`(后端),二者常数与 `match*CertName` 保持镜像;`both` 类型返回独立 4 项列表;历史数据先跑迁移 SQL 再部署代码。
|
||||
|
||||
**Tech Stack:** FastAPI + SQLAlchemy;Vue 3 + Element Plus;MySQL 5.7
|
||||
|
||||
**Status:** ✅ 已实现(2026-07-13)
|
||||
|
||||
---
|
||||
|
||||
## 文件结构
|
||||
|
||||
| 操作 | 文件 | 职责 |
|
||||
|------|------|------|
|
||||
| Create | `backend/scripts/migration_20260713_pl_personnel_cert_split.sql` | 历史 cert_name 重命名 + both 待人工清单查询 |
|
||||
| Create | `backend/tests/test_pl_personnel_cert_required.py` | 必备规则与匹配单元测试 |
|
||||
| Modify | `backend/app/services/pl_cert_required_service.py` | 后端必备常数、`both` 合并、`match_required_cert_name` |
|
||||
| Modify | `web-admin/src/utils/pl-personnel-cert.ts` | 前端规则源(与后端对齐) |
|
||||
| Modify | `web-admin/src/views/pl/personnel/index.vue` | 证书下拉选项 |
|
||||
| Modify | `docs/superpowers/specs/2026-07-12-pl-required-cert-slots-design.md` | 废止 D5/D6,指向新 spec |
|
||||
| Modify | `docs/sql/shanxia2.0.sql` | 字典 `pl_cert_name` 增量(可选,见 Task 6) |
|
||||
| 回归 | `web-admin/src/components/business/pl-personnel-cert-badges/index.vue` | 无需改代码,验徽章 |
|
||||
| 回归 | `web-admin/src/views/pl/self-vehicle/index.vue` | 关联人员证书校验 |
|
||||
| 回归 | `web-admin/src/views/pl/vehicle/index.vue` | 同上 |
|
||||
|
||||
---
|
||||
|
||||
## 部署顺序(强制)
|
||||
|
||||
```
|
||||
1. 执行 migration_20260713_pl_personnel_cert_split.sql
|
||||
2. 处理 both + 单条「从业资格证」人工清单
|
||||
3. 部署 backend + web-admin
|
||||
4. 按 §验收步骤 走查
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 后端单元测试(TDD 先行)
|
||||
|
||||
**Files:**
|
||||
- Create: `backend/tests/test_pl_personnel_cert_required.py`
|
||||
|
||||
- [ ] **Step 1: 编写失败测试**
|
||||
|
||||
```python
|
||||
"""pl_cert_required_service 人员必备证书规则测试。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from app.services.pl_cert_required_service import (
|
||||
collect_required_cert_errors,
|
||||
get_required_personnel_cert_names,
|
||||
match_required_cert_name,
|
||||
)
|
||||
|
||||
|
||||
def test_match_driver_qualification_exact():
|
||||
assert match_required_cert_name("驾驶员从业资格证", "驾驶员从业资格证") is True
|
||||
assert match_required_cert_name("从业资格证", "驾驶员从业资格证") is False
|
||||
assert match_required_cert_name("危化品从业资格证", "驾驶员从业资格证") is False
|
||||
|
||||
|
||||
def test_match_escort_qualification_and_alias():
|
||||
assert match_required_cert_name("押运员从业资格证", "押运员从业资格证") is True
|
||||
assert match_required_cert_name("押运员证", "押运员从业资格证") is True
|
||||
assert match_required_cert_name("从业资格证", "押运员从业资格证") is False
|
||||
|
||||
|
||||
def test_required_names_by_personnel_type():
|
||||
assert get_required_personnel_cert_names("driver") == (
|
||||
"身份证",
|
||||
"驾驶证",
|
||||
"驾驶员从业资格证",
|
||||
)
|
||||
assert get_required_personnel_cert_names("escort") == (
|
||||
"身份证",
|
||||
"押运员从业资格证",
|
||||
)
|
||||
assert get_required_personnel_cert_names("both") == (
|
||||
"身份证",
|
||||
"驾驶证",
|
||||
"驾驶员从业资格证",
|
||||
"押运员从业资格证",
|
||||
)
|
||||
|
||||
|
||||
def test_both_requires_four_certs():
|
||||
cert_rows = [
|
||||
{"certName": "身份证", "certNo": "1", "expireDate": "2030-01-01", "attachmentUrls": "http://a"},
|
||||
{"certName": "驾驶证", "certNo": "2", "expireDate": "2030-01-01", "attachmentUrls": "http://b"},
|
||||
{"certName": "驾驶员从业资格证", "certNo": "3", "expireDate": "2030-01-01", "attachmentUrls": "http://c"},
|
||||
]
|
||||
errors = collect_required_cert_errors(
|
||||
cert_rows,
|
||||
get_required_personnel_cert_names("both"),
|
||||
)
|
||||
assert any("押运员从业资格证" in e for e in errors)
|
||||
|
||||
|
||||
def test_escort_alias_counts_as_complete():
|
||||
cert_rows = [
|
||||
{"certName": "身份证", "certNo": "1", "expireDate": "2030-01-01", "attachmentUrls": "http://a"},
|
||||
{"certName": "押运员证", "certNo": "2", "expireDate": "2030-01-01", "attachmentUrls": "http://b"},
|
||||
]
|
||||
errors = collect_required_cert_errors(
|
||||
cert_rows,
|
||||
get_required_personnel_cert_names("escort"),
|
||||
)
|
||||
assert errors == []
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 运行测试确认失败**
|
||||
|
||||
```bash
|
||||
cd backend && source venv/bin/activate && pytest tests/test_pl_personnel_cert_required.py -v
|
||||
```
|
||||
|
||||
Expected: FAIL(常数仍为「从业资格证」、`both` 仅 3 项)
|
||||
|
||||
- [ ] **Step 3: Commit 测试文件**
|
||||
|
||||
```bash
|
||||
git add backend/tests/test_pl_personnel_cert_required.py
|
||||
git commit -m "test: add personnel cert split required rules tests"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: 后端规则实现
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/services/pl_cert_required_service.py`
|
||||
|
||||
- [ ] **Step 1: 更新常数与匹配函数**
|
||||
|
||||
将第 22–39 行替换为:
|
||||
|
||||
```python
|
||||
PERSONNEL_DRIVER_REQUIRED = ("身份证", "驾驶证", "驾驶员从业资格证")
|
||||
PERSONNEL_ESCORT_REQUIRED = ("身份证", "押运员从业资格证")
|
||||
PERSONNEL_BOTH_REQUIRED = (
|
||||
"身份证",
|
||||
"驾驶证",
|
||||
"驾驶员从业资格证",
|
||||
"押运员从业资格证",
|
||||
)
|
||||
|
||||
|
||||
def match_required_cert_name(actual_name: str | None, required_name: str) -> bool:
|
||||
name = (actual_name or "").strip()
|
||||
if not name:
|
||||
return False
|
||||
if required_name == "押运员从业资格证":
|
||||
return name == "押运员从业资格证" or name == "押运员证"
|
||||
return name == required_name
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 更新 `get_required_personnel_cert_names`**
|
||||
|
||||
将第 136–142 行替换为:
|
||||
|
||||
```python
|
||||
def get_required_personnel_cert_names(personnel_type: str | None) -> tuple[str, ...]:
|
||||
ptype = (personnel_type or "").strip()
|
||||
if ptype == "escort":
|
||||
return PERSONNEL_ESCORT_REQUIRED
|
||||
if ptype == "driver":
|
||||
return PERSONNEL_DRIVER_REQUIRED
|
||||
if ptype == "both":
|
||||
return PERSONNEL_BOTH_REQUIRED
|
||||
return PERSONNEL_BOTH_REQUIRED
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 运行测试**
|
||||
|
||||
```bash
|
||||
cd backend && pytest tests/test_pl_personnel_cert_required.py -v
|
||||
```
|
||||
|
||||
Expected: PASS(5 passed)
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/services/pl_cert_required_service.py
|
||||
git commit -m "feat(pl): split driver and escort qualification cert requirements"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: 前端规则源
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/utils/pl-personnel-cert.ts`
|
||||
|
||||
- [ ] **Step 1: 更新常数(第 5–11 行)**
|
||||
|
||||
```typescript
|
||||
export const PL_PERSONNEL_DRIVER_REQUIRED_CERT_NAMES = [
|
||||
'身份证',
|
||||
'驾驶证',
|
||||
'驾驶员从业资格证'
|
||||
] as const
|
||||
|
||||
export const PL_PERSONNEL_ESCORT_REQUIRED_CERT_NAMES = [
|
||||
'身份证',
|
||||
'押运员从业资格证'
|
||||
] as const
|
||||
|
||||
export const PL_PERSONNEL_BOTH_REQUIRED_CERT_NAMES = [
|
||||
'身份证',
|
||||
'驾驶证',
|
||||
'驾驶员从业资格证',
|
||||
'押运员从业资格证'
|
||||
] as const
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 更新 `getRequiredPersonnelCertNamesByType`(第 66–73 行)**
|
||||
|
||||
```typescript
|
||||
export function getRequiredPersonnelCertNamesByType(
|
||||
personnelType?: string | null
|
||||
): readonly string[] {
|
||||
if (personnelType === 'escort') {
|
||||
return PL_PERSONNEL_ESCORT_REQUIRED_CERT_NAMES
|
||||
}
|
||||
if (personnelType === 'driver') {
|
||||
return PL_PERSONNEL_DRIVER_REQUIRED_CERT_NAMES
|
||||
}
|
||||
return PL_PERSONNEL_BOTH_REQUIRED_CERT_NAMES
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 更新 `matchRequiredCertName`(第 114–128 行)**
|
||||
|
||||
```typescript
|
||||
export function matchRequiredCertName(
|
||||
actualName: string | undefined,
|
||||
requiredName: string
|
||||
): boolean {
|
||||
const name = actualName?.trim() || ''
|
||||
if (!name) return false
|
||||
if (requiredName === '押运员从业资格证') {
|
||||
return name === '押运员从业资格证' || name === '押运员证'
|
||||
}
|
||||
return name === requiredName
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 更新徽章 shortLabel(第 190–194 行)**
|
||||
|
||||
```typescript
|
||||
export const PL_PERSONNEL_CERT_SHORT_LABELS: Record<string, string> = {
|
||||
身份证: '身',
|
||||
驾驶证: '驾',
|
||||
驾驶员从业资格证: '业',
|
||||
押运员从业资格证: '押'
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/utils/pl-personnel-cert.ts
|
||||
git commit -m "feat(pl): align frontend personnel cert required rules with split design"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: 人员页下拉选项
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/views/pl/personnel/index.vue:431-438`
|
||||
|
||||
- [ ] **Step 1: 更新 `certNameOptions`**
|
||||
|
||||
```typescript
|
||||
const certNameOptions = [
|
||||
'身份证',
|
||||
'驾驶证',
|
||||
'驾驶员从业资格证',
|
||||
'押运员从业资格证',
|
||||
'押运员证',
|
||||
'健康证'
|
||||
]
|
||||
```
|
||||
|
||||
说明:移除泛称 `从业资格证`、`危化品从业资格证`(避免误选;历史/other 证书仍可手输)。
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/views/pl/personnel/index.vue
|
||||
git commit -m "feat(pl): update personnel cert name dropdown for split qualifications"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: 历史数据迁移脚本
|
||||
|
||||
**Files:**
|
||||
- Create: `backend/scripts/migration_20260713_pl_personnel_cert_split.sql`
|
||||
|
||||
- [ ] **Step 1: 创建迁移 SQL**
|
||||
|
||||
```sql
|
||||
-- 人员从业资格证拆分:cert_name 重命名(可重复执行)
|
||||
-- 前置 spec: docs/superpowers/specs/2026-07-13-pl-personnel-cert-split-design.md
|
||||
|
||||
-- 1) 押运员证 → 押运员从业资格证(全部 personnel 证书)
|
||||
UPDATE pl_cert c
|
||||
INNER JOIN pl_personnel p ON p.id = c.owner_id AND p.del_flag = 0
|
||||
SET c.cert_name = '押运员从业资格证',
|
||||
c.update_time = NOW()
|
||||
WHERE c.del_flag = 0
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.cert_name = '押运员证';
|
||||
|
||||
-- 2) 泛称从业资格证 → 驾驶员从业资格证(driver / both,且非 both 单条歧义场景见注释)
|
||||
UPDATE pl_cert c
|
||||
INNER JOIN pl_personnel p ON p.id = c.owner_id AND p.del_flag = 0
|
||||
SET c.cert_name = '驾驶员从业资格证',
|
||||
c.update_time = NOW()
|
||||
WHERE c.del_flag = 0
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.cert_name = '从业资格证'
|
||||
AND p.personnel_type IN ('driver', 'both');
|
||||
|
||||
-- 3) 泛称从业资格证 → 押运员从业资格证(escort)
|
||||
UPDATE pl_cert c
|
||||
INNER JOIN pl_personnel p ON p.id = c.owner_id AND p.del_flag = 0
|
||||
SET c.cert_name = '押运员从业资格证',
|
||||
c.update_time = NOW()
|
||||
WHERE c.del_flag = 0
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.cert_name = '从业资格证'
|
||||
AND p.personnel_type = 'escort';
|
||||
|
||||
-- 4) both 人员:若迁移后仍缺驾/押任一从业证,供运营补录(验证查询,不修改数据)
|
||||
SELECT
|
||||
p.id AS personnel_id,
|
||||
p.personnel_name,
|
||||
p.personnel_type,
|
||||
GROUP_CONCAT(c.cert_name ORDER BY c.cert_name SEPARATOR '、') AS cert_names
|
||||
FROM pl_personnel p
|
||||
LEFT JOIN pl_cert c
|
||||
ON c.owner_id = p.id
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.del_flag = 0
|
||||
WHERE p.del_flag = 0
|
||||
AND p.personnel_type = 'both'
|
||||
GROUP BY p.id, p.personnel_name, p.personnel_type
|
||||
HAVING SUM(CASE WHEN c.cert_name IN ('驾驶员从业资格证') THEN 1 ELSE 0 END) = 0
|
||||
OR SUM(CASE WHEN c.cert_name IN ('押运员从业资格证', '押运员证') THEN 1 ELSE 0 END) = 0;
|
||||
|
||||
-- 5) 危化品从业资格证:不自动迁移(人工清单)
|
||||
SELECT
|
||||
p.id AS personnel_id,
|
||||
p.personnel_name,
|
||||
p.personnel_type,
|
||||
c.id AS cert_id,
|
||||
c.cert_name
|
||||
FROM pl_cert c
|
||||
INNER JOIN pl_personnel p ON p.id = c.owner_id AND p.del_flag = 0
|
||||
WHERE c.del_flag = 0
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.cert_name = '危化品从业资格证';
|
||||
|
||||
-- 6) both + 仍保留泛称「从业资格证」的歧义记录(需人工处理,不自动改)
|
||||
SELECT
|
||||
p.id AS personnel_id,
|
||||
p.personnel_name,
|
||||
c.id AS cert_id,
|
||||
c.cert_name
|
||||
FROM pl_cert c
|
||||
INNER JOIN pl_personnel p ON p.id = c.owner_id AND p.del_flag = 0
|
||||
WHERE c.del_flag = 0
|
||||
AND c.owner_type = 'personnel'
|
||||
AND c.cert_name = '从业资格证'
|
||||
AND p.personnel_type = 'both';
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 在测试库执行并保存清单**
|
||||
|
||||
```bash
|
||||
mysql -h <host> -u <user> -p <database> < backend/scripts/migration_20260713_pl_personnel_cert_split.sql
|
||||
```
|
||||
|
||||
将步骤 4–6 的 SELECT 结果导出给运营。
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/scripts/migration_20260713_pl_personnel_cert_split.sql
|
||||
git commit -m "chore(pl): add migration script for personnel cert name split"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: 字典同步(可选)
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/sql/shanxia2.0.sql`(`pl_cert_name` 字典段)
|
||||
|
||||
- [ ] **Step 1: 追加字典项(若不存在)**
|
||||
|
||||
```sql
|
||||
-- pl_cert_name 字典增量(执行前检查是否已存在)
|
||||
INSERT INTO sys_dict_data (id, dict_label, dict_value, tag_type, dict_type, tenant_no, order_num, del_flag, create_time, update_time)
|
||||
SELECT 'PL_CERT_DRIVER_QUAL', '驾驶员从业资格证', '驾驶员从业资格证', 'primary', 'pl_cert_name', 'shanxia2.0', 6, 0, NOW(), NOW()
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_dict_data WHERE id = 'PL_CERT_DRIVER_QUAL');
|
||||
|
||||
INSERT INTO sys_dict_data (id, dict_label, dict_value, tag_type, dict_type, tenant_no, order_num, del_flag, create_time, update_time)
|
||||
SELECT 'PL_CERT_ESCORT_QUAL', '押运员从业资格证', '押运员从业资格证', 'warning', 'pl_cert_name', 'shanxia2.0', 7, 0, NOW(), NOW()
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_dict_data WHERE id = 'PL_CERT_ESCORT_QUAL');
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Commit(若做了字典变更)**
|
||||
|
||||
---
|
||||
|
||||
### Task 7: 文档与图谱
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/superpowers/specs/2026-07-12-pl-required-cert-slots-design.md`(§1.3 表格 + D5/D6 加注「已由 2026-07-13 spec 替代」)
|
||||
- Modify: `docs/superpowers/specs/2026-07-13-pl-personnel-cert-split-design.md`(状态改为「已批准」)
|
||||
|
||||
- [ ] **Step 1: 更新旧 spec 废止说明**
|
||||
- [ ] **Step 2: 运行 graphify 更新**
|
||||
|
||||
```bash
|
||||
cd /Users/zlwu/work/00code/shanxia2.0 && ./scripts/update-graph.sh backend
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add docs/superpowers/specs/
|
||||
git commit -m "docs(pl): mark personnel cert split spec approved and supersede 2026-07-12 D5/D6"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 验收步骤
|
||||
|
||||
### A. 自动化
|
||||
|
||||
```bash
|
||||
# 后端
|
||||
cd backend && pytest tests/test_pl_personnel_cert_required.py -v
|
||||
|
||||
# 前端 lint(可选)
|
||||
cd web-admin && pnpm lint
|
||||
```
|
||||
|
||||
### B. 人员主数据页 `/#/pl/base-info/personnel`
|
||||
|
||||
| # | 操作 | 预期 |
|
||||
|---|------|------|
|
||||
| 1 | 新增 → 选「驾驶员」 | 预置 3 槽:身份证、驾驶证、**驾驶员从业资格证**;徽章占位 **身驾业** |
|
||||
| 2 | 缺「驾驶员从业资格证」保存 | 阻断,提示「押运员从业资格证」或「驾驶员从业资格证」缺失文案 |
|
||||
| 3 | 新增 → 选「押运员」 | 预置 2 槽;列表徽章 **身押**(非「业」) |
|
||||
| 4 | 证书名选手输「押运员证」且三字段齐全 | 满足押运员必备,可保存 |
|
||||
| 5 | 新增 → 选「驾驶员兼押运员」 | 预置 **4** 槽;徽章 **身驾业押** |
|
||||
| 6 | both 仅填 3 证(缺押运员侧) | 保存阻断 |
|
||||
| 7 | 手输泛称「从业资格证」 | **不能**满足任一从业必备槽 |
|
||||
|
||||
### C. 车辆关联(山峡自有车)
|
||||
|
||||
| # | 操作 | 预期 |
|
||||
|---|------|------|
|
||||
| 8 | 关联 escort 角色,人员仅有押运员从业资格证(或押运员证) | 车辆保存通过 escort 证书校验 |
|
||||
| 9 | 关联 driver 角色,人员缺「驾驶员从业资格证」 | 车辆保存阻断 |
|
||||
|
||||
### D. 迁移后数据
|
||||
|
||||
| # | 检查 | 预期 |
|
||||
|---|------|------|
|
||||
| 10 | `SELECT cert_name FROM pl_cert WHERE cert_name='押运员证' AND owner_type='personnel'` | 0 行(已 rename) |
|
||||
| 11 | both 缺证清单(迁移 SQL §4) | 运营已补录或确认无遗漏 |
|
||||
| 12 | 危化品从业资格证清单(迁移 SQL §5) | 运营已人工归类 |
|
||||
|
||||
### E. API 直调(可选)
|
||||
|
||||
```bash
|
||||
# PUT /api/web/admin/transport/personnel/{id}
|
||||
# personnelType=both, certList 仅含 3 证 → 期望 400,detail 含「押运员从业资格证」
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Spec 覆盖自检
|
||||
|
||||
| Spec 要求 | 对应 Task |
|
||||
|-----------|-----------|
|
||||
| D1 拆分必备证种 | Task 2, 3 |
|
||||
| D2 兼岗 4 证 | Task 2, 3 |
|
||||
| D3 徽章 业/押 | Task 3 Step 4 |
|
||||
| D4 押运员证别名 | Task 2, 3 match 函数 |
|
||||
| D5 严格匹配 | Task 2, 3 删除模糊规则 |
|
||||
| D6/D7 双校验 | Task 2 + 3 + 验收 B/E |
|
||||
| D8 迁移 | Task 5 |
|
||||
| 验收 1–8 | §验收步骤 B–D |
|
||||
|
||||
---
|
||||
|
||||
## 工作量
|
||||
|
||||
| Task | 预估 |
|
||||
|------|------|
|
||||
| Task 1–2 后端 | 2h |
|
||||
| Task 3–4 前端 | 1h |
|
||||
| Task 5 迁移 | 1h |
|
||||
| Task 6–7 文档 | 0.5h |
|
||||
| 验收走查 | 1h |
|
||||
| **合计** | **约 5.5h** |
|
||||
@@ -45,8 +45,8 @@
|
||||
| D2 | **必备字段:证号 + 有效期 + 附件** | 提醒天数维持默认 30,不作为必备条件 |
|
||||
| D3 | **仅山峡自有车强制车辆证** | `vehicleType=self` 时校验主车 3 证、有挂车号时挂车 4 证;`carrier` 不校验 |
|
||||
| D4 | **人员类型三选一** | `driver` 驾驶员 / `escort` 押运员 / `both` 驾驶员兼押运员;人员主数据必填 |
|
||||
| D5 | **人员必备按类型** | driver、both → 身份证+驾驶证+从业资格证;escort → 身份证+从业资格证 |
|
||||
| D6 | **从业资格证别名** | 「危化品从业资格证」等等价匹配「从业资格证」(沿用 `matchRequiredCertName`) |
|
||||
| D5 | **人员必备按类型** | ~~driver、both → 身份证+驾驶证+从业资格证;escort → 身份证+从业资格证~~ **已由 `2026-07-13-pl-personnel-cert-split-design.md` 替代**:驾/押从业证拆分,both 须 4 证 |
|
||||
| D6 | **从业资格证别名** | ~~「危化品从业资格证」等等价匹配「从业资格证」~~ **已废止**;押运员侧仅 `押运员证` 可匹配 `押运员从业资格证` |
|
||||
| D7 | **保存一律阻断** | 历史数据缺必备证时,任何字段保存均须先补齐 |
|
||||
| D8 | **前后端双校验** | 前端 UX + 后端 API 400,防绕过 |
|
||||
| D9 | **关联人员角色兼容** | 车辆子表 `role` 保留;保存山峡自有车时校验人员类型与 role 可匹配(见 §三) |
|
||||
@@ -74,9 +74,9 @@
|
||||
|
||||
| personnel_type | 展示文案 | 必备证书 |
|
||||
|----------------|---------|---------|
|
||||
| `driver` | 驾驶员 | 身份证、驾驶证、从业资格证 |
|
||||
| `escort` | 押运员 | 身份证、从业资格证 |
|
||||
| `both` | 驾驶员兼押运员 | 身份证、驾驶证、从业资格证 |
|
||||
| `driver` | 驾驶员 | 身份证、驾驶证、驾驶员从业资格证 |
|
||||
| `escort` | 押运员 | 身份证、押运员从业资格证 |
|
||||
| `both` | 驾驶员兼押运员 | 身份证、驾驶证、驾驶员从业资格证、押运员从业资格证 |
|
||||
|
||||
常数来源:`PL_PERSONNEL_DRIVER_REQUIRED_CERT_NAMES`、`PL_PERSONNEL_ESCORT_REQUIRED_CERT_NAMES`。
|
||||
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
# 运输管理 · 人员从业资格证拆分 — 设计文档
|
||||
|
||||
> **日期**: 2026-07-13
|
||||
> **状态**: 已批准
|
||||
> **前置**: `docs/superpowers/specs/2026-07-12-pl-required-cert-slots-design.md`(D5/D6 需废止并替换)
|
||||
> **界面**: `/#/pl/base-info/personnel`(驾押人员信息)
|
||||
|
||||
## 背景
|
||||
|
||||
2026-07-12 实现将「从业资格证」视为**驾押共用**的一种证,并通过 `matchRequiredCertName` 模糊匹配(含「危化品从业资格证」、名称含「从业资格证」)。业务上这是**错误建模**:
|
||||
|
||||
- **驾驶员从业资格证** 与 **押运员从业资格证** 是两张不同的证
|
||||
- **驾驶员兼押运员** 须同时持有上述两种从业资格证(共 4 项必备,非 3 项)
|
||||
|
||||
## 已确认决策
|
||||
|
||||
| # | 决策 | 说明 |
|
||||
|---|------|------|
|
||||
| D1 | **拆分必备证种** | 不再使用泛称「从业资格证」作为必备槽名称 |
|
||||
| D2 | **兼岗 4 证** | `both` = 身份证 + 驾驶证 + 驾驶员从业资格证 + 押运员从业资格证 |
|
||||
| D3 | **徽章 shortLabel** | 驾驶员从业资格证 → **业**;押运员从业资格证 → **押** |
|
||||
| D4 | **押运员证别名** | 历史/录入名称「押运员证」**等价于**「押运员从业资格证」(匹配与迁移均认可) |
|
||||
| D5 | **严格匹配从业证** | 取消「名称含从业资格证」的宽泛规则;两类从业证分别精确匹配(押运员侧含 D4 别名) |
|
||||
| D6 | **保存一律阻断** | 沿用 2026-07-12 D7:缺必备证时任何保存均 400 / 前端 warning |
|
||||
| D7 | **前后端双校验** | 规则以 util + service 两处硬编码保持一致 |
|
||||
| D8 | **历史数据迁移** | 上线前执行 SQL/脚本,见 §三 |
|
||||
|
||||
## 一、修订后必备证书矩阵
|
||||
|
||||
| personnel_type | 展示文案 | 必备证书 | 列表徽章顺序 |
|
||||
|----------------|---------|---------|-------------|
|
||||
| `driver` | 驾驶员 | 身份证、驾驶证、驾驶员从业资格证 | 身、驾、业 |
|
||||
| `escort` | 押运员 | 身份证、押运员从业资格证 | 身、押 |
|
||||
| `both` | 驾驶员兼押运员 | 身份证、驾驶证、驾驶员从业资格证、押运员从业资格证 | 身、驾、业、押 |
|
||||
|
||||
每项必备仍要求:**证号 + 有效期 + 附件** 均非空(与 2026-07-12 §1.4 一致)。
|
||||
|
||||
### 1.1 证书名称匹配规则
|
||||
|
||||
| 必备槽目标名称 | 可接受的 cert_name |
|
||||
|---------------|-------------------|
|
||||
| 身份证 | 精确:`身份证` |
|
||||
| 驾驶证 | 精确:`驾驶证` |
|
||||
| 驾驶员从业资格证 | 精确:`驾驶员从业资格证` |
|
||||
| 押运员从业资格证 | 精确:`押运员从业资格证`;别名:`押运员证`(D4) |
|
||||
|
||||
**不再接受**作为任一从业必备槽的匹配:
|
||||
|
||||
- 泛称 `从业资格证`
|
||||
- `危化品从业资格证`(除非业务后续单独确认可映射到驾驶员侧,**本期不自动映射**)
|
||||
- `name.includes('从业资格证')` 类模糊规则
|
||||
|
||||
### 1.2 与 2026-07-12 的差异
|
||||
|
||||
| 项 | 2026-07-12 | 本变更 |
|
||||
|----|-----------|--------|
|
||||
| driver 必备 | 身份证、驾驶证、从业资格证 | 身份证、驾驶证、**驾驶员**从业资格证 |
|
||||
| escort 必备 | 身份证、从业资格证 | 身份证、**押运员**从业资格证 |
|
||||
| both 必备 | 同 driver(3 项) | **4 项**(驾+押从业证均有) |
|
||||
| 从业证匹配 | 模糊共用 | 分类型精确匹配 + 押运员证别名 |
|
||||
|
||||
## 二、实现范围
|
||||
|
||||
### 2.1 前端
|
||||
|
||||
**文件**: `web-admin/src/utils/pl-personnel-cert.ts`
|
||||
|
||||
- 常数:
|
||||
- `PL_PERSONNEL_DRIVER_REQUIRED_CERT_NAMES` → `('身份证', '驾驶证', '驾驶员从业资格证')`
|
||||
- `PL_PERSONNEL_ESCORT_REQUIRED_CERT_NAMES` → `('身份证', '押运员从业资格证')`
|
||||
- `getRequiredPersonnelCertNamesByType`:
|
||||
- `escort` → escort 列表
|
||||
- `driver` → driver 列表
|
||||
- `both` → **合并去重** driver ∪ escort(顺序:身份证、驾驶证、驾驶员从业资格证、押运员从业资格证)
|
||||
- `matchRequiredCertName`:
|
||||
- 删除对泛称「从业资格证」的模糊分支
|
||||
- 新增:`押运员从业资格证` 可匹配 `押运员证`
|
||||
- `驾驶员从业资格证` 仅精确匹配
|
||||
- `PL_PERSONNEL_CERT_SHORT_LABELS`:
|
||||
- `驾驶员从业资格证: '业'`
|
||||
- `押运员从业资格证: '押'`
|
||||
- 移除泛称 `从业资格证: '业'`
|
||||
|
||||
**文件**: `web-admin/src/views/pl/personnel/index.vue`
|
||||
|
||||
- `certNameOptions`:必备相关选项改为 `驾驶员从业资格证`、`押运员从业资格证`;保留 `押运员证` 于「其他证书」可选(或标注为别名,非必备槽名)
|
||||
- 移除泛称 `从业资格证` 作为必备槽预置名(可选是否保留于自由添加下拉)
|
||||
|
||||
**连带组件**(逻辑随 util 自动生效,需回归):
|
||||
|
||||
- `pl-personnel-cert-badges`
|
||||
- `pl-cert-form-list` / `pl-cert-slots`
|
||||
- `pl-vehicle-personnel-view-list` / `PersonnelViewPanel`(车辆关联查看态缺失 suffix)
|
||||
- `pl/self-vehicle`、`pl/vehicle`(关联人员证书校验提示)
|
||||
|
||||
### 2.2 后端
|
||||
|
||||
**文件**: `backend/app/services/pl_cert_required_service.py`
|
||||
|
||||
- `PERSONNEL_DRIVER_REQUIRED`、`PERSONNEL_ESCORT_REQUIRED` 与前端对齐
|
||||
- `get_required_personnel_cert_names`:`both` 返回 4 项合并列表
|
||||
- `match_required_cert_name`:与前端 D4/D5 一致
|
||||
- `validate_vehicle_personnel_cert_links`:按 `role` 使用 driver/escort 必备列表(escort 侧含押运员从业资格证 + 押运员证别名)
|
||||
|
||||
### 2.3 字典(可选同步)
|
||||
|
||||
`sys_dict_data` / `pl_cert_name`:
|
||||
|
||||
- 新增:`驾驶员从业资格证`、`押运员从业资格证`
|
||||
- `押运员证` 保留(作为别名来源,非必备槽展示名)
|
||||
- 泛称 `从业资格证`、`危化品从业资格证`:可保留于字典供历史/other 证书,**不参与必备匹配**
|
||||
|
||||
## 三、历史数据迁移
|
||||
|
||||
### 3.1 证书名称重命名
|
||||
|
||||
| 原 cert_name | 迁移后 cert_name | 条件 |
|
||||
|-------------|-----------------|------|
|
||||
| `押运员证` | `押运员从业资格证` | 全部 personnel owner |
|
||||
| `从业资格证` | `驾驶员从业资格证` | 该人员 `personnel_type IN ('driver', 'both')` |
|
||||
| `从业资格证` | `押运员从业资格证` | 该人员 `personnel_type = 'escort'` |
|
||||
| `从业资格证` | **不自动迁移** | `personnel_type = 'both'` 且仅有一条 → **导出人工清单**;或按业务规则复制为两条(若证号相同则拆两条记录,**需运营确认**,默认不自动复制) |
|
||||
|
||||
**both + 单条泛称「从业资格证」**:迁移脚本应 **输出待人工处理清单**(personnel_id、姓名、原 cert_name),不静默映射,避免一张证冒充两种从业证。
|
||||
|
||||
**危化品从业资格证**:本期 **不自动映射**;进入缺证清单,由运营按实际类型补录或重命名。
|
||||
|
||||
### 3.2 迁移脚本
|
||||
|
||||
- 路径建议:`backend/scripts/migration_20260713_pl_personnel_cert_split.sql`
|
||||
- 要求:可重复执行(UPDATE 仅作用于未迁移行);执行后附 `SELECT` 验证 both 人员是否仍缺押运/驾从业证
|
||||
|
||||
### 3.3 上线顺序
|
||||
|
||||
1. 执行迁移脚本 + 人工处理 both ambiguous 清单
|
||||
2. 部署前后端新规则
|
||||
3. 运营抽查列表徽章(身驾业押)与保存阻断
|
||||
|
||||
## 四、业务规则(保持不变部分)
|
||||
|
||||
- 人员主数据:按 `personnel_type` 校验必备(`both` 为 4 项)
|
||||
- 山峡自有车关联人员:按关联行 `role` 校验 driver/escort 必备子集
|
||||
- `both` 类型人员主数据仍须驾驶证,即使仅关联为 escort(沿用 2026-07-12 §3.2 说明)
|
||||
- 承运商车辆不强制车辆证;人员主数据始终强制
|
||||
|
||||
## 五、验收标准
|
||||
|
||||
1. 新增驾驶员:预置 3 必备槽(身份证、驾驶证、驾驶员从业资格证);缺任一项无法保存。
|
||||
2. 新增押运员:预置 2 必备槽(身份证、押运员从业资格证);列表徽章 **身、押**。
|
||||
3. 新增兼岗:预置 4 必备槽;列表徽章 **身、驾、业、押**;缺押运员从业资格证无法保存。
|
||||
4. 录入证书名称为「押运员证」时,满足押运员从业资格证必备槽(D4)。
|
||||
5. 泛称「从业资格证」**不能**满足任一从业必备槽(迁移后)。
|
||||
6. 车辆关联 escort role:校验身份证 + 押运员从业资格证(含押运员证别名)。
|
||||
7. 前后端错误文案一致,含缺失字段(证号/有效期/附件)。
|
||||
8. 迁移脚本执行后,`押运员证` 行已更名为 `押运员从业资格证`。
|
||||
|
||||
## 六、工作量估算
|
||||
|
||||
| 模块 | 预估 |
|
||||
|------|------|
|
||||
| 前后端 util/service 规则对齐 | 0.5 天 |
|
||||
| 人员页下拉/槽位 + 徽章回归 | 0.25 天 |
|
||||
| 迁移脚本 + both 人工清单 | 0.25 天 |
|
||||
| 车辆页关联校验回归 + 自测 | 0.25 天 |
|
||||
| **合计** | **约 1~1.25 人天** |
|
||||
|
||||
## 七、风险
|
||||
|
||||
| 风险 | 缓解 |
|
||||
|------|------|
|
||||
| both 人员仅有一条泛称从业证 | 迁移输出人工清单,不上线前不部署新规则 |
|
||||
| 兼岗人员大量缺「押运员从业资格证」 | 迁移押运员证 + 运营补录 |
|
||||
| 危化品从业资格证无法自动归类 | 本期不映射,运营手动改为驾驶员/押运员从业资格证 |
|
||||
|
||||
## 八、OpenSpec
|
||||
|
||||
建议在 `transport-plan-management` 或新 change 中增补 Scenario,**废止** 2026-07-12 的 D5/D6 表述,引用本设计 §1 矩阵。
|
||||
+61
-21
@@ -450,7 +450,7 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/app/schemas/crm/contract.py": {
|
||||
"mtime": 1783885711.598627,
|
||||
"mtime": 1783946468.3566067,
|
||||
"ast_hash": "6553f54ca1fd19086c170095f402a628",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
@@ -770,8 +770,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/plan.py": {
|
||||
"mtime": 1783845558.7014904,
|
||||
"ast_hash": "853850cff4f1ebd6ff197681e21e81f6",
|
||||
"mtime": 1783945795.4842672,
|
||||
"ast_hash": "c29fcd9010986053c0b329b165edc904",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/app/api/pl/transport.py": {
|
||||
@@ -925,8 +925,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/app/services/pl_cert_required_service.py": {
|
||||
"mtime": 1783845035.534594,
|
||||
"ast_hash": "279f299a4969244bad7f866ae9ee97fb",
|
||||
"mtime": 1783946967.244319,
|
||||
"ast_hash": "48e656d81a0ea254135bcae7e41bda63",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/app/services/workflow_engine.py": {
|
||||
@@ -2395,8 +2395,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/utils/pl-personnel-cert.ts": {
|
||||
"mtime": 1783849542.7557807,
|
||||
"ast_hash": "b063105c550403d69893f65d3da2f70c",
|
||||
"mtime": 1783946960.4894924,
|
||||
"ast_hash": "ce4a23486763cdd36e54734d609f65b6",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/utils/patch-el-select-filterable.ts": {
|
||||
@@ -2520,8 +2520,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/utils/pl-cert-slots.ts": {
|
||||
"mtime": 1783844749.9400146,
|
||||
"ast_hash": "33ea084eaaba3ec98c170d8651ca83f9",
|
||||
"mtime": 1783947180.506817,
|
||||
"ast_hash": "8af97a57279e0223c77be962f9478e87",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/utils/index.ts": {
|
||||
@@ -2560,8 +2560,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/utils/pl-vehicle-cert.ts": {
|
||||
"mtime": 1783849840.3343875,
|
||||
"ast_hash": "d7537c9326ca88ffb699852e5ce1832b",
|
||||
"mtime": 1783946962.4179957,
|
||||
"ast_hash": "ce856feef2f4d3f514f2d13e889f2fcc",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/utils/protocol-payment-installment.ts": {
|
||||
@@ -3485,8 +3485,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/components/business/pl-cert-form-list/index.vue": {
|
||||
"mtime": 1783849061.800741,
|
||||
"ast_hash": "952e011c4aa5d0432a808ad15fd11e88",
|
||||
"mtime": 1783947181.289606,
|
||||
"ast_hash": "181ec92980e1828363725ba383c17674",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/components/business/product-view-dialog/index.vue": {
|
||||
@@ -3890,8 +3890,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/api/pl/index.ts": {
|
||||
"mtime": 1783849851.9140031,
|
||||
"ast_hash": "b4a408e66eb8617b69385fcf85fb61d5",
|
||||
"mtime": 1783945795.170435,
|
||||
"ast_hash": "58f65f29bc822eead3a2d51335bb7e31",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/api/pl/public-transport.ts": {
|
||||
@@ -4195,8 +4195,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/views/pl/plan-archive/index.vue": {
|
||||
"mtime": 1783846246.026981,
|
||||
"ast_hash": "8e2207eb52be4b0dca7811323f61aabf",
|
||||
"mtime": 1783945922.585953,
|
||||
"ast_hash": "d48e90b3deeadc919204cd9900fc743d",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/views/pl/self-vehicle/index.vue": {
|
||||
@@ -4210,8 +4210,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/views/pl/personnel/index.vue": {
|
||||
"mtime": 1783849448.5590773,
|
||||
"ast_hash": "d71558db33a5c5531066cf3983b02a7a",
|
||||
"mtime": 1783947181.9509516,
|
||||
"ast_hash": "9ac8cf2b667043ab7adc2b1d9a00fea8",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/views/pl/vehicle-maintenance-process/index.vue": {
|
||||
@@ -4260,8 +4260,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/views/bx/view/all/index.vue": {
|
||||
"mtime": 1783749875.5645318,
|
||||
"ast_hash": "8c9a56af329d2c44040435a83bf60955",
|
||||
"mtime": 1783889609.5657969,
|
||||
"ast_hash": "a10b326099589df85aab2bbdf9cfef24",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/web-admin/src/views/bx/view/todo/index.vue": {
|
||||
@@ -6393,5 +6393,45 @@
|
||||
"mtime": 1783886258.0258434,
|
||||
"ast_hash": "1188a31d71cbaf95584619ae5adb007d",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/tests/test_pl_personnel_cert_required.py": {
|
||||
"mtime": 1783946968.4303102,
|
||||
"ast_hash": "9a36f0a55a8226b299707fa6da6e61b4",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_opportunity.py": {
|
||||
"mtime": 1783887271.1669047,
|
||||
"ast_hash": "282e3cb71401711e6d355dafc77840c6",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_payment_invoice.py": {
|
||||
"mtime": 1783888353.7715802,
|
||||
"ast_hash": "616d8c0e8866a3006937dd90e12526d4",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_clue.py": {
|
||||
"mtime": 1783887050.391179,
|
||||
"ast_hash": "106a41cb68b0444892f6ad7f118c1176",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_bx_data.py": {
|
||||
"mtime": 1783888844.4506958,
|
||||
"ast_hash": "eb57e09f1d0a31d7170e6fba30a91ef2",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_contract.py": {
|
||||
"mtime": 1783888258.2304351,
|
||||
"ast_hash": "9d8c495362959fee8018c396d4e6dcfd",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migrate_crm_quote.py": {
|
||||
"mtime": 1783887475.224438,
|
||||
"ast_hash": "ebe7d542c8254547db2b7176baff2e47",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"/Users/zlwu/work/00code/shanxia2.0/backend/scripts/migration_20260713_pl_personnel_cert_split.sql": {
|
||||
"mtime": 1783946793.684379,
|
||||
"ast_hash": "7b5ad50506d6660fcc3c1ac032ac5b34",
|
||||
"semantic_hash": ""
|
||||
}
|
||||
}
|
||||
@@ -723,7 +723,6 @@
|
||||
"721": "Community 721",
|
||||
"722": "Community 722",
|
||||
"723": "Community 723",
|
||||
"724": "Community 724",
|
||||
"725": "Community 725",
|
||||
"726": "Community 726",
|
||||
"727": "Community 727",
|
||||
@@ -731,28 +730,17 @@
|
||||
"729": "Community 729",
|
||||
"730": "Community 730",
|
||||
"731": "Community 731",
|
||||
"732": "Community 732",
|
||||
"733": "Community 733",
|
||||
"734": "Community 734",
|
||||
"735": "Community 735",
|
||||
"736": "Community 736",
|
||||
"737": "Community 737",
|
||||
"738": "Community 738",
|
||||
"739": "Community 739",
|
||||
"740": "Community 740",
|
||||
"741": "Community 741",
|
||||
"742": "Community 742",
|
||||
"743": "Community 743",
|
||||
"744": "Community 744",
|
||||
"745": "Community 745",
|
||||
"746": "Community 746",
|
||||
"747": "Community 747",
|
||||
"748": "Community 748",
|
||||
"749": "Community 749",
|
||||
"750": "Community 750",
|
||||
"751": "Community 751",
|
||||
"752": "Community 752",
|
||||
"753": "Community 753",
|
||||
"754": "Community 754",
|
||||
"755": "Community 755"
|
||||
"754": "Community 754"
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
+3788
-3607
File diff suppressed because it is too large.
Load diff
@@ -419,6 +419,7 @@ export interface PlanQuery {
|
||||
transportStatus?: string
|
||||
archiveStatus?: string
|
||||
customerName?: string
|
||||
productName?: string
|
||||
planDateFrom?: string
|
||||
planDateTo?: string
|
||||
page?: number
|
||||
|
||||
@@ -205,6 +205,8 @@ const props = withDefaults(
|
||||
enforceSelfVehicleRequired?: boolean
|
||||
/** 承运商车辆:按主车/挂车注入必备槽位(行驶证、营运证) */
|
||||
enforceCarrierVehicleRequired?: boolean
|
||||
/** 人员:切换类型时隐藏非当前类型的必备槽(如 driver 不展示押运员从业资格证) */
|
||||
stripManagedCertNames?: readonly string[]
|
||||
}>(),
|
||||
{
|
||||
title: '证书',
|
||||
@@ -216,7 +218,8 @@ const props = withDefaults(
|
||||
requiredCertNames: () => [],
|
||||
requiredVehiclePart: PL_VEHICLE_CERT_PART_HEAD,
|
||||
enforceSelfVehicleRequired: false,
|
||||
enforceCarrierVehicleRequired: false
|
||||
enforceCarrierVehicleRequired: false,
|
||||
stripManagedCertNames: () => []
|
||||
}
|
||||
)
|
||||
|
||||
@@ -294,7 +297,8 @@ function syncRequiredSlots() {
|
||||
}
|
||||
if (props.requiredCertNames?.length) {
|
||||
certList.value = mergeCertListWithRequiredSlots(certList.value, props.requiredCertNames, {
|
||||
vehiclePart: props.requiredVehiclePart
|
||||
vehiclePart: props.requiredVehiclePart,
|
||||
stripManagedNames: props.stripManagedCertNames
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -319,6 +323,7 @@ watch(
|
||||
props.enforceSelfVehicleRequired,
|
||||
props.enforceCarrierVehicleRequired,
|
||||
props.requiredCertNames,
|
||||
props.stripManagedCertNames,
|
||||
props.trailerNo
|
||||
] as const,
|
||||
() => {
|
||||
|
||||
@@ -21,7 +21,6 @@ export function isRequiredCertSlotComplete(
|
||||
): boolean {
|
||||
if (!cert) return false
|
||||
if (!matchRequiredCertName(cert.certName, requiredName)) return false
|
||||
if (!cert.certNo?.trim()) return false
|
||||
if (!cert.expireDate) return false
|
||||
if (!cert.attachmentUrls?.trim()) return false
|
||||
return true
|
||||
@@ -32,10 +31,9 @@ export function getMissingRequiredCertFieldLabels(
|
||||
requiredName: string
|
||||
): string[] {
|
||||
if (!cert || !matchRequiredCertName(cert.certName, requiredName)) {
|
||||
return ['证号', '有效期', '附件']
|
||||
return ['有效期', '附件']
|
||||
}
|
||||
const missing: string[] = []
|
||||
if (!cert.certNo?.trim()) missing.push('证号')
|
||||
if (!cert.expireDate) missing.push('有效期')
|
||||
if (!cert.attachmentUrls?.trim()) missing.push('附件')
|
||||
return missing
|
||||
@@ -133,12 +131,28 @@ function findCertIndexForRequired(
|
||||
export function mergeCertListWithRequiredSlots(
|
||||
existing: CertRowWithMeta[],
|
||||
requiredNames: readonly string[],
|
||||
options?: { vehiclePart?: string }
|
||||
options?: { vehiclePart?: string; stripManagedNames?: readonly string[] }
|
||||
): CertRowWithMeta[] {
|
||||
const vehiclePart = options?.vehiclePart
|
||||
const next = existing.map(cert => ({ ...cert }))
|
||||
const stripManagedNames = options?.stripManagedNames
|
||||
const normalizedPart = vehiclePart ? normalizeVehicleCertPart(vehiclePart) : null
|
||||
|
||||
let source = existing
|
||||
if (stripManagedNames?.length) {
|
||||
source = existing.filter(cert => {
|
||||
if (normalizedPart && normalizeVehicleCertPart(cert.vehiclePart) !== normalizedPart) {
|
||||
return true
|
||||
}
|
||||
if (requiredNames.some(name => matchRequiredCertName(cert.certName, name))) {
|
||||
return true
|
||||
}
|
||||
const isManaged = stripManagedNames.some(name => matchRequiredCertName(cert.certName, name))
|
||||
return !isManaged
|
||||
})
|
||||
}
|
||||
|
||||
const next = source.map(cert => ({ ...cert }))
|
||||
|
||||
const extras = next.filter(cert => {
|
||||
if (normalizedPart && normalizeVehicleCertPart(cert.vehiclePart) !== normalizedPart) {
|
||||
return false
|
||||
|
||||
@@ -5,10 +5,20 @@ export const PL_PERSONNEL_CERT_MISSING_SUFFIX = '(证书缺失)'
|
||||
export const PL_PERSONNEL_DRIVER_REQUIRED_CERT_NAMES = [
|
||||
'身份证',
|
||||
'驾驶证',
|
||||
'从业资格证'
|
||||
'驾驶员从业资格证'
|
||||
] as const
|
||||
|
||||
export const PL_PERSONNEL_ESCORT_REQUIRED_CERT_NAMES = ['身份证', '从业资格证'] as const
|
||||
export const PL_PERSONNEL_ESCORT_REQUIRED_CERT_NAMES = [
|
||||
'身份证',
|
||||
'押运员从业资格证'
|
||||
] as const
|
||||
|
||||
export const PL_PERSONNEL_BOTH_REQUIRED_CERT_NAMES = [
|
||||
'身份证',
|
||||
'驾驶证',
|
||||
'驾驶员从业资格证',
|
||||
'押运员从业资格证'
|
||||
] as const
|
||||
|
||||
export type PersonnelCertRole = 'driver' | 'escort'
|
||||
export type PersonnelType = 'driver' | 'escort' | 'both'
|
||||
@@ -69,7 +79,10 @@ export function getRequiredPersonnelCertNamesByType(
|
||||
if (personnelType === 'escort') {
|
||||
return PL_PERSONNEL_ESCORT_REQUIRED_CERT_NAMES
|
||||
}
|
||||
return PL_PERSONNEL_DRIVER_REQUIRED_CERT_NAMES
|
||||
if (personnelType === 'driver') {
|
||||
return PL_PERSONNEL_DRIVER_REQUIRED_CERT_NAMES
|
||||
}
|
||||
return PL_PERSONNEL_BOTH_REQUIRED_CERT_NAMES
|
||||
}
|
||||
|
||||
/** 车辆关联人员:从人员主数据类型映射为关联角色(司机/押运员) */
|
||||
@@ -105,7 +118,6 @@ export function isPersonnelCertStrictComplete(
|
||||
): boolean {
|
||||
if (!cert?.certName?.trim()) return false
|
||||
if (!matchRequiredCertName(cert.certName, requiredName)) return false
|
||||
if (!cert.certNo?.trim()) return false
|
||||
if (!cert.expireDate) return false
|
||||
if (!cert.attachmentUrls?.trim()) return false
|
||||
return true
|
||||
@@ -117,12 +129,8 @@ export function matchRequiredCertName(
|
||||
): boolean {
|
||||
const name = actualName?.trim() || ''
|
||||
if (!name) return false
|
||||
if (requiredName === '从业资格证') {
|
||||
return (
|
||||
name === '从业资格证' ||
|
||||
name === '危化品从业资格证' ||
|
||||
name.includes('从业资格证')
|
||||
)
|
||||
if (requiredName === '押运员从业资格证') {
|
||||
return name === '押运员从业资格证' || name === '押运员证'
|
||||
}
|
||||
return name === requiredName
|
||||
}
|
||||
@@ -130,7 +138,6 @@ export function matchRequiredCertName(
|
||||
export function isPersonnelCertUploaded(cert?: Pick<CertRow, 'certName' | 'certNo' | 'expireDate' | 'attachmentUrls'>) {
|
||||
return Boolean(
|
||||
cert?.certName?.trim() &&
|
||||
cert?.certNo?.trim() &&
|
||||
cert?.expireDate &&
|
||||
cert?.attachmentUrls?.trim()
|
||||
)
|
||||
@@ -190,7 +197,8 @@ export function getPersonnelCertMissingSuffix(
|
||||
export const PL_PERSONNEL_CERT_SHORT_LABELS: Record<string, string> = {
|
||||
身份证: '身',
|
||||
驾驶证: '驾',
|
||||
从业资格证: '业'
|
||||
驾驶员从业资格证: '业',
|
||||
押运员从业资格证: '押'
|
||||
}
|
||||
|
||||
export type PersonnelCertBadgeStatus = 'missing' | 'valid' | 'expiring' | 'expired'
|
||||
@@ -207,10 +215,9 @@ function getPersonnelCertMissingFieldLabels(
|
||||
requiredName: string
|
||||
): string[] {
|
||||
if (!cert || !matchRequiredCertName(cert.certName, requiredName)) {
|
||||
return ['证号', '有效期', '附件']
|
||||
return ['有效期', '附件']
|
||||
}
|
||||
const missing: string[] = []
|
||||
if (!cert.certNo?.trim()) missing.push('证号')
|
||||
if (!cert.expireDate) missing.push('有效期')
|
||||
if (!cert.attachmentUrls?.trim()) missing.push('附件')
|
||||
return missing
|
||||
|
||||
@@ -79,7 +79,6 @@ export function mergeVehicleCertsByPart<T extends CertRow>(
|
||||
export function isVehicleCertUploaded(cert?: Pick<CertRow, 'certName' | 'certNo' | 'expireDate' | 'attachmentUrls'>) {
|
||||
return Boolean(
|
||||
cert?.certName?.trim() &&
|
||||
cert?.certNo?.trim() &&
|
||||
cert?.expireDate &&
|
||||
cert?.attachmentUrls?.trim()
|
||||
)
|
||||
@@ -264,10 +263,9 @@ function getVehicleCertMissingFieldLabels(
|
||||
requiredName: string
|
||||
): string[] {
|
||||
if (!cert || !matchVehicleRequiredCertName(cert.certName, requiredName)) {
|
||||
return ['证号', '有效期', '附件']
|
||||
return ['有效期', '附件']
|
||||
}
|
||||
const missing: string[] = []
|
||||
if (!cert.certNo?.trim()) missing.push('证号')
|
||||
if (!cert.expireDate) missing.push('有效期')
|
||||
if (!cert.attachmentUrls?.trim()) missing.push('附件')
|
||||
return missing
|
||||
|
||||
@@ -311,6 +311,7 @@
|
||||
upload-folder="pl/personnel-cert"
|
||||
:cert-name-options="certNameOptions"
|
||||
:required-cert-names="requiredPersonnelCertNames"
|
||||
:strip-managed-cert-names="PL_PERSONNEL_BOTH_REQUIRED_CERT_NAMES"
|
||||
layout="table"
|
||||
/>
|
||||
</el-form>
|
||||
@@ -388,6 +389,7 @@ import {
|
||||
getPersonnelAffiliationLabel,
|
||||
getPersonnelAffiliationTagType,
|
||||
PL_PERSONNEL_AFFILIATION_OPTIONS,
|
||||
PL_PERSONNEL_BOTH_REQUIRED_CERT_NAMES,
|
||||
PL_PERSONNEL_TYPE_OPTIONS
|
||||
} from '@/utils/pl-personnel-cert'
|
||||
|
||||
@@ -431,8 +433,8 @@ const viewDetail = ref<PersonnelDetail | null>(null)
|
||||
const certNameOptions = [
|
||||
'身份证',
|
||||
'驾驶证',
|
||||
'从业资格证',
|
||||
'危化品从业资格证',
|
||||
'驾驶员从业资格证',
|
||||
'押运员从业资格证',
|
||||
'押运员证',
|
||||
'健康证'
|
||||
]
|
||||
@@ -462,9 +464,20 @@ const formData = reactive({
|
||||
})
|
||||
|
||||
const requiredPersonnelCertNames = computed(() =>
|
||||
getRequiredPersonnelCertNamesByType(formData.personnelType)
|
||||
formData.personnelType
|
||||
? getRequiredPersonnelCertNamesByType(formData.personnelType)
|
||||
: []
|
||||
)
|
||||
|
||||
function mergePersonnelCertSlots(list: CertListItem[]) {
|
||||
if (!formData.personnelType) return list
|
||||
return mergeCertListWithRequiredSlots(
|
||||
list,
|
||||
getRequiredPersonnelCertNamesByType(formData.personnelType),
|
||||
{ stripManagedNames: PL_PERSONNEL_BOTH_REQUIRED_CERT_NAMES }
|
||||
)
|
||||
}
|
||||
|
||||
const formRules = {
|
||||
personnelName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||
personnelAffiliation: [{ required: true, message: '请选择人员归属', trigger: 'change' }],
|
||||
@@ -575,10 +588,7 @@ watch(
|
||||
() => formData.personnelType,
|
||||
() => {
|
||||
if (!formData.personnelType) return
|
||||
certList.value = mergeCertListWithRequiredSlots(
|
||||
certList.value,
|
||||
getRequiredPersonnelCertNamesByType(formData.personnelType)
|
||||
)
|
||||
certList.value = mergePersonnelCertSlots(certList.value)
|
||||
certFormListRef.value?.refreshRequiredSlots?.()
|
||||
}
|
||||
)
|
||||
@@ -715,7 +725,7 @@ async function handleEdit(row: Personnel) {
|
||||
status: detail.status,
|
||||
remark: detail.remark || ''
|
||||
})
|
||||
certList.value = mergeCertListWithRequiredSlots(
|
||||
certList.value = mergePersonnelCertSlots(
|
||||
(detail.certList || []).map(c => ({
|
||||
_key: c.id || c.certId || `cert-${Math.random().toString(36).slice(2, 10)}`,
|
||||
certId: c.id || c.certId,
|
||||
@@ -724,8 +734,7 @@ async function handleEdit(row: Personnel) {
|
||||
expireDate: c.expireDate,
|
||||
remindDays: c.remindDays ?? 30,
|
||||
attachmentUrls: c.attachmentUrls || ''
|
||||
})),
|
||||
getRequiredPersonnelCertNamesByType(detail.personnelType || 'both')
|
||||
}))
|
||||
)
|
||||
certFormListRef.value?.refreshRequiredSlots?.()
|
||||
} catch {
|
||||
|
||||
@@ -19,6 +19,14 @@
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="产品名称">
|
||||
<el-input
|
||||
v-model="searchForm.productName"
|
||||
placeholder="搜索产品名称"
|
||||
clearable
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="跟进状态">
|
||||
<el-select v-model="searchForm.followStatus" placeholder="全部" clearable>
|
||||
<el-option label="草稿" value="draft" />
|
||||
@@ -398,8 +406,9 @@ const activePlanTypeTab = ref<PlPlanTypeTab>('all')
|
||||
const searchForm = reactive({
|
||||
planNo: '',
|
||||
planType: '',
|
||||
productName: '',
|
||||
followStatus: '',
|
||||
transportStatus: '',
|
||||
transportStatus: 'arranged',
|
||||
customerName: '',
|
||||
archiveStatus: ''
|
||||
})
|
||||
@@ -451,6 +460,7 @@ async function fetchData() {
|
||||
followStatus: searchForm.followStatus || undefined,
|
||||
transportStatus: searchForm.transportStatus || undefined,
|
||||
customerName: keyword ? undefined : searchForm.customerName || undefined,
|
||||
productName: keyword ? undefined : searchForm.productName || undefined,
|
||||
archiveStatus: searchForm.archiveStatus || undefined,
|
||||
planDateFrom: dateRange.value?.[0] || undefined,
|
||||
planDateTo: dateRange.value?.[1] || undefined,
|
||||
@@ -480,8 +490,9 @@ function handleReset() {
|
||||
activePlanTypeTab.value = 'all'
|
||||
searchForm.planNo = ''
|
||||
searchForm.planType = ''
|
||||
searchForm.productName = ''
|
||||
searchForm.followStatus = ''
|
||||
searchForm.transportStatus = ''
|
||||
searchForm.transportStatus = 'arranged'
|
||||
searchForm.customerName = ''
|
||||
searchForm.archiveStatus = ''
|
||||
quickSearch.value = ''
|
||||
@@ -581,6 +592,7 @@ useDbInstantSearch(
|
||||
() => ({
|
||||
planNo: searchForm.planNo,
|
||||
planType: searchForm.planType,
|
||||
productName: searchForm.productName,
|
||||
followStatus: searchForm.followStatus,
|
||||
transportStatus: searchForm.transportStatus,
|
||||
customerName: searchForm.customerName,
|
||||
|
||||
Reference in new issue
Block a user