提交
This commit is contained in:
1 parent
0b50eff3d8
commit
ee364e24aa
323 files changed
+57731
-35766
No files matched your search
@@ -1 +0,0 @@
|
||||
78910
|
||||
@@ -1,4 +1,5 @@
|
||||
"""环境检测 — 检测项维护 + 登记管理 API"""
|
||||
from datetime import datetime, time
|
||||
from typing import List, Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
@@ -227,10 +228,31 @@ async def delete_env_detect_item(
|
||||
# ---------- 环境检测登记 ----------
|
||||
|
||||
|
||||
def _parse_detect_date(value: Optional[str]) -> Optional[datetime]:
|
||||
s = (value or "").strip()
|
||||
if not s:
|
||||
return None
|
||||
dt = parse_datetime(s)
|
||||
if not dt and len(s) >= 10:
|
||||
dt = parse_datetime(f"{s[:10]} 00:00:00")
|
||||
return dt
|
||||
|
||||
|
||||
def _parse_detect_date_bound(value: Optional[str], *, end_of_day: bool = False) -> Optional[datetime]:
|
||||
dt = _parse_detect_date(value)
|
||||
if not dt:
|
||||
return None
|
||||
s = (value or "").strip()
|
||||
if end_of_day and " " not in s:
|
||||
return datetime.combine(dt.date(), time(23, 59, 59))
|
||||
return dt
|
||||
|
||||
|
||||
class EnvDetectRecordBody(BaseModel):
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
|
||||
detect_time: str = Field(..., alias="detectTime")
|
||||
result_time: Optional[str] = Field(None, alias="resultTime")
|
||||
inspector_ids: List[str] = Field(..., alias="inspectorIds")
|
||||
env_detect_item_id: str = Field(..., alias="envDetectItemId")
|
||||
result_desc: str = Field(..., alias="resultDesc")
|
||||
@@ -242,6 +264,7 @@ class EnvDetectRecordUpdateBody(BaseModel):
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
|
||||
detect_time: Optional[str] = Field(None, alias="detectTime")
|
||||
result_time: Optional[str] = Field(None, alias="resultTime")
|
||||
inspector_ids: Optional[List[str]] = Field(None, alias="inspectorIds")
|
||||
env_detect_item_id: Optional[str] = Field(None, alias="envDetectItemId")
|
||||
result_desc: Optional[str] = Field(None, alias="resultDesc")
|
||||
@@ -287,8 +310,8 @@ async def list_env_detect_records(
|
||||
from sqlalchemy import func
|
||||
|
||||
query = query.filter(func.find_in_set(insp_id, BizEnvDetectRecord.inspector_ids) > 0)
|
||||
dt_start = parse_datetime(detectTimeStart) if detectTimeStart else None
|
||||
dt_end = parse_datetime(detectTimeEnd) if detectTimeEnd else None
|
||||
dt_start = _parse_detect_date_bound(detectTimeStart, end_of_day=False)
|
||||
dt_end = _parse_detect_date_bound(detectTimeEnd, end_of_day=True)
|
||||
if dt_start:
|
||||
query = query.filter(BizEnvDetectRecord.detect_time >= dt_start)
|
||||
if dt_end:
|
||||
@@ -338,12 +361,18 @@ async def create_env_detect_record(
|
||||
user_id = _get_current_user_id(user)
|
||||
sys_user = db.query(SysUser).filter(SysUser.id == user_id).first()
|
||||
dept_id = (sys_user.dept_id or "") if sys_user else ""
|
||||
detect_time = parse_datetime(body.detect_time)
|
||||
detect_time = _parse_detect_date(body.detect_time)
|
||||
if not detect_time:
|
||||
return error_response(400, "检测时间格式无效")
|
||||
return error_response(400, "检测日期格式无效")
|
||||
result_time = None
|
||||
if body.result_time:
|
||||
result_time = _parse_detect_date(body.result_time)
|
||||
if not result_time:
|
||||
return error_response(400, "结果日期格式无效")
|
||||
obj = record_svc.create_env_detect_record(
|
||||
db,
|
||||
detect_time=detect_time,
|
||||
result_time=result_time,
|
||||
inspector_ids=body.inspector_ids,
|
||||
env_detect_item_id=body.env_detect_item_id,
|
||||
result_desc=body.result_desc,
|
||||
@@ -372,13 +401,21 @@ async def update_env_detect_record(
|
||||
try:
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
user_id = _get_current_user_id(user)
|
||||
detect_time = parse_datetime(body.detect_time) if body.detect_time else None
|
||||
detect_time = _parse_detect_date(body.detect_time) if body.detect_time else None
|
||||
if body.detect_time and not detect_time:
|
||||
return error_response(400, "检测时间格式无效")
|
||||
return error_response(400, "检测日期格式无效")
|
||||
update_result_time = "result_time" in body.model_fields_set
|
||||
result_time = None
|
||||
if update_result_time and body.result_time:
|
||||
result_time = _parse_detect_date(body.result_time)
|
||||
if not result_time:
|
||||
return error_response(400, "结果日期格式无效")
|
||||
obj = record_svc.update_env_detect_record(
|
||||
db,
|
||||
row_id,
|
||||
detect_time=detect_time,
|
||||
result_time=result_time,
|
||||
update_result_time=update_result_time,
|
||||
inspector_ids=body.inspector_ids,
|
||||
env_detect_item_id=body.env_detect_item_id,
|
||||
result_desc=body.result_desc,
|
||||
|
||||
@@ -1752,6 +1752,42 @@ async def list_production_work_orders(
|
||||
return success_response({"list": items, "total": total, "page": page, "pageSize": pageSize, "totalPages": tp})
|
||||
|
||||
|
||||
@router.get("/production-work-orders/tab-step-counts")
|
||||
async def production_work_order_tab_step_counts(
|
||||
user: dict = Depends(require_admin_or_super_admin),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
try:
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
counts = production_task_svc.count_production_work_order_tab_step_badges(
|
||||
db, tenant_no=tenant_no, user_info=user
|
||||
)
|
||||
return success_response(counts)
|
||||
except PermissionError as e:
|
||||
return error_response(403, str(e))
|
||||
except Exception as e:
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
@router.get("/production-work-orders/mine-tab-step-counts")
|
||||
async def production_work_order_mine_tab_step_counts(
|
||||
user: dict = Depends(require_menu_code("production:my-task:list")),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
try:
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
counts = production_task_svc.count_mine_production_work_order_tab_step_badges(
|
||||
db,
|
||||
tenant_no=tenant_no,
|
||||
assignee_user_id=_get_current_user_id(user),
|
||||
)
|
||||
return success_response(counts)
|
||||
except PermissionError as e:
|
||||
return error_response(403, str(e))
|
||||
except Exception as e:
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
@router.get("/production-work-orders/{wo_id}")
|
||||
async def get_production_work_order(
|
||||
wo_id: str,
|
||||
|
||||
@@ -54,6 +54,7 @@ class StockInBody(BaseModel):
|
||||
stock_in_no: str = Field(..., alias="stockInNo")
|
||||
stock_in_date: str = Field(..., alias="stockInDate")
|
||||
expire_date: str = Field(..., alias="expireDate")
|
||||
production_date: Optional[str] = Field(None, alias="productionDate")
|
||||
catalog_no: str = Field(..., alias="catalogNo")
|
||||
batch_no: str = Field(..., alias="batchNo")
|
||||
manufacturer: str
|
||||
@@ -71,6 +72,7 @@ class BatchStockInItem(BaseModel):
|
||||
stock_in_no: str = Field(..., alias="stockInNo")
|
||||
stock_in_date: str = Field(..., alias="stockInDate")
|
||||
expire_date: str = Field(..., alias="expireDate")
|
||||
production_date: Optional[str] = Field(None, alias="productionDate")
|
||||
catalog_no: str = Field(..., alias="catalogNo")
|
||||
batch_no: str = Field(..., alias="batchNo")
|
||||
manufacturer: str
|
||||
@@ -125,6 +127,7 @@ class ProductionMaterialBatchUpdateBody(BaseModel):
|
||||
stock_in_no: Optional[str] = Field(None, alias="stockInNo")
|
||||
stock_in_date: Optional[str] = Field(None, alias="stockInDate")
|
||||
expire_date: Optional[str] = Field(None, alias="expireDate")
|
||||
production_date: Optional[str] = Field(None, alias="productionDate")
|
||||
catalog_no: Optional[str] = Field(None, alias="catalogNo")
|
||||
batch_no: Optional[str] = Field(None, alias="batchNo")
|
||||
manufacturer: Optional[str] = None
|
||||
@@ -528,6 +531,7 @@ async def stock_in_production_material(
|
||||
amount=body.amount,
|
||||
qty=Decimal(str(body.qty)),
|
||||
remark=body.remark,
|
||||
production_date=body.production_date,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
operate_time=operate_time,
|
||||
|
||||
+110
-10
@@ -1,5 +1,5 @@
|
||||
"""质量检测 — 第三方/实验室主数据、质检工单、质检任务 API"""
|
||||
from typing import Any, Dict, List, Optional
|
||||
from typing import Any, Dict, Iterable, List, Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
@@ -20,6 +20,8 @@ from app.core.menu_guard import (
|
||||
)
|
||||
|
||||
MY_QC_MATERIAL_USAGE_VIEW_AMOUNT_PERM = "biz:myQcMaterialUsage:viewAmount"
|
||||
QC_MATERIAL_VIEW_AMOUNT_PERM = "biz:qcMaterial:viewAmount"
|
||||
QC_MATERIAL_AMOUNT_FIELD_NAMES = ("unitPrice", "amount", "remainingAmount", "unit_price")
|
||||
from app.core.response import error_response, success_response
|
||||
from app.core.utils import parse_datetime
|
||||
from app.crud import qc_lab_test_item as lab_svc
|
||||
@@ -557,9 +559,22 @@ async def save_item_params(
|
||||
# ---------- 质检工单 ----------
|
||||
|
||||
|
||||
class WorkOrderConfigureBatchItem(BaseModel):
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
|
||||
id: Optional[str] = None
|
||||
batch_name: Optional[str] = Field(None, alias="batchName")
|
||||
assignee_user_ids: List[str] = Field(default_factory=list, alias="assigneeUserIds")
|
||||
has_lab: bool = Field(False, alias="hasLab")
|
||||
has_third_party: bool = Field(False, alias="hasThirdParty")
|
||||
lab_item_ids: List[str] = Field(default_factory=list, alias="labItemIds")
|
||||
third_party_item_ids: List[str] = Field(default_factory=list, alias="thirdPartyItemIds")
|
||||
|
||||
|
||||
class WorkOrderConfigureBody(BaseModel):
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
|
||||
batches: Optional[List[WorkOrderConfigureBatchItem]] = Field(None, alias="batches")
|
||||
has_lab: bool = Field(False, alias="hasLab")
|
||||
has_third_party: bool = Field(False, alias="hasThirdParty")
|
||||
lab_item_ids: List[str] = Field(default_factory=list, alias="labItemIds")
|
||||
@@ -671,6 +686,42 @@ async def list_qc_work_orders(
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
@router.get("/qc-work-orders/tab-unfinished-counts")
|
||||
async def qc_work_order_tab_unfinished_counts(
|
||||
db: Session = Depends(get_db),
|
||||
user: dict = Depends(require_menu_code("biz:qcWorkOrder:list")),
|
||||
):
|
||||
try:
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
counts = wo_svc.count_unfinished_work_orders_by_tab(
|
||||
db, tenant_no=tenant_no, user_info=user
|
||||
)
|
||||
return success_response(counts)
|
||||
except PermissionError as e:
|
||||
return error_response(403, str(e))
|
||||
except Exception as e:
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
@router.get("/qc-work-orders/mine-tab-unfinished-counts")
|
||||
async def qc_work_order_mine_tab_unfinished_counts(
|
||||
db: Session = Depends(get_db),
|
||||
user: dict = Depends(require_menu_code("biz:myQcTask:list")),
|
||||
):
|
||||
try:
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
counts = wo_svc.count_mine_unfinished_work_orders_by_tab(
|
||||
db,
|
||||
tenant_no=tenant_no,
|
||||
assignee_user_id=_get_current_user_id(user),
|
||||
)
|
||||
return success_response(counts)
|
||||
except PermissionError as e:
|
||||
return error_response(403, str(e))
|
||||
except Exception as e:
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
@router.get("/qc-work-orders/{work_order_id}")
|
||||
async def get_qc_work_order_detail(
|
||||
work_order_id: str,
|
||||
@@ -769,6 +820,7 @@ async def configure_qc_work_order(
|
||||
third_party_item_ids=body.third_party_item_ids,
|
||||
lab_item_assignees=body.lab_item_assignees,
|
||||
third_party_item_assignees=body.third_party_item_assignees,
|
||||
batches=[b.model_dump(by_alias=True) for b in body.batches] if body.batches else None,
|
||||
tenant_no=tenant_no,
|
||||
user_id=_get_current_user_id(user),
|
||||
create_dept_id=user.get("dept_id", ""),
|
||||
@@ -782,6 +834,26 @@ async def configure_qc_work_order(
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
@router.get("/qc-work-orders/{work_order_id}/inspection-batches")
|
||||
async def list_qc_work_order_inspection_batches(
|
||||
work_order_id: str,
|
||||
db: Session = Depends(get_db),
|
||||
user: dict = Depends(require_any_menu_code("biz:qcWorkOrder:list", "biz:myQcTask:list")),
|
||||
):
|
||||
try:
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
from app.crud import qc_inspection_batch as batch_svc
|
||||
|
||||
wo = wo_svc.get_work_order(db, work_order_id, tenant_no=tenant_no)
|
||||
if not wo:
|
||||
return error_response(404, "工单不存在")
|
||||
return success_response(batch_svc.list_inspection_batches(db, work_order_id, tenant_no))
|
||||
except PermissionError as e:
|
||||
return error_response(403, str(e))
|
||||
except Exception as e:
|
||||
return error_response(400, str(e))
|
||||
|
||||
|
||||
# ---------- 质检任务 ----------
|
||||
|
||||
|
||||
@@ -1113,6 +1185,23 @@ async def delete_qc_task_api(
|
||||
# ---------- 质检物料库 ----------
|
||||
|
||||
|
||||
def _maybe_strip_qc_material_amount_fields(
|
||||
db: Session, user: dict, rows: Iterable[Dict[str, Any]]
|
||||
) -> None:
|
||||
if user_has_menu_perm(db, user, QC_MATERIAL_VIEW_AMOUNT_PERM):
|
||||
return
|
||||
strip_row_fields(rows, *QC_MATERIAL_AMOUNT_FIELD_NAMES)
|
||||
|
||||
|
||||
def _maybe_strip_qc_material_stock_check_detail(db: Session, user: dict, data: Dict[str, Any]) -> None:
|
||||
if user_has_menu_perm(db, user, QC_MATERIAL_VIEW_AMOUNT_PERM):
|
||||
return
|
||||
for key in ("batchLines", "unusedLines"):
|
||||
lines = data.get(key)
|
||||
if isinstance(lines, list):
|
||||
strip_row_fields(lines, *QC_MATERIAL_AMOUNT_FIELD_NAMES)
|
||||
|
||||
|
||||
class QcMaterialBody(BaseModel):
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
material_code: str = Field(..., alias="materialCode")
|
||||
@@ -1246,6 +1335,7 @@ async def list_qc_material_batches(
|
||||
tenant_no=tenant_no,
|
||||
user_info=user,
|
||||
)
|
||||
_maybe_strip_qc_material_amount_fields(db, user, items)
|
||||
return success_response(_page_payload(items, total, page, pageSize))
|
||||
except PermissionError as e:
|
||||
return error_response(403, str(e))
|
||||
@@ -1263,15 +1353,15 @@ async def qc_material_batch_options(
|
||||
):
|
||||
try:
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
return success_response(
|
||||
batch_svc.batch_options(
|
||||
db,
|
||||
tenant_no,
|
||||
keyword=keyword,
|
||||
material_id=materialId,
|
||||
only_available=onlyAvailable,
|
||||
)
|
||||
options = batch_svc.batch_options(
|
||||
db,
|
||||
tenant_no,
|
||||
keyword=keyword,
|
||||
material_id=materialId,
|
||||
only_available=onlyAvailable,
|
||||
)
|
||||
_maybe_strip_qc_material_amount_fields(db, user, options)
|
||||
return success_response(options)
|
||||
except Exception as e:
|
||||
return error_response(400, str(e))
|
||||
|
||||
@@ -1295,8 +1385,10 @@ async def update_qc_material_batch(
|
||||
**data,
|
||||
)
|
||||
material = mat_svc.get_material(db, obj.material_id, tenant_no=tenant_no)
|
||||
payload = batch_svc._batch_row_to_dict(obj, material)
|
||||
_maybe_strip_qc_material_amount_fields(db, user, [payload])
|
||||
return success_response(
|
||||
batch_svc._batch_row_to_dict(obj, material),
|
||||
payload,
|
||||
message="更新成功",
|
||||
)
|
||||
except ValueError as e:
|
||||
@@ -1660,6 +1752,7 @@ async def list_qc_material_usages(
|
||||
keyword=keyword, stock_in_no=stockInNo,
|
||||
user_info=user,
|
||||
)
|
||||
_maybe_strip_qc_material_amount_fields(db, user, items)
|
||||
return success_response(_page_payload(items, total, page, pageSize))
|
||||
except PermissionError as e:
|
||||
return error_response(403, str(e))
|
||||
@@ -1720,6 +1813,11 @@ async def list_qc_material_linked_task_usages(
|
||||
items = mu_svc.list_linked_task_usages(
|
||||
db, usage_id, tenant_no, user_info=user
|
||||
)
|
||||
if not (
|
||||
user_has_menu_perm(db, user, QC_MATERIAL_VIEW_AMOUNT_PERM)
|
||||
or user_has_menu_perm(db, user, MY_QC_MATERIAL_USAGE_VIEW_AMOUNT_PERM)
|
||||
):
|
||||
strip_row_fields(items, *QC_MATERIAL_AMOUNT_FIELD_NAMES)
|
||||
return success_response(items)
|
||||
except HTTPException as e:
|
||||
detail = e.detail
|
||||
@@ -1750,6 +1848,7 @@ async def list_qc_material_stock_check_requisitions(
|
||||
keyword=keyword,
|
||||
user_info=user,
|
||||
)
|
||||
_maybe_strip_qc_material_amount_fields(db, user, items)
|
||||
return success_response(_page_payload(items, total, page, pageSize))
|
||||
except PermissionError as e:
|
||||
return error_response(403, str(e))
|
||||
@@ -1886,6 +1985,7 @@ async def get_qc_material_stock_check(
|
||||
try:
|
||||
tenant_no = _get_tenant_no(db, user)
|
||||
data = stock_check_svc.get_check_detail(db, check_id, tenant_no)
|
||||
_maybe_strip_qc_material_stock_check_detail(db, user, data)
|
||||
return success_response(data)
|
||||
except ValueError as e:
|
||||
return error_response(400, str(e))
|
||||
|
||||
@@ -7,7 +7,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||
from sqlalchemy import and_, func, or_
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.utils import generate_uuid
|
||||
from app.core.utils import format_date, generate_uuid
|
||||
from app.crud import env_detect_item as item_svc
|
||||
from app.models.models import BizEnvDetectRecord, SysUser
|
||||
|
||||
@@ -26,7 +26,8 @@ def _row_to_dict(r: BizEnvDetectRecord) -> Dict[str, Any]:
|
||||
return {
|
||||
"id": r.id,
|
||||
"recordNo": r.record_no,
|
||||
"detectTime": r.detect_time.strftime("%Y-%m-%d %H:%M:%S") if r.detect_time else "",
|
||||
"detectTime": format_date(r.detect_time),
|
||||
"resultTime": format_date(r.result_time) if r.result_time else "",
|
||||
"inspectorIds": inspector_ids,
|
||||
"inspectorNames": inspector_names,
|
||||
"inspectorDisplay": " / ".join(inspector_names) if inspector_names else "",
|
||||
@@ -181,6 +182,7 @@ def create_env_detect_record(
|
||||
db: Session,
|
||||
*,
|
||||
detect_time: datetime,
|
||||
result_time: Optional[datetime] = None,
|
||||
inspector_ids: List[str],
|
||||
env_detect_item_id: str,
|
||||
result_desc: str,
|
||||
@@ -201,6 +203,7 @@ def create_env_detect_record(
|
||||
id=generate_uuid(),
|
||||
record_no=_generate_record_no(db, tenant_no),
|
||||
detect_time=detect_time,
|
||||
result_time=result_time,
|
||||
inspector_ids=ids_csv,
|
||||
inspector_names=names_csv,
|
||||
env_detect_item_id=item_id,
|
||||
@@ -229,6 +232,8 @@ def update_env_detect_record(
|
||||
row_id: str,
|
||||
*,
|
||||
detect_time: Optional[datetime] = None,
|
||||
result_time: Optional[datetime] = None,
|
||||
update_result_time: bool = False,
|
||||
inspector_ids: Optional[List[str]] = None,
|
||||
env_detect_item_id: Optional[str] = None,
|
||||
result_desc: Optional[str] = None,
|
||||
@@ -244,6 +249,8 @@ def update_env_detect_record(
|
||||
if not detect_time:
|
||||
raise ValueError("检测时间不能为空")
|
||||
obj.detect_time = detect_time
|
||||
if update_result_time:
|
||||
obj.result_time = result_time
|
||||
if inspector_ids is not None:
|
||||
ids_csv, names_csv = _resolve_inspector_snapshots(db, obj.tenant_no, inspector_ids)
|
||||
obj.inspector_ids = ids_csv
|
||||
|
||||
@@ -35,6 +35,15 @@ def _parse_expire_date(v: Any) -> date:
|
||||
return _parse_date(v, label="过期日期")
|
||||
|
||||
|
||||
def _parse_optional_date(v: Any, *, label: str = "日期") -> Optional[date]:
|
||||
if v is None:
|
||||
return None
|
||||
s = str(v).strip()
|
||||
if not s:
|
||||
return None
|
||||
return _parse_date(s, label=label)
|
||||
|
||||
|
||||
def _require_str(v: Any, label: str) -> str:
|
||||
s = str(v or "").strip()
|
||||
if not s:
|
||||
@@ -96,6 +105,7 @@ def _batch_row_to_dict(b: BizProductionMaterialStockBatch, material: Optional[Bi
|
||||
"stockInNo": b.stock_in_no or "",
|
||||
"stockInDate": _fmt_date(b.stock_in_date),
|
||||
"expireDate": _fmt_date(b.expire_date),
|
||||
"productionDate": _fmt_date(b.production_date),
|
||||
"catalogNo": b.catalog_no or "",
|
||||
"batchNo": b.batch_no or "",
|
||||
"manufacturer": b.manufacturer or "",
|
||||
@@ -281,6 +291,7 @@ def batch_options(
|
||||
"stockInNo": b.stock_in_no or "",
|
||||
"stockInDate": _fmt_date(b.stock_in_date),
|
||||
"expireDate": _fmt_date(b.expire_date),
|
||||
"productionDate": _fmt_date(b.production_date),
|
||||
"materialId": b.material_id,
|
||||
"materialType": b.material_type or "",
|
||||
"materialCode": b.material_code or "",
|
||||
@@ -321,6 +332,7 @@ def _create_batch_and_usage(
|
||||
commit: bool = False,
|
||||
source_type: str = "manual_in",
|
||||
prep_id: Optional[str] = None,
|
||||
production_date: Optional[date] = None,
|
||||
) -> BizProductionMaterialStockBatch:
|
||||
if qty <= 0:
|
||||
raise ValueError("入库数量必须大于0")
|
||||
@@ -351,6 +363,7 @@ def _create_batch_and_usage(
|
||||
stock_in_no=sno,
|
||||
stock_in_date=stock_in_date,
|
||||
expire_date=expire_date,
|
||||
production_date=production_date,
|
||||
catalog_no=catalog_no,
|
||||
batch_no=batch_no,
|
||||
manufacturer=manufacturer,
|
||||
@@ -417,6 +430,7 @@ def stock_in_one(
|
||||
qty: Decimal,
|
||||
remark: Optional[str] = None,
|
||||
storage_location: Optional[str] = None,
|
||||
production_date: Any = None,
|
||||
tenant_no: str,
|
||||
user_id: Optional[str] = None,
|
||||
operate_time: Optional[datetime] = None,
|
||||
@@ -440,6 +454,7 @@ def stock_in_one(
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
operate_time=op_time,
|
||||
production_date=_parse_optional_date(production_date, label="生产日期"),
|
||||
commit=True,
|
||||
)
|
||||
return batch
|
||||
@@ -493,6 +508,10 @@ def batch_stock_in(
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
operate_time=op_time,
|
||||
production_date=_parse_optional_date(
|
||||
it.get("production_date") or it.get("productionDate"),
|
||||
label="生产日期",
|
||||
),
|
||||
commit=False,
|
||||
)
|
||||
db.commit()
|
||||
@@ -796,6 +815,7 @@ def update_batch(
|
||||
stock_in_no: Optional[str] = None,
|
||||
stock_in_date: Optional[Any] = None,
|
||||
expire_date: Optional[Any] = None,
|
||||
production_date: Optional[Any] = None,
|
||||
catalog_no: Optional[str] = None,
|
||||
batch_no: Optional[str] = None,
|
||||
manufacturer: Optional[str] = None,
|
||||
@@ -848,6 +868,8 @@ def update_batch(
|
||||
batch.stock_in_date = _parse_date(stock_in_date)
|
||||
if expire_date is not None:
|
||||
batch.expire_date = _parse_expire_date(expire_date)
|
||||
if production_date is not None:
|
||||
batch.production_date = _parse_optional_date(production_date, label="生产日期")
|
||||
if catalog_no is not None:
|
||||
batch.catalog_no = _require_str(catalog_no, "货号")
|
||||
if batch_no is not None:
|
||||
|
||||
@@ -8,7 +8,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||
from sqlalchemy import and_, func, or_
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.utils import generate_uuid, parse_datetime
|
||||
from app.core.utils import format_date, generate_uuid, parse_datetime
|
||||
from app.crud.equipment_snapshot import parse_equipment_ids, resolve_equipment_list_snapshot
|
||||
from app.models.models import (
|
||||
BizCellProduct,
|
||||
@@ -306,7 +306,7 @@ def _step_to_dict(s: BizProductionTaskStep) -> Dict[str, Any]:
|
||||
"actualDuration": s.actual_duration or "",
|
||||
"sopIds": s.sop_ids or "",
|
||||
"stepStatus": s.step_status or "dzx",
|
||||
"plannedStartTime": _fmt_dt(getattr(s, "planned_start_time", None)),
|
||||
"plannedStartTime": format_date(getattr(s, "planned_start_time", None)) or "",
|
||||
"startedTime": _fmt_dt(s.started_time),
|
||||
"completedTime": _fmt_dt(s.completed_time),
|
||||
"completedBy": getattr(s, "completed_by", None) or "",
|
||||
@@ -2621,3 +2621,187 @@ def total_pages(total: int, page_size: int) -> int:
|
||||
if total <= 0:
|
||||
return 0
|
||||
return int(math.ceil(total / float(page_size)))
|
||||
|
||||
|
||||
_PRODUCTION_TAB_STEP_COUNT_KEYS = (
|
||||
"inbound_cell_storage",
|
||||
"inbound_research_donation",
|
||||
"outbound_pilot_service",
|
||||
"outbound_basic_experiment",
|
||||
"temporary",
|
||||
)
|
||||
|
||||
|
||||
def _empty_production_tab_step_counts() -> Dict[str, Dict[str, int]]:
|
||||
return {
|
||||
k: {"overdueIncomplete": 0, "unassigned": 0}
|
||||
for k in _PRODUCTION_TAB_STEP_COUNT_KEYS
|
||||
}
|
||||
|
||||
|
||||
def _resolve_production_tab_key(
|
||||
wo_type: Optional[str],
|
||||
reception_source: Optional[str],
|
||||
biz_type: Optional[str],
|
||||
) -> Optional[str]:
|
||||
wt = (wo_type or "inbound").strip() or "inbound"
|
||||
if wt == "temporary":
|
||||
return "temporary"
|
||||
if wt == "outbound":
|
||||
bt = (biz_type or "pilot_service").strip() or "pilot_service"
|
||||
if bt == "basic_experiment":
|
||||
return "outbound_basic_experiment"
|
||||
if bt == "clinical_application":
|
||||
return None
|
||||
return "outbound_pilot_service"
|
||||
rs = (reception_source or "cell_storage").strip() or "cell_storage"
|
||||
return "inbound_research_donation" if rs == "research_donation" else "inbound_cell_storage"
|
||||
|
||||
|
||||
def _aggregate_production_tab_step_field(
|
||||
counts: Dict[str, Dict[str, int]],
|
||||
rows,
|
||||
field: str,
|
||||
) -> None:
|
||||
for wo_type, rs, bt, cnt in rows:
|
||||
tab_key = _resolve_production_tab_key(wo_type, rs, bt)
|
||||
if not tab_key or tab_key not in counts:
|
||||
continue
|
||||
counts[tab_key][field] += int(cnt or 0)
|
||||
|
||||
|
||||
def _base_active_step_count_query(
|
||||
db: Session,
|
||||
*,
|
||||
tenant_no: str,
|
||||
user_info=None,
|
||||
mine_user_id: Optional[str] = None,
|
||||
):
|
||||
q = (
|
||||
db.query(
|
||||
BizProductionWorkOrder.work_order_type,
|
||||
BizProductionWorkOrder.reception_source,
|
||||
BizProductionWorkOrder.biz_type,
|
||||
func.count(BizProductionTaskStep.id),
|
||||
)
|
||||
.select_from(BizProductionTaskStep)
|
||||
.join(
|
||||
BizProductionTask,
|
||||
and_(
|
||||
BizProductionTask.id == BizProductionTaskStep.task_id,
|
||||
BizProductionTask.del_flag == 0,
|
||||
BizProductionTask.tenant_no == tenant_no,
|
||||
),
|
||||
)
|
||||
.join(
|
||||
BizProductionWorkOrder,
|
||||
and_(
|
||||
BizProductionWorkOrder.id == BizProductionTask.work_order_id,
|
||||
BizProductionWorkOrder.del_flag == 0,
|
||||
BizProductionWorkOrder.tenant_no == tenant_no,
|
||||
),
|
||||
)
|
||||
.filter(
|
||||
BizProductionTaskStep.del_flag == 0,
|
||||
BizProductionTaskStep.tenant_no == tenant_no,
|
||||
BizProductionWorkOrder.work_order_status.in_(("dpz", "jxz")),
|
||||
BizProductionTask.task_status.in_(("dpz", "jxz")),
|
||||
BizProductionTaskStep.step_status != "ywc",
|
||||
)
|
||||
)
|
||||
if user_info:
|
||||
from app.core.data_scope import apply_data_scope
|
||||
|
||||
q = apply_data_scope(q, BizProductionWorkOrder, user_info, db, tenant_no)
|
||||
|
||||
uid = (mine_user_id or "").strip()
|
||||
if uid:
|
||||
step_task_ids = (
|
||||
db.query(BizProductionTaskStep.task_id)
|
||||
.join(
|
||||
BizProductionTaskStepAssignee,
|
||||
BizProductionTaskStepAssignee.step_id == BizProductionTaskStep.id,
|
||||
)
|
||||
.filter(
|
||||
BizProductionTaskStepAssignee.user_id == uid,
|
||||
BizProductionTaskStepAssignee.tenant_no == tenant_no,
|
||||
BizProductionTaskStepAssignee.del_flag == 0,
|
||||
BizProductionTaskStep.del_flag == 0,
|
||||
)
|
||||
.distinct()
|
||||
.subquery()
|
||||
)
|
||||
q = q.filter(
|
||||
or_(
|
||||
BizProductionTask.id.in_(step_task_ids),
|
||||
BizProductionTask.current_assignee_user_id == uid,
|
||||
)
|
||||
)
|
||||
return q
|
||||
|
||||
|
||||
def count_step_tab_badges_by_tab(
|
||||
db: Session,
|
||||
*,
|
||||
tenant_no: str,
|
||||
user_info=None,
|
||||
mine_user_id: Optional[str] = None,
|
||||
) -> Dict[str, Dict[str, int]]:
|
||||
"""按 Tab 统计工艺步骤角标:计划开始已到期未完成数 + 未安排负责人数。"""
|
||||
counts = _empty_production_tab_step_counts()
|
||||
today_end = datetime.now().replace(hour=23, minute=59, second=59, microsecond=0)
|
||||
|
||||
overdue_rows = (
|
||||
_base_active_step_count_query(
|
||||
db, tenant_no=tenant_no, user_info=user_info, mine_user_id=mine_user_id
|
||||
)
|
||||
.filter(
|
||||
BizProductionTaskStep.planned_start_time.isnot(None),
|
||||
BizProductionTaskStep.planned_start_time <= today_end,
|
||||
)
|
||||
.group_by(
|
||||
BizProductionWorkOrder.work_order_type,
|
||||
BizProductionWorkOrder.reception_source,
|
||||
BizProductionWorkOrder.biz_type,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
_aggregate_production_tab_step_field(counts, overdue_rows, "overdueIncomplete")
|
||||
|
||||
assignee_exists = (
|
||||
db.query(BizProductionTaskStepAssignee.id)
|
||||
.filter(
|
||||
BizProductionTaskStepAssignee.step_id == BizProductionTaskStep.id,
|
||||
BizProductionTaskStepAssignee.tenant_no == tenant_no,
|
||||
BizProductionTaskStepAssignee.del_flag == 0,
|
||||
)
|
||||
.exists()
|
||||
)
|
||||
unassigned_rows = (
|
||||
_base_active_step_count_query(
|
||||
db, tenant_no=tenant_no, user_info=user_info, mine_user_id=mine_user_id
|
||||
)
|
||||
.filter(~assignee_exists)
|
||||
.group_by(
|
||||
BizProductionWorkOrder.work_order_type,
|
||||
BizProductionWorkOrder.reception_source,
|
||||
BizProductionWorkOrder.biz_type,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
_aggregate_production_tab_step_field(counts, unassigned_rows, "unassigned")
|
||||
return counts
|
||||
|
||||
|
||||
def count_production_work_order_tab_step_badges(
|
||||
db: Session, *, tenant_no: str, user_info=None
|
||||
) -> Dict[str, Dict[str, int]]:
|
||||
return count_step_tab_badges_by_tab(db, tenant_no=tenant_no, user_info=user_info)
|
||||
|
||||
|
||||
def count_mine_production_work_order_tab_step_badges(
|
||||
db: Session, *, tenant_no: str, assignee_user_id: str
|
||||
) -> Dict[str, Dict[str, int]]:
|
||||
return count_step_tab_badges_by_tab(
|
||||
db, tenant_no=tenant_no, mine_user_id=assignee_user_id
|
||||
)
|
||||
@@ -0,0 +1,848 @@
|
||||
"""质检工单检测批次 CRUD"""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from typing import Any, Dict, List, Optional, Set, Tuple
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.utils import generate_uuid
|
||||
from app.crud import qc_lab_test_item as lab_item_svc
|
||||
from app.crud import qc_task as task_svc
|
||||
from app.crud import qc_task_assignee as assignee_svc
|
||||
from app.crud import qc_third_party_item as third_item_svc
|
||||
from app.crud.qc_third_party_company import get_company
|
||||
from app.models.models import (
|
||||
BizQcBatchAssignee,
|
||||
BizQcTask,
|
||||
BizQcWorkOrder,
|
||||
BizQcWorkOrderInspectionBatch,
|
||||
BizQcWorkOrderLabItem,
|
||||
BizQcWorkOrderThirdItem,
|
||||
SysUser,
|
||||
)
|
||||
|
||||
|
||||
def _dec(v) -> float:
|
||||
if v is None:
|
||||
return 0.0
|
||||
return float(v)
|
||||
|
||||
|
||||
def _unique_ids(ids: List[str]) -> List[str]:
|
||||
seen: Set[str] = set()
|
||||
out: List[str] = []
|
||||
for x in ids:
|
||||
v = (x or "").strip()
|
||||
if not v or v in seen:
|
||||
continue
|
||||
seen.add(v)
|
||||
out.append(v)
|
||||
return out
|
||||
|
||||
|
||||
def _validate_batch_payload(batch: Dict[str, Any], index: int) -> None:
|
||||
label = f"批次 {index + 1}"
|
||||
batch_name = (batch.get("batchName") or batch.get("batch_name") or "").strip()
|
||||
lab_ids = _unique_ids(batch.get("labItemIds") or batch.get("lab_item_ids") or [])
|
||||
third_ids = _unique_ids(batch.get("thirdPartyItemIds") or batch.get("third_party_item_ids") or [])
|
||||
assignees = batch.get("assigneeUserIds") or batch.get("assignee_user_ids") or []
|
||||
has_lab = bool(batch.get("hasLab") or batch.get("has_lab")) or bool(lab_ids)
|
||||
has_third = bool(batch.get("hasThirdParty") or batch.get("has_third_party")) or bool(third_ids)
|
||||
if not batch_name:
|
||||
raise ValueError(f"{label}:请填写批次名称")
|
||||
if not has_lab and not has_third:
|
||||
raise ValueError(f"{label}:请至少选择一项检测项目")
|
||||
if has_lab and not lab_ids:
|
||||
raise ValueError(f"{label}:请选择实验室自检项目")
|
||||
if has_third and not third_ids:
|
||||
raise ValueError(f"{label}:请选择第三方检测项目")
|
||||
if len(lab_ids) != len(set(lab_ids)):
|
||||
raise ValueError(f"{label}:实验室项目不能重复")
|
||||
if len(third_ids) != len(set(third_ids)):
|
||||
raise ValueError(f"{label}:第三方项目不能重复")
|
||||
if not assignees:
|
||||
raise ValueError(f"{label}:请指定负责人")
|
||||
|
||||
|
||||
def _order_source_for_wo(wo: BizQcWorkOrder) -> str:
|
||||
wo_type = getattr(wo, "work_order_type", None) or "inbound"
|
||||
if wo_type == "temporary":
|
||||
return "temporary"
|
||||
if wo_type == "outbound":
|
||||
return "outbound"
|
||||
return "inbound"
|
||||
|
||||
|
||||
def _next_batch_no(db: Session, wo: BizQcWorkOrder, tenant_no: str) -> str:
|
||||
prefix = f"{wo.work_order_no}-B"
|
||||
rows = (
|
||||
db.query(BizQcWorkOrderInspectionBatch.batch_no)
|
||||
.filter(
|
||||
BizQcWorkOrderInspectionBatch.work_order_id == wo.id,
|
||||
BizQcWorkOrderInspectionBatch.tenant_no == tenant_no,
|
||||
BizQcWorkOrderInspectionBatch.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
max_seq = 0
|
||||
for (bn,) in rows:
|
||||
s = (bn or "")[len(prefix) :]
|
||||
if s.isdigit():
|
||||
max_seq = max(max_seq, int(s))
|
||||
return f"{prefix}{max_seq + 1:02d}"
|
||||
|
||||
|
||||
def _allocate_batch_name(db: Session, wo_id: str, tenant_no: str, day: datetime) -> str:
|
||||
base = day.strftime("%Y%m%d") + "检测"
|
||||
rows = (
|
||||
db.query(BizQcWorkOrderInspectionBatch.batch_name)
|
||||
.filter(
|
||||
BizQcWorkOrderInspectionBatch.work_order_id == wo_id,
|
||||
BizQcWorkOrderInspectionBatch.tenant_no == tenant_no,
|
||||
BizQcWorkOrderInspectionBatch.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
same_day = [n for (n,) in rows if (n or "").startswith(base)]
|
||||
if not same_day:
|
||||
return base
|
||||
if base not in same_day:
|
||||
return base
|
||||
suffix = 2
|
||||
while f"{base}-{suffix}" in same_day:
|
||||
suffix += 1
|
||||
return f"{base}-{suffix}"
|
||||
|
||||
|
||||
def sync_batch_assignees(
|
||||
db: Session,
|
||||
batch_id: str,
|
||||
user_ids: List[str],
|
||||
*,
|
||||
tenant_no: str,
|
||||
operator_id: Optional[str],
|
||||
create_dept_id: str = "",
|
||||
) -> List[str]:
|
||||
normalized = assignee_svc.validate_assignee_user_ids(db, user_ids, tenant_no)
|
||||
now = datetime.now()
|
||||
existing = (
|
||||
db.query(BizQcBatchAssignee)
|
||||
.filter(
|
||||
BizQcBatchAssignee.batch_id == batch_id,
|
||||
BizQcBatchAssignee.tenant_no == tenant_no,
|
||||
BizQcBatchAssignee.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
keep = set(normalized)
|
||||
for row in existing:
|
||||
if row.user_id not in keep:
|
||||
row.del_flag = 1
|
||||
row.update_by = operator_id
|
||||
row.update_time = now
|
||||
for idx, uid in enumerate(normalized):
|
||||
hit = next((r for r in existing if r.user_id == uid and r.del_flag == 0), None)
|
||||
if hit:
|
||||
continue
|
||||
db.add(
|
||||
BizQcBatchAssignee(
|
||||
id=generate_uuid(),
|
||||
batch_id=batch_id,
|
||||
user_id=uid,
|
||||
tenant_no=tenant_no,
|
||||
order_num=idx,
|
||||
create_by=operator_id,
|
||||
create_dept_id=create_dept_id or "",
|
||||
create_time=now,
|
||||
update_by=operator_id,
|
||||
update_time=now,
|
||||
del_flag=0,
|
||||
)
|
||||
)
|
||||
db.flush()
|
||||
return normalized
|
||||
|
||||
|
||||
def _batch_assignee_user_ids(db: Session, batch_id: str, tenant_no: str) -> List[str]:
|
||||
rows = (
|
||||
db.query(BizQcBatchAssignee.user_id)
|
||||
.filter(
|
||||
BizQcBatchAssignee.batch_id == batch_id,
|
||||
BizQcBatchAssignee.tenant_no == tenant_no,
|
||||
BizQcBatchAssignee.del_flag == 0,
|
||||
)
|
||||
.order_by(BizQcBatchAssignee.order_num.asc())
|
||||
.all()
|
||||
)
|
||||
return [r[0] for r in rows]
|
||||
|
||||
|
||||
def _assignee_names(db: Session, user_ids: List[str]) -> str:
|
||||
if not user_ids:
|
||||
return ""
|
||||
rows = (
|
||||
db.query(SysUser.id, SysUser.nick_name, SysUser.user_no)
|
||||
.filter(SysUser.id.in_(user_ids), SysUser.del_flag == 0)
|
||||
.all()
|
||||
)
|
||||
name_map = {r.id: (r.nick_name or r.user_no or r.id) for r in rows}
|
||||
return "、".join(name_map.get(uid, uid) for uid in user_ids)
|
||||
|
||||
|
||||
def _apply_assignees_to_batch_tasks(
|
||||
db: Session,
|
||||
batch_id: str,
|
||||
user_ids: List[str],
|
||||
*,
|
||||
tenant_no: str,
|
||||
operator_id: Optional[str],
|
||||
create_dept_id: str,
|
||||
) -> None:
|
||||
tasks = (
|
||||
db.query(BizQcTask)
|
||||
.filter(
|
||||
BizQcTask.batch_id == batch_id,
|
||||
BizQcTask.tenant_no == tenant_no,
|
||||
BizQcTask.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
for task in tasks:
|
||||
assignee_svc.sync_assignees_for_task(
|
||||
db,
|
||||
task.id,
|
||||
user_ids,
|
||||
tenant_no=tenant_no,
|
||||
operator_id=operator_id,
|
||||
create_dept_id=create_dept_id,
|
||||
)
|
||||
|
||||
|
||||
def _batch_has_blocking_tasks(db: Session, batch_id: str, tenant_no: str) -> bool:
|
||||
return (
|
||||
db.query(BizQcTask)
|
||||
.filter(
|
||||
BizQcTask.batch_id == batch_id,
|
||||
BizQcTask.tenant_no == tenant_no,
|
||||
BizQcTask.del_flag == 0,
|
||||
BizQcTask.task_status.in_(["jxz", "ywc"]),
|
||||
)
|
||||
.first()
|
||||
is not None
|
||||
)
|
||||
|
||||
|
||||
def _soft_delete_batch(
|
||||
db: Session,
|
||||
batch: BizQcWorkOrderInspectionBatch,
|
||||
*,
|
||||
tenant_no: str,
|
||||
user_id: Optional[str],
|
||||
) -> None:
|
||||
from app.crud.qc_work_order import _soft_delete_tasks_by_source_line_ids
|
||||
|
||||
if _batch_has_blocking_tasks(db, batch.id, tenant_no):
|
||||
raise ValueError(f"批次「{batch.batch_name}」存在进行中或已完成任务,无法删除")
|
||||
now = datetime.now()
|
||||
lab_lines = (
|
||||
db.query(BizQcWorkOrderLabItem)
|
||||
.filter(
|
||||
BizQcWorkOrderLabItem.batch_id == batch.id,
|
||||
BizQcWorkOrderLabItem.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
third_lines = (
|
||||
db.query(BizQcWorkOrderThirdItem)
|
||||
.filter(
|
||||
BizQcWorkOrderThirdItem.batch_id == batch.id,
|
||||
BizQcWorkOrderThirdItem.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
line_ids = [r.id for r in lab_lines + third_lines]
|
||||
for line in lab_lines + third_lines:
|
||||
line.del_flag = 1
|
||||
line.update_by = user_id
|
||||
line.update_time = now
|
||||
_soft_delete_tasks_by_source_line_ids(db, line_ids, tenant_no)
|
||||
assignees = (
|
||||
db.query(BizQcBatchAssignee)
|
||||
.filter(BizQcBatchAssignee.batch_id == batch.id, BizQcBatchAssignee.del_flag == 0)
|
||||
.all()
|
||||
)
|
||||
for a in assignees:
|
||||
a.del_flag = 1
|
||||
a.update_by = user_id
|
||||
a.update_time = now
|
||||
batch.del_flag = 1
|
||||
batch.update_by = user_id
|
||||
batch.update_time = now
|
||||
|
||||
|
||||
def _sync_batch_lab_items(
|
||||
db: Session,
|
||||
wo: BizQcWorkOrder,
|
||||
batch: BizQcWorkOrderInspectionBatch,
|
||||
*,
|
||||
order_source: str,
|
||||
lab_item_ids: List[str],
|
||||
assignee_user_ids: List[str],
|
||||
tenant_no: str,
|
||||
user_id: Optional[str],
|
||||
create_dept_id: str,
|
||||
seq_start: int,
|
||||
) -> int:
|
||||
from app.crud.qc_work_order import _get_task_by_source_line_id, _soft_delete_tasks_by_source_line_ids
|
||||
|
||||
now = datetime.now()
|
||||
existing_rows = (
|
||||
db.query(BizQcWorkOrderLabItem)
|
||||
.filter(
|
||||
BizQcWorkOrderLabItem.batch_id == batch.id,
|
||||
BizQcWorkOrderLabItem.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
existing_by_item_id = {r.lab_test_item_id: r for r in existing_rows}
|
||||
new_id_set = set(lab_item_ids)
|
||||
old_id_set = set(existing_by_item_id.keys())
|
||||
|
||||
for item_id in old_id_set - new_id_set:
|
||||
line = existing_by_item_id[item_id]
|
||||
task = _get_task_by_source_line_id(db, line.id, tenant_no)
|
||||
if task and (task.task_status or "") in ("jxz", "ywc"):
|
||||
raise ValueError(f"项目「{line.item_name}」任务进行中或已完成,无法移除")
|
||||
line.del_flag = 1
|
||||
line.update_by = user_id
|
||||
line.update_time = now
|
||||
db.add(line)
|
||||
remove_line_ids = [existing_by_item_id[i].id for i in old_id_set - new_id_set]
|
||||
_soft_delete_tasks_by_source_line_ids(db, remove_line_ids, tenant_no)
|
||||
|
||||
seq = seq_start
|
||||
for lid in lab_item_ids:
|
||||
seq += 1
|
||||
if lid in existing_by_item_id and lid in new_id_set:
|
||||
line = existing_by_item_id[lid]
|
||||
line.order_num = seq
|
||||
line.update_by = user_id
|
||||
line.update_time = now
|
||||
db.add(line)
|
||||
task = _get_task_by_source_line_id(db, line.id, tenant_no)
|
||||
if task:
|
||||
task.order_num = seq
|
||||
task.batch_id = batch.id
|
||||
task.update_by = user_id
|
||||
task.update_time = now
|
||||
db.add(task)
|
||||
else:
|
||||
task = task_svc.create_task_for_line(
|
||||
db,
|
||||
work_order=wo,
|
||||
task_type="sysz",
|
||||
source_line_id=line.id,
|
||||
item_code=line.item_code,
|
||||
item_name=line.item_name,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
seq=seq,
|
||||
order_source=order_source,
|
||||
batch_id=batch.id,
|
||||
)
|
||||
assignee_svc.sync_assignees_for_task(
|
||||
db,
|
||||
task.id,
|
||||
assignee_user_ids,
|
||||
tenant_no=tenant_no,
|
||||
operator_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
)
|
||||
continue
|
||||
|
||||
item = lab_item_svc.get_lab_item(db, lid, tenant_no=tenant_no)
|
||||
if not item or item.status != "1":
|
||||
raise ValueError("实验室项目无效或已停用")
|
||||
line = BizQcWorkOrderLabItem(
|
||||
id=generate_uuid(),
|
||||
work_order_id=wo.id,
|
||||
order_source=order_source,
|
||||
batch_id=batch.id,
|
||||
lab_test_item_id=item.id,
|
||||
item_code=item.item_code,
|
||||
item_name=item.item_name,
|
||||
tenant_no=tenant_no,
|
||||
order_num=seq,
|
||||
create_by=user_id,
|
||||
create_dept_id=create_dept_id or "",
|
||||
create_time=now,
|
||||
update_by=user_id,
|
||||
update_time=now,
|
||||
del_flag=0,
|
||||
)
|
||||
db.add(line)
|
||||
db.flush()
|
||||
task = task_svc.create_task_for_line(
|
||||
db,
|
||||
work_order=wo,
|
||||
task_type="sysz",
|
||||
source_line_id=line.id,
|
||||
item_code=line.item_code,
|
||||
item_name=line.item_name,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
seq=seq,
|
||||
order_source=order_source,
|
||||
batch_id=batch.id,
|
||||
)
|
||||
assignee_svc.sync_assignees_for_task(
|
||||
db,
|
||||
task.id,
|
||||
assignee_user_ids,
|
||||
tenant_no=tenant_no,
|
||||
operator_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
)
|
||||
return seq
|
||||
|
||||
|
||||
def _sync_batch_third_items(
|
||||
db: Session,
|
||||
wo: BizQcWorkOrder,
|
||||
batch: BizQcWorkOrderInspectionBatch,
|
||||
*,
|
||||
order_source: str,
|
||||
third_party_item_ids: List[str],
|
||||
assignee_user_ids: List[str],
|
||||
tenant_no: str,
|
||||
user_id: Optional[str],
|
||||
create_dept_id: str,
|
||||
seq_start: int,
|
||||
) -> Tuple[int, Decimal]:
|
||||
from app.crud.qc_work_order import _get_task_by_source_line_id, _soft_delete_tasks_by_source_line_ids
|
||||
|
||||
now = datetime.now()
|
||||
existing_rows = (
|
||||
db.query(BizQcWorkOrderThirdItem)
|
||||
.filter(
|
||||
BizQcWorkOrderThirdItem.batch_id == batch.id,
|
||||
BizQcWorkOrderThirdItem.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
existing_by_item_id = {r.third_party_item_id: r for r in existing_rows}
|
||||
new_id_set = set(third_party_item_ids)
|
||||
old_id_set = set(existing_by_item_id.keys())
|
||||
|
||||
for item_id in old_id_set - new_id_set:
|
||||
line = existing_by_item_id[item_id]
|
||||
task = _get_task_by_source_line_id(db, line.id, tenant_no)
|
||||
if task and (task.task_status or "") in ("jxz", "ywc"):
|
||||
raise ValueError(f"项目「{line.item_name}」任务进行中或已完成,无法移除")
|
||||
line.del_flag = 1
|
||||
line.update_by = user_id
|
||||
line.update_time = now
|
||||
db.add(line)
|
||||
remove_line_ids = [existing_by_item_id[i].id for i in old_id_set - new_id_set]
|
||||
_soft_delete_tasks_by_source_line_ids(db, remove_line_ids, tenant_no)
|
||||
|
||||
fee_total = Decimal("0")
|
||||
seq = seq_start
|
||||
for tid in third_party_item_ids:
|
||||
seq += 1
|
||||
if tid in existing_by_item_id and tid in new_id_set:
|
||||
line = existing_by_item_id[tid]
|
||||
line.order_num = seq
|
||||
line.update_by = user_id
|
||||
line.update_time = now
|
||||
db.add(line)
|
||||
fee_total += line.fee_amount or Decimal("0")
|
||||
task = _get_task_by_source_line_id(db, line.id, tenant_no)
|
||||
if task:
|
||||
task.order_num = seq
|
||||
task.batch_id = batch.id
|
||||
task.update_by = user_id
|
||||
task.update_time = now
|
||||
db.add(task)
|
||||
else:
|
||||
task = task_svc.create_task_for_line(
|
||||
db,
|
||||
work_order=wo,
|
||||
task_type="dsfjc",
|
||||
source_line_id=line.id,
|
||||
item_code=line.item_code,
|
||||
item_name=line.item_name,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
seq=seq,
|
||||
company_id=line.company_id,
|
||||
company_name=line.company_name,
|
||||
fee_amount=line.fee_amount,
|
||||
order_source=order_source,
|
||||
batch_id=batch.id,
|
||||
)
|
||||
assignee_svc.sync_assignees_for_task(
|
||||
db,
|
||||
task.id,
|
||||
assignee_user_ids,
|
||||
tenant_no=tenant_no,
|
||||
operator_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
)
|
||||
continue
|
||||
|
||||
item = third_item_svc.get_item(db, tid, tenant_no=tenant_no)
|
||||
if not item or item.status != "1":
|
||||
raise ValueError("第三方项目无效或已停用")
|
||||
comp = get_company(db, item.company_id, tenant_no=tenant_no)
|
||||
if not comp:
|
||||
raise ValueError("第三方公司不存在")
|
||||
fee = item.fee_amount or Decimal("0")
|
||||
fee_total += fee
|
||||
line = BizQcWorkOrderThirdItem(
|
||||
id=generate_uuid(),
|
||||
work_order_id=wo.id,
|
||||
order_source=order_source,
|
||||
batch_id=batch.id,
|
||||
third_party_item_id=item.id,
|
||||
company_id=item.company_id,
|
||||
company_name=comp.company_name,
|
||||
item_code=item.item_code,
|
||||
item_name=item.item_name,
|
||||
fee_amount=fee,
|
||||
tenant_no=tenant_no,
|
||||
order_num=seq,
|
||||
create_by=user_id,
|
||||
create_dept_id=create_dept_id or "",
|
||||
create_time=now,
|
||||
update_by=user_id,
|
||||
update_time=now,
|
||||
del_flag=0,
|
||||
)
|
||||
db.add(line)
|
||||
db.flush()
|
||||
task = task_svc.create_task_for_line(
|
||||
db,
|
||||
work_order=wo,
|
||||
task_type="dsfjc",
|
||||
source_line_id=line.id,
|
||||
item_code=line.item_code,
|
||||
item_name=line.item_name,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
seq=seq,
|
||||
company_id=line.company_id,
|
||||
company_name=line.company_name,
|
||||
fee_amount=line.fee_amount,
|
||||
order_source=order_source,
|
||||
batch_id=batch.id,
|
||||
)
|
||||
assignee_svc.sync_assignees_for_task(
|
||||
db,
|
||||
task.id,
|
||||
assignee_user_ids,
|
||||
tenant_no=tenant_no,
|
||||
operator_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
)
|
||||
return seq, fee_total
|
||||
|
||||
|
||||
def _batch_item_ids(db: Session, batch_id: str) -> Tuple[List[str], List[str]]:
|
||||
lab_ids = [
|
||||
r.lab_test_item_id
|
||||
for r in db.query(BizQcWorkOrderLabItem)
|
||||
.filter(BizQcWorkOrderLabItem.batch_id == batch_id, BizQcWorkOrderLabItem.del_flag == 0)
|
||||
.order_by(BizQcWorkOrderLabItem.order_num.asc())
|
||||
.all()
|
||||
]
|
||||
third_ids = [
|
||||
r.third_party_item_id
|
||||
for r in db.query(BizQcWorkOrderThirdItem)
|
||||
.filter(
|
||||
BizQcWorkOrderThirdItem.batch_id == batch_id,
|
||||
BizQcWorkOrderThirdItem.del_flag == 0,
|
||||
)
|
||||
.order_by(BizQcWorkOrderThirdItem.order_num.asc())
|
||||
.all()
|
||||
]
|
||||
return lab_ids, third_ids
|
||||
|
||||
|
||||
def _batch_to_dict(
|
||||
db: Session,
|
||||
batch: BizQcWorkOrderInspectionBatch,
|
||||
*,
|
||||
tenant_no: str,
|
||||
tasks: Optional[List[Dict[str, Any]]] = None,
|
||||
) -> Dict[str, Any]:
|
||||
assignee_ids = _batch_assignee_user_ids(db, batch.id, tenant_no)
|
||||
lab_ids, third_ids = _batch_item_ids(db, batch.id)
|
||||
task_list = tasks or []
|
||||
completed = sum(1 for t in task_list if (t.get("taskStatus") or "") == "ywc")
|
||||
return {
|
||||
"id": batch.id,
|
||||
"workOrderId": batch.work_order_id,
|
||||
"batchNo": batch.batch_no,
|
||||
"batchName": batch.batch_name,
|
||||
"orderNum": batch.order_num or 0,
|
||||
"assigneeUserIds": assignee_ids,
|
||||
"assigneeUserNames": _assignee_names(db, assignee_ids),
|
||||
"hasLab": bool(lab_ids),
|
||||
"hasThirdParty": bool(third_ids),
|
||||
"labItemIds": lab_ids,
|
||||
"thirdPartyItemIds": third_ids,
|
||||
"taskCount": len(task_list),
|
||||
"completedTaskCount": completed,
|
||||
"tasks": task_list,
|
||||
}
|
||||
|
||||
|
||||
def list_inspection_batches(
|
||||
db: Session, work_order_id: str, tenant_no: str, *, user_info=None
|
||||
) -> List[Dict[str, Any]]:
|
||||
batches = (
|
||||
db.query(BizQcWorkOrderInspectionBatch)
|
||||
.filter(
|
||||
BizQcWorkOrderInspectionBatch.work_order_id == work_order_id,
|
||||
BizQcWorkOrderInspectionBatch.tenant_no == tenant_no,
|
||||
BizQcWorkOrderInspectionBatch.del_flag == 0,
|
||||
)
|
||||
.order_by(BizQcWorkOrderInspectionBatch.order_num.asc())
|
||||
.all()
|
||||
)
|
||||
all_tasks = task_svc.list_tasks_by_work_order(db, work_order_id, tenant_no)
|
||||
tasks_by_batch: Dict[str, List[Dict[str, Any]]] = {}
|
||||
orphan: List[Dict[str, Any]] = []
|
||||
batch_ids = {b.id for b in batches}
|
||||
for t in all_tasks:
|
||||
bid = t.get("batchId") or ""
|
||||
if bid and bid in batch_ids:
|
||||
tasks_by_batch.setdefault(bid, []).append(t)
|
||||
else:
|
||||
orphan.append(t)
|
||||
out = [_batch_to_dict(db, b, tenant_no=tenant_no, tasks=tasks_by_batch.get(b.id, [])) for b in batches]
|
||||
if orphan and out:
|
||||
out[0]["tasks"] = orphan + out[0]["tasks"]
|
||||
out[0]["taskCount"] = len(out[0]["tasks"])
|
||||
out[0]["completedTaskCount"] = sum(
|
||||
1 for t in out[0]["tasks"] if (t.get("taskStatus") or "") == "ywc"
|
||||
)
|
||||
elif orphan:
|
||||
out.append(
|
||||
{
|
||||
"id": "",
|
||||
"workOrderId": work_order_id,
|
||||
"batchNo": "—",
|
||||
"batchName": "历史任务",
|
||||
"orderNum": 0,
|
||||
"assigneeUserIds": [],
|
||||
"assigneeUserNames": "",
|
||||
"taskCount": len(orphan),
|
||||
"completedTaskCount": sum(1 for t in orphan if (t.get("taskStatus") or "") == "ywc"),
|
||||
"tasks": orphan,
|
||||
}
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
def configure_work_order_batches(
|
||||
db: Session,
|
||||
wo: BizQcWorkOrder,
|
||||
batches: List[Dict[str, Any]],
|
||||
*,
|
||||
tenant_no: str,
|
||||
user_id: Optional[str],
|
||||
create_dept_id: str = "",
|
||||
) -> BizQcWorkOrder:
|
||||
status = (wo.work_order_status or "").strip()
|
||||
if status not in ("dpz", "ypz"):
|
||||
raise ValueError("当前工单状态不可配置检测")
|
||||
if not batches:
|
||||
raise ValueError("请至少添加一个检测批次")
|
||||
|
||||
order_source = _order_source_for_wo(wo)
|
||||
now = datetime.now()
|
||||
is_first = status == "dpz"
|
||||
|
||||
for idx, b in enumerate(batches):
|
||||
_validate_batch_payload(b, idx)
|
||||
|
||||
existing_batches = {
|
||||
r.id: r
|
||||
for r in db.query(BizQcWorkOrderInspectionBatch)
|
||||
.filter(
|
||||
BizQcWorkOrderInspectionBatch.work_order_id == wo.id,
|
||||
BizQcWorkOrderInspectionBatch.tenant_no == tenant_no,
|
||||
BizQcWorkOrderInspectionBatch.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
}
|
||||
keep_batch_ids = {((b.get("id") or "").strip()) for b in batches if (b.get("id") or "").strip()}
|
||||
|
||||
for bid, batch_row in existing_batches.items():
|
||||
if bid not in keep_batch_ids:
|
||||
_soft_delete_batch(db, batch_row, tenant_no=tenant_no, user_id=user_id)
|
||||
|
||||
fee_total = Decimal("0")
|
||||
has_lab = False
|
||||
has_third = False
|
||||
global_seq = 0
|
||||
|
||||
for batch_idx, payload in enumerate(batches):
|
||||
batch_id = (payload.get("id") or "").strip()
|
||||
lab_ids = _unique_ids(payload.get("labItemIds") or payload.get("lab_item_ids") or [])
|
||||
third_ids = _unique_ids(payload.get("thirdPartyItemIds") or payload.get("third_party_item_ids") or [])
|
||||
has_lab_batch = bool(lab_ids) or bool(payload.get("hasLab") or payload.get("has_lab"))
|
||||
has_third_batch = bool(third_ids) or bool(payload.get("hasThirdParty") or payload.get("has_third_party"))
|
||||
assignee_ids = payload.get("assigneeUserIds") or payload.get("assignee_user_ids") or []
|
||||
normalized_assignees = assignee_svc.validate_assignee_user_ids(db, assignee_ids, tenant_no)
|
||||
batch_name = (payload.get("batchName") or payload.get("batch_name") or "").strip()
|
||||
|
||||
if batch_id and batch_id in existing_batches:
|
||||
batch = existing_batches[batch_id]
|
||||
batch.order_num = batch_idx + 1
|
||||
if batch_name:
|
||||
batch.batch_name = batch_name
|
||||
batch.update_by = user_id
|
||||
batch.update_time = now
|
||||
db.add(batch)
|
||||
else:
|
||||
batch = BizQcWorkOrderInspectionBatch(
|
||||
id=generate_uuid(),
|
||||
work_order_id=wo.id,
|
||||
order_source=order_source,
|
||||
batch_no=_next_batch_no(db, wo, tenant_no),
|
||||
batch_name=batch_name or _allocate_batch_name(db, wo.id, tenant_no, now),
|
||||
tenant_no=tenant_no,
|
||||
order_num=batch_idx + 1,
|
||||
create_by=user_id,
|
||||
create_dept_id=create_dept_id or "",
|
||||
create_time=now,
|
||||
update_by=user_id,
|
||||
update_time=now,
|
||||
del_flag=0,
|
||||
)
|
||||
db.add(batch)
|
||||
db.flush()
|
||||
|
||||
sync_batch_assignees(
|
||||
db,
|
||||
batch.id,
|
||||
normalized_assignees,
|
||||
tenant_no=tenant_no,
|
||||
operator_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
)
|
||||
|
||||
if has_lab_batch:
|
||||
has_lab = True
|
||||
global_seq = _sync_batch_lab_items(
|
||||
db,
|
||||
wo,
|
||||
batch,
|
||||
order_source=order_source,
|
||||
lab_item_ids=lab_ids,
|
||||
assignee_user_ids=normalized_assignees,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
seq_start=global_seq,
|
||||
)
|
||||
else:
|
||||
global_seq = _sync_batch_lab_items(
|
||||
db,
|
||||
wo,
|
||||
batch,
|
||||
order_source=order_source,
|
||||
lab_item_ids=[],
|
||||
assignee_user_ids=normalized_assignees,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
seq_start=global_seq,
|
||||
)
|
||||
|
||||
if has_third_batch:
|
||||
has_third = True
|
||||
global_seq, batch_fee = _sync_batch_third_items(
|
||||
db,
|
||||
wo,
|
||||
batch,
|
||||
order_source=order_source,
|
||||
third_party_item_ids=third_ids,
|
||||
assignee_user_ids=normalized_assignees,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
seq_start=global_seq,
|
||||
)
|
||||
fee_total += batch_fee
|
||||
else:
|
||||
global_seq, _ = _sync_batch_third_items(
|
||||
db,
|
||||
wo,
|
||||
batch,
|
||||
order_source=order_source,
|
||||
third_party_item_ids=[],
|
||||
assignee_user_ids=normalized_assignees,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
seq_start=global_seq,
|
||||
)
|
||||
|
||||
wo.has_lab = "1" if has_lab else "0"
|
||||
wo.has_third_party = "1" if has_third else "0"
|
||||
wo.work_order_status = "ypz"
|
||||
if is_first:
|
||||
wo.configured_time = now
|
||||
wo.configured_by = user_id
|
||||
wo.third_party_fee_total = fee_total if has_third else None
|
||||
wo.update_by = user_id
|
||||
wo.update_time = now
|
||||
db.add(wo)
|
||||
|
||||
from app.crud.pilot_outbound_status_sync import sync_schedule_from_qc_work_order
|
||||
|
||||
sync_schedule_from_qc_work_order(db, wo, user_id=user_id)
|
||||
db.commit()
|
||||
db.refresh(wo)
|
||||
return wo
|
||||
|
||||
|
||||
def normalize_legacy_configure_to_batches(body: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
"""将扁平 labItemIds 配置转为单批次结构。"""
|
||||
batches = body.get("batches")
|
||||
if batches:
|
||||
return batches
|
||||
has_lab = bool(body.get("hasLab") or body.get("has_lab"))
|
||||
has_third = bool(body.get("hasThirdParty") or body.get("has_third_party"))
|
||||
lab_ids = body.get("labItemIds") or body.get("lab_item_ids") or []
|
||||
third_ids = body.get("thirdPartyItemIds") or body.get("third_party_item_ids") or []
|
||||
lab_assignees = body.get("labItemAssignees") or body.get("lab_item_assignees") or {}
|
||||
third_assignees = body.get("thirdPartyItemAssignees") or body.get("third_party_item_assignees") or {}
|
||||
assignee_set: Set[str] = set()
|
||||
for lid in lab_ids:
|
||||
for uid in lab_assignees.get(lid) or []:
|
||||
if uid:
|
||||
assignee_set.add(uid)
|
||||
for tid in third_ids:
|
||||
for uid in third_assignees.get(tid) or []:
|
||||
if uid:
|
||||
assignee_set.add(uid)
|
||||
return [
|
||||
{
|
||||
"assigneeUserIds": list(assignee_set),
|
||||
"hasLab": has_lab,
|
||||
"hasThirdParty": has_third,
|
||||
"labItemIds": lab_ids,
|
||||
"thirdPartyItemIds": third_ids,
|
||||
}
|
||||
]
|
||||
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
@@ -16,11 +17,41 @@ def _row_to_dict(r: BizQcItemParam) -> Dict[str, Any]:
|
||||
"paramCode": r.param_code,
|
||||
"paramUnit": r.param_unit or "",
|
||||
"paramType": r.param_type or "text",
|
||||
"options": r.options or "",
|
||||
"defaultValue": r.default_value or "",
|
||||
"requiredFlag": r.required_flag or "0",
|
||||
"orderNum": r.order_num if r.order_num is not None else 0,
|
||||
}
|
||||
|
||||
|
||||
def _parse_options_list(options_raw: Any) -> List[str]:
|
||||
if not options_raw:
|
||||
return []
|
||||
if isinstance(options_raw, list):
|
||||
arr = options_raw
|
||||
else:
|
||||
try:
|
||||
arr = json.loads(str(options_raw))
|
||||
except json.JSONDecodeError:
|
||||
raise ValueError("单选选项格式无效")
|
||||
if not isinstance(arr, list):
|
||||
raise ValueError("单选选项格式无效")
|
||||
cleaned = [str(x).strip() for x in arr if str(x).strip()]
|
||||
return cleaned
|
||||
|
||||
|
||||
def _validate_param(p: Dict[str, Any], index: int) -> None:
|
||||
label = (p.get("paramName") or "").strip() or f"第{index + 1}个参数"
|
||||
param_type = (p.get("paramType") or "text").strip()
|
||||
if param_type != "select":
|
||||
return
|
||||
opts = _parse_options_list(p.get("options"))
|
||||
if not opts:
|
||||
raise ValueError(f"「{label}」为单选类型,请至少配置一个选项")
|
||||
if len(opts) != len(set(opts)):
|
||||
raise ValueError(f"「{label}」的选项不能重复")
|
||||
|
||||
|
||||
def list_params_by_item(
|
||||
db: Session, item_source: str, item_id: str, tenant_no: str, *, user_info=None
|
||||
) -> List[Dict[str, Any]]:
|
||||
@@ -45,6 +76,9 @@ def save_params_for_item(
|
||||
tenant_no: str,
|
||||
user_id: Optional[str] = None,
|
||||
) -> List[Dict[str, Any]]:
|
||||
for idx, p in enumerate(params):
|
||||
_validate_param(p, idx)
|
||||
|
||||
now = datetime.now()
|
||||
db.query(BizQcItemParam).filter(
|
||||
BizQcItemParam.item_source == item_source,
|
||||
@@ -58,6 +92,14 @@ def save_params_for_item(
|
||||
db.flush()
|
||||
|
||||
for idx, p in enumerate(params):
|
||||
param_type = (p.get("paramType") or "text").strip()
|
||||
options_val = None
|
||||
default_val = None
|
||||
if param_type == "select":
|
||||
opts = _parse_options_list(p.get("options"))
|
||||
options_val = json.dumps(opts, ensure_ascii=False)
|
||||
default_val = opts[0] if opts else None
|
||||
|
||||
obj = BizQcItemParam(
|
||||
id=generate_uuid(),
|
||||
item_source=item_source,
|
||||
@@ -65,7 +107,9 @@ def save_params_for_item(
|
||||
param_name=p.get("paramName", ""),
|
||||
param_code=p.get("paramCode", ""),
|
||||
param_unit=p.get("paramUnit") or None,
|
||||
param_type=p.get("paramType", "text"),
|
||||
param_type=param_type,
|
||||
options=options_val,
|
||||
default_value=default_val,
|
||||
required_flag=p.get("requiredFlag", "0"),
|
||||
tenant_no=tenant_no,
|
||||
order_num=p.get("orderNum", idx),
|
||||
|
||||
@@ -71,6 +71,7 @@ def _task_to_dict(
|
||||
return {
|
||||
"id": t.id,
|
||||
"workOrderId": t.work_order_id,
|
||||
"batchId": getattr(t, "batch_id", None) or "",
|
||||
"orderSource": getattr(t, "order_source", "inbound") or "inbound",
|
||||
"workOrderNo": work_order_no,
|
||||
"taskNo": t.task_no,
|
||||
@@ -266,10 +267,12 @@ def create_task_for_line(
|
||||
company_name: Optional[str] = None,
|
||||
fee_amount: Optional[Decimal] = None,
|
||||
order_source: str = "inbound",
|
||||
batch_id: Optional[str] = None,
|
||||
) -> BizQcTask:
|
||||
obj = BizQcTask(
|
||||
id=generate_uuid(),
|
||||
work_order_id=work_order.id,
|
||||
batch_id=batch_id,
|
||||
order_source=order_source,
|
||||
task_no=_gen_task_no(db, work_order, seq),
|
||||
task_type=task_type,
|
||||
|
||||
@@ -76,14 +76,21 @@ def _merge_saved_into_template(
|
||||
pid = p.get("id") or ""
|
||||
code = p.get("paramCode") or ""
|
||||
hit = by_id.get(pid) or (by_code.get(code) if code else None)
|
||||
saved_value = (hit.get("paramValue") if hit else "") or ""
|
||||
default_value = (p.get("defaultValue") or "").strip()
|
||||
param_type = p.get("paramType", "text")
|
||||
if not saved_value and param_type == "select" and default_value:
|
||||
saved_value = default_value
|
||||
out.append(
|
||||
{
|
||||
"paramId": pid,
|
||||
"paramName": p.get("paramName", ""),
|
||||
"paramCode": code,
|
||||
"paramUnit": p.get("paramUnit", ""),
|
||||
"paramType": p.get("paramType", "text"),
|
||||
"paramValue": (hit.get("paramValue") if hit else "") or "",
|
||||
"paramType": param_type,
|
||||
"options": p.get("options", ""),
|
||||
"defaultValue": default_value,
|
||||
"paramValue": saved_value,
|
||||
"requiredFlag": p.get("requiredFlag", "0"),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||
from sqlalchemy import and_, func, or_
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.db_collation import eq_unicode, like_unicode
|
||||
from app.core.db_collation import eq_unicode, like_unicode, unicode_ci
|
||||
from app.core.utils import generate_uuid
|
||||
from app.crud import qc_lab_test_item as lab_item_svc
|
||||
from app.crud import qc_task as task_svc
|
||||
@@ -39,6 +39,7 @@ from app.models.models import (
|
||||
BizOutputType,
|
||||
BizQcLabTestItem,
|
||||
BizQcTask,
|
||||
BizQcTaskAssignee,
|
||||
BizQcThirdPartyItem,
|
||||
BizQcWorkOrder,
|
||||
BizQcWorkOrderLabItem,
|
||||
@@ -1231,6 +1232,13 @@ def list_work_orders(
|
||||
wt = (work_order_type or "").strip()
|
||||
if wt:
|
||||
q0 = q0.filter(BizQcWorkOrder.work_order_type == wt)
|
||||
else:
|
||||
q0 = q0.filter(
|
||||
~and_(
|
||||
BizQcWorkOrder.work_order_type == "outbound",
|
||||
BizQcWorkOrder.biz_type == "clinical_application",
|
||||
)
|
||||
)
|
||||
bt = (biz_type or "").strip()
|
||||
if bt:
|
||||
q0 = q0.filter(BizQcWorkOrder.biz_type == bt)
|
||||
@@ -1239,8 +1247,23 @@ def list_work_orders(
|
||||
q0 = q0.filter(BizQcWorkOrder.reception_source == rs)
|
||||
ts = (trigger_source or "").strip()
|
||||
if ts:
|
||||
if ts == "manual" and wt == "temporary":
|
||||
if ts == "temp_manual":
|
||||
q0 = q0.filter(
|
||||
BizQcWorkOrder.work_order_type == "temporary",
|
||||
BizQcWorkOrder.trigger_source != "production",
|
||||
)
|
||||
elif ts == "temp_production":
|
||||
q0 = q0.filter(
|
||||
BizQcWorkOrder.work_order_type == "temporary",
|
||||
BizQcWorkOrder.trigger_source == "production",
|
||||
)
|
||||
elif ts == "manual" and wt == "temporary":
|
||||
q0 = q0.filter(BizQcWorkOrder.trigger_source != "production")
|
||||
elif ts == "production" and not wt:
|
||||
q0 = q0.filter(
|
||||
BizQcWorkOrder.trigger_source == "production",
|
||||
BizQcWorkOrder.work_order_type != "temporary",
|
||||
)
|
||||
else:
|
||||
q0 = q0.filter(BizQcWorkOrder.trigger_source == ts)
|
||||
kw = (keyword or "").strip()
|
||||
@@ -1249,6 +1272,7 @@ def list_work_orders(
|
||||
keyword_conditions = [
|
||||
BizQcWorkOrder.work_order_no.like(like),
|
||||
BizQcWorkOrder.sample_code.like(like),
|
||||
BizQcWorkOrder.protocol_no.like(like),
|
||||
]
|
||||
if tenant_no:
|
||||
from app.crud import sample_reception as reception_svc
|
||||
@@ -1263,7 +1287,7 @@ def list_work_orders(
|
||||
)
|
||||
if lab_codes:
|
||||
keyword_conditions.append(BizQcWorkOrder.sample_code.in_(lab_codes))
|
||||
if tenant_no and wt == "outbound":
|
||||
if tenant_no and (wt == "outbound" or not wt):
|
||||
outbound_ids = _outbound_qc_work_order_ids_by_keyword(db, tenant_no, kw)
|
||||
if outbound_ids:
|
||||
keyword_conditions.append(BizQcWorkOrder.id.in_(outbound_ids))
|
||||
@@ -1327,6 +1351,140 @@ def list_work_orders(
|
||||
return items, int(total)
|
||||
|
||||
|
||||
_QC_TAB_COUNT_KEYS = (
|
||||
"all",
|
||||
"inbound_cell_storage",
|
||||
"inbound_research_donation",
|
||||
"outbound_pilot_service",
|
||||
"outbound_basic_experiment",
|
||||
"temporary",
|
||||
)
|
||||
|
||||
|
||||
def _empty_qc_tab_counts() -> Dict[str, int]:
|
||||
return {k: 0 for k in _QC_TAB_COUNT_KEYS}
|
||||
|
||||
|
||||
def _resolve_wo_tab_key(
|
||||
wo_type: Optional[str],
|
||||
reception_source: Optional[str],
|
||||
biz_type: Optional[str],
|
||||
) -> str:
|
||||
wt = (wo_type or "inbound").strip() or "inbound"
|
||||
if wt == "temporary":
|
||||
return "temporary"
|
||||
if wt == "outbound":
|
||||
bt = (biz_type or "pilot_service").strip() or "pilot_service"
|
||||
if bt == "basic_experiment":
|
||||
return "outbound_basic_experiment"
|
||||
if bt == "clinical_application":
|
||||
return "outbound_clinical_application"
|
||||
return "outbound_pilot_service"
|
||||
rs = (reception_source or "cell_storage").strip() or "cell_storage"
|
||||
return "inbound_research_donation" if rs == "research_donation" else "inbound_cell_storage"
|
||||
|
||||
|
||||
def _unfinished_work_order_filter(q):
|
||||
return q.filter(
|
||||
BizQcWorkOrder.work_order_status.in_(("dpz", "ypz")),
|
||||
~and_(
|
||||
BizQcWorkOrder.work_order_type == "outbound",
|
||||
BizQcWorkOrder.biz_type == "clinical_application",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _aggregate_qc_tab_counts(rows) -> Dict[str, int]:
|
||||
counts = _empty_qc_tab_counts()
|
||||
for wo_type, rs, bt, cnt in rows:
|
||||
tab_key = _resolve_wo_tab_key(wo_type, rs, bt)
|
||||
if tab_key == "outbound_clinical_application":
|
||||
continue
|
||||
n = int(cnt or 0)
|
||||
counts[tab_key] = counts.get(tab_key, 0) + n
|
||||
counts["all"] += n
|
||||
return counts
|
||||
|
||||
|
||||
def count_unfinished_work_orders_by_tab(
|
||||
db: Session,
|
||||
*,
|
||||
tenant_no: str,
|
||||
user_info=None,
|
||||
) -> Dict[str, int]:
|
||||
"""按 Tab 统计未完成质检工单数(待配置 + 已配置)。"""
|
||||
q = db.query(BizQcWorkOrder).filter(
|
||||
BizQcWorkOrder.del_flag == 0,
|
||||
BizQcWorkOrder.tenant_no == tenant_no,
|
||||
)
|
||||
q = _unfinished_work_order_filter(q)
|
||||
if user_info:
|
||||
from app.core.data_scope import apply_data_scope
|
||||
|
||||
q = apply_data_scope(q, BizQcWorkOrder, user_info, db, tenant_no)
|
||||
rows = (
|
||||
q.with_entities(
|
||||
BizQcWorkOrder.work_order_type,
|
||||
BizQcWorkOrder.reception_source,
|
||||
BizQcWorkOrder.biz_type,
|
||||
func.count(BizQcWorkOrder.id),
|
||||
)
|
||||
.group_by(
|
||||
BizQcWorkOrder.work_order_type,
|
||||
BizQcWorkOrder.reception_source,
|
||||
BizQcWorkOrder.biz_type,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
return _aggregate_qc_tab_counts(rows)
|
||||
|
||||
|
||||
def count_mine_unfinished_work_orders_by_tab(
|
||||
db: Session,
|
||||
*,
|
||||
tenant_no: str,
|
||||
assignee_user_id: str,
|
||||
) -> Dict[str, int]:
|
||||
"""我的质检任务:按 Tab 统计当前用户负责且未完成的质检工单数。"""
|
||||
q = (
|
||||
db.query(
|
||||
BizQcWorkOrder.work_order_type,
|
||||
BizQcWorkOrder.reception_source,
|
||||
BizQcWorkOrder.biz_type,
|
||||
func.count(func.distinct(BizQcWorkOrder.id)),
|
||||
)
|
||||
.join(
|
||||
BizQcTask,
|
||||
and_(
|
||||
BizQcTask.work_order_id == BizQcWorkOrder.id,
|
||||
BizQcTask.del_flag == 0,
|
||||
),
|
||||
)
|
||||
.join(
|
||||
BizQcTaskAssignee,
|
||||
and_(
|
||||
eq_unicode(BizQcTaskAssignee.task_id, BizQcTask.id),
|
||||
unicode_ci(BizQcTaskAssignee.user_id) == assignee_user_id,
|
||||
BizQcTaskAssignee.del_flag == 0,
|
||||
),
|
||||
)
|
||||
.filter(
|
||||
BizQcWorkOrder.del_flag == 0,
|
||||
BizQcWorkOrder.tenant_no == tenant_no,
|
||||
)
|
||||
)
|
||||
q = _unfinished_work_order_filter(q)
|
||||
rows = (
|
||||
q.group_by(
|
||||
BizQcWorkOrder.work_order_type,
|
||||
BizQcWorkOrder.reception_source,
|
||||
BizQcWorkOrder.biz_type,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
return _aggregate_qc_tab_counts(rows)
|
||||
|
||||
|
||||
def get_work_order(
|
||||
db: Session, row_id: str, tenant_no: Optional[str] = None
|
||||
) -> Optional[BizQcWorkOrder]:
|
||||
@@ -1382,6 +1540,8 @@ def _third_lines(db: Session, work_order_id: str) -> List[Dict[str, Any]]:
|
||||
|
||||
|
||||
def _qc_info_item(db: Session, wo: BizQcWorkOrder, tenant_no: str) -> Dict[str, Any]:
|
||||
from app.crud import qc_inspection_batch as batch_svc
|
||||
|
||||
tasks = task_svc.list_tasks_by_work_order(db, wo.id, tenant_no)
|
||||
for t in tasks:
|
||||
tt = (t.get("taskType") or "").strip()
|
||||
@@ -1398,6 +1558,7 @@ def _qc_info_item(db: Session, wo: BizQcWorkOrder, tenant_no: str) -> Dict[str,
|
||||
"qcBizTypeLabel": _qc_biz_type_label(biz),
|
||||
"labItems": _lab_lines(db, wo.id),
|
||||
"thirdPartyItems": _third_lines(db, wo.id),
|
||||
"inspectionBatches": batch_svc.list_inspection_batches(db, wo.id, tenant_no),
|
||||
"tasks": tasks,
|
||||
}
|
||||
|
||||
@@ -1712,6 +1873,9 @@ def get_work_order_detail(
|
||||
out["labItems"] = _lab_lines(db, wo.id)
|
||||
out["thirdPartyItems"] = _third_lines(db, wo.id)
|
||||
out["tasks"] = task_svc.list_tasks_by_work_order(db, wo.id, tenant_no)
|
||||
from app.crud import qc_inspection_batch as batch_svc
|
||||
|
||||
out["inspectionBatches"] = batch_svc.list_inspection_batches(db, wo.id, tenant_no)
|
||||
enriched_fee = enrich_work_order_fee_summaries(db, [out], tenant_no)
|
||||
if enriched_fee:
|
||||
out["paymentSummary"] = enriched_fee[0].get("paymentSummary")
|
||||
@@ -2069,69 +2233,38 @@ def configure_work_order(
|
||||
third_party_item_ids: List[str],
|
||||
lab_item_assignees: Optional[Dict[str, List[str]]] = None,
|
||||
third_party_item_assignees: Optional[Dict[str, List[str]]] = None,
|
||||
batches: Optional[List[Dict[str, Any]]] = None,
|
||||
tenant_no: str,
|
||||
user_id: Optional[str] = None,
|
||||
create_dept_id: str = "",
|
||||
) -> BizQcWorkOrder:
|
||||
from app.crud import qc_inspection_batch as batch_svc
|
||||
|
||||
wo = get_work_order(db, work_order_id, tenant_no=tenant_no)
|
||||
if not wo:
|
||||
raise ValueError("工单不存在")
|
||||
wo_type = getattr(wo, "work_order_type", None) or "inbound"
|
||||
if wo_type == "temporary":
|
||||
order_source = "temporary"
|
||||
elif wo_type == "outbound":
|
||||
order_source = "outbound"
|
||||
|
||||
if batches is not None:
|
||||
payload_batches = batches
|
||||
else:
|
||||
order_source = "inbound"
|
||||
|
||||
if not has_lab and not has_third_party:
|
||||
raise ValueError("请至少选择一种检测方式")
|
||||
if has_lab and not lab_item_ids:
|
||||
raise ValueError("请选择实验室自检项目")
|
||||
if has_third_party and not third_party_item_ids:
|
||||
raise ValueError("请选择第三方检测项目")
|
||||
if not has_lab:
|
||||
lab_item_ids = []
|
||||
if not has_third_party:
|
||||
third_party_item_ids = []
|
||||
|
||||
seq = _sync_work_order_lab_items(
|
||||
payload_batches = batch_svc.normalize_legacy_configure_to_batches(
|
||||
{
|
||||
"hasLab": has_lab,
|
||||
"hasThirdParty": has_third_party,
|
||||
"labItemIds": lab_item_ids,
|
||||
"thirdPartyItemIds": third_party_item_ids,
|
||||
"labItemAssignees": lab_item_assignees,
|
||||
"thirdPartyItemAssignees": third_party_item_assignees,
|
||||
}
|
||||
)
|
||||
return batch_svc.configure_work_order_batches(
|
||||
db,
|
||||
wo,
|
||||
order_source=order_source,
|
||||
lab_item_ids=lab_item_ids,
|
||||
lab_item_assignees=lab_item_assignees,
|
||||
payload_batches,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
)
|
||||
seq, fee_total = _sync_work_order_third_party_items(
|
||||
db,
|
||||
wo,
|
||||
order_source=order_source,
|
||||
third_party_item_ids=third_party_item_ids,
|
||||
third_party_item_assignees=third_party_item_assignees,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
seq_start=seq,
|
||||
)
|
||||
|
||||
wo.has_lab = "1" if has_lab else "0"
|
||||
wo.has_third_party = "1" if has_third_party else "0"
|
||||
wo.work_order_status = "ypz"
|
||||
wo.configured_time = datetime.now()
|
||||
wo.configured_by = user_id
|
||||
wo.third_party_fee_total = fee_total if has_third_party else None
|
||||
wo.update_by = user_id
|
||||
wo.update_time = datetime.now()
|
||||
db.add(wo)
|
||||
from app.crud.pilot_outbound_status_sync import sync_schedule_from_qc_work_order
|
||||
|
||||
sync_schedule_from_qc_work_order(db, wo, user_id=user_id)
|
||||
db.commit()
|
||||
db.refresh(wo)
|
||||
return wo
|
||||
|
||||
|
||||
def try_complete_work_order(db: Session, work_order_id: str, tenant_no: str) -> None:
|
||||
@@ -2412,6 +2545,7 @@ def configure_temp_qc_work_order(
|
||||
has_third_party: bool,
|
||||
lab_item_ids: List[str],
|
||||
third_party_item_ids: List[str],
|
||||
batches: Optional[List[Dict[str, Any]]] = None,
|
||||
tenant_no: str,
|
||||
user_id: Optional[str] = None,
|
||||
create_dept_id: str = "",
|
||||
@@ -2419,50 +2553,27 @@ def configure_temp_qc_work_order(
|
||||
wo = get_temp_qc_work_order(db, work_order_id, tenant_no)
|
||||
if not wo:
|
||||
raise ValueError("工单不存在")
|
||||
from app.crud import qc_inspection_batch as batch_svc
|
||||
|
||||
if not has_lab and not has_third_party:
|
||||
raise ValueError("请至少选择一种检测方式")
|
||||
if has_lab and not lab_item_ids:
|
||||
raise ValueError("请选择实验室自检项目")
|
||||
if has_third_party and not third_party_item_ids:
|
||||
raise ValueError("请选择第三方检测项目")
|
||||
if not has_lab:
|
||||
lab_item_ids = []
|
||||
if not has_third_party:
|
||||
third_party_item_ids = []
|
||||
|
||||
seq = _sync_work_order_lab_items(
|
||||
if batches is not None:
|
||||
payload_batches = batches
|
||||
else:
|
||||
payload_batches = batch_svc.normalize_legacy_configure_to_batches(
|
||||
{
|
||||
"hasLab": has_lab,
|
||||
"hasThirdParty": has_third_party,
|
||||
"labItemIds": lab_item_ids,
|
||||
"thirdPartyItemIds": third_party_item_ids,
|
||||
}
|
||||
)
|
||||
return batch_svc.configure_work_order_batches(
|
||||
db,
|
||||
wo,
|
||||
order_source="temporary",
|
||||
lab_item_ids=lab_item_ids,
|
||||
payload_batches,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
)
|
||||
seq, fee_total = _sync_work_order_third_party_items(
|
||||
db,
|
||||
wo,
|
||||
order_source="temporary",
|
||||
third_party_item_ids=third_party_item_ids,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user_id,
|
||||
create_dept_id=create_dept_id,
|
||||
seq_start=seq,
|
||||
)
|
||||
|
||||
wo.has_lab = "1" if has_lab else "0"
|
||||
wo.has_third_party = "1" if has_third_party else "0"
|
||||
wo.work_order_status = "ypz"
|
||||
wo.configured_time = datetime.now()
|
||||
wo.configured_by = user_id
|
||||
wo.third_party_fee_total = fee_total if has_third_party else None
|
||||
wo.update_by = user_id
|
||||
wo.update_time = datetime.now()
|
||||
db.add(wo)
|
||||
db.commit()
|
||||
db.refresh(wo)
|
||||
return wo
|
||||
|
||||
|
||||
def try_complete_temp_qc_work_order(
|
||||
@@ -2713,15 +2824,10 @@ def get_outbound_qc_detail(
|
||||
"tasks": [],
|
||||
}
|
||||
|
||||
if not schedule_id:
|
||||
out["tasks"] = task_svc.list_tasks_by_work_order(db, wo.id, tenant_no)
|
||||
enriched_fee = enrich_work_order_fee_summaries(db, [out["workOrder"]], tenant_no)
|
||||
if enriched_fee:
|
||||
out["workOrder"]["feeSummary"] = enriched_fee[0].get("feeSummary")
|
||||
out["feeSummary"] = enriched_fee[0].get("feeSummary")
|
||||
return out
|
||||
from app.crud import qc_inspection_batch as batch_svc
|
||||
|
||||
out["tasks"] = task_svc.list_tasks_by_work_order(db, wo.id, tenant_no)
|
||||
out["inspectionBatches"] = batch_svc.list_inspection_batches(db, wo.id, tenant_no)
|
||||
enriched_fee = enrich_work_order_fee_summaries(db, [out["workOrder"]], tenant_no)
|
||||
if enriched_fee:
|
||||
out["workOrder"]["feeSummary"] = enriched_fee[0].get("feeSummary")
|
||||
|
||||
@@ -955,13 +955,14 @@ def create_sample_reception(
|
||||
_, biz_date, seq = lab_code_svc.validate_and_parse_lab_storage_code(
|
||||
resolved_lab_code, reception_time
|
||||
)
|
||||
lab_code_svc.sync_lab_storage_seq_after_use(
|
||||
db,
|
||||
tenant_no=tenant_no,
|
||||
biz_date=biz_date,
|
||||
seq=seq,
|
||||
user_id=user_id,
|
||||
)
|
||||
if biz_date is not None and seq is not None:
|
||||
lab_code_svc.sync_lab_storage_seq_after_use(
|
||||
db,
|
||||
tenant_no=tenant_no,
|
||||
biz_date=biz_date,
|
||||
seq=seq,
|
||||
user_id=user_id,
|
||||
)
|
||||
db.commit()
|
||||
db.refresh(obj)
|
||||
return obj
|
||||
@@ -1024,13 +1025,14 @@ def update_sample_reception(
|
||||
exclude_reception_id=reception_id,
|
||||
)
|
||||
rec.lab_storage_code = parsed_code
|
||||
lab_code_svc.sync_lab_storage_seq_after_use(
|
||||
db,
|
||||
tenant_no=tenant_no,
|
||||
biz_date=biz_date,
|
||||
seq=seq,
|
||||
user_id=user_id,
|
||||
)
|
||||
if biz_date is not None and seq is not None:
|
||||
lab_code_svc.sync_lab_storage_seq_after_use(
|
||||
db,
|
||||
tenant_no=tenant_no,
|
||||
biz_date=biz_date,
|
||||
seq=seq,
|
||||
user_id=user_id,
|
||||
)
|
||||
|
||||
handler_display = (handler_name or "").strip()
|
||||
if handler_user_id and not handler_display:
|
||||
|
||||
@@ -167,18 +167,22 @@ def allocate_lab_storage_codes(
|
||||
|
||||
def validate_and_parse_lab_storage_code(
|
||||
code: str,
|
||||
reception_time: datetime,
|
||||
) -> Tuple[str, str, int]:
|
||||
reception_time: Optional[datetime] = None,
|
||||
) -> Tuple[str, Optional[str], Optional[int]]:
|
||||
"""校验入库编码非空;若为 RK+日期+序号 格式则解析 biz_date/seq 供序号同步,否则仅返回编码本身。"""
|
||||
c = (code or "").strip()
|
||||
if not c:
|
||||
raise ValueError("实验室入库编码不能为空")
|
||||
if len(c) > 32:
|
||||
raise ValueError("实验室入库编码长度不能超过 32 个字符")
|
||||
m = LAB_STORAGE_CODE_RE.match(c)
|
||||
if not m:
|
||||
raise ValueError("实验室入库编码格式无效")
|
||||
return c, None, None
|
||||
biz_date, seq_str = m.group(1), m.group(2)
|
||||
expected_date = reception_time_date_str(reception_time)
|
||||
if biz_date != expected_date:
|
||||
raise ValueError("实验室入库编码日期须与样本接收时间日期一致")
|
||||
if reception_time is not None:
|
||||
expected_date = reception_time_date_str(reception_time)
|
||||
if biz_date != expected_date:
|
||||
raise ValueError("实验室入库编码日期须与样本接收时间日期一致")
|
||||
return c, biz_date, int(seq_str)
|
||||
|
||||
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_production_material_py", "label": "production_material.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L1"}, {"id": "api_production_material_productionmaterialbody", "label": "ProductionMaterialBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L28"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_production_material_productionmaterialupdatebody", "label": "ProductionMaterialUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L40"}, {"id": "api_production_material_stockinbody", "label": "StockInBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L52"}, {"id": "api_production_material_batchstockinitem", "label": "BatchStockInItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L69"}, {"id": "api_production_material_batchstockinbody", "label": "BatchStockInBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L86"}, {"id": "api_production_material_batchstockoutitem", "label": "BatchStockOutItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L93"}, {"id": "api_production_material_batchstockoutbody", "label": "BatchStockOutBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L100"}, {"id": "api_production_material_batchdiscarditem", "label": "BatchDiscardItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L109"}, {"id": "api_production_material_batchdiscardbody", "label": "BatchDiscardBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L117"}, {"id": "api_production_material_productionmaterialbatchupdatebody", "label": "ProductionMaterialBatchUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L125"}, {"id": "api_production_material_list_production_material_batches", "label": "list_production_material_batches()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L147"}, {"id": "api_production_material_production_material_batch_options", "label": "production_material_batch_options()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L178"}, {"id": "api_production_material_update_production_material_batch", "label": "update_production_material_batch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L203"}, {"id": "api_production_material_delete_production_material_batch", "label": "delete_production_material_batch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L232"}, {"id": "api_production_material_list_production_materials", "label": "list_production_materials()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L249"}, {"id": "api_production_material_production_material_options", "label": "production_material_options()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L278"}, {"id": "api_production_material_create_production_material", "label": "create_production_material()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L293"}, {"id": "api_production_material_update_production_material", "label": "update_production_material()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L324"}, {"id": "api_production_material_delete_production_material", "label": "delete_production_material()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py", "source_location": "L353"}, {"id": "api_production_material_batch_stock_in_production_material", "label": "batch_stock_in_production_material()", "file_type": "code", "source_file": "/Users/Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_production_task_py", "label": "production_task.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L1"}, {"id": "crud_production_task_require_requisition_for_catalog_material", "label": "_require_requisition_for_catalog_material()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L49"}, {"id": "crud_production_task_production_conclusion_label", "label": "_production_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L101"}, {"id": "crud_production_task_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L108"}, {"id": "crud_production_task_normalize_date_bound", "label": "_normalize_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L112"}, {"id": "crud_production_task_enrich_outbound_task_items", "label": "_enrich_outbound_task_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L119"}, {"id": "crud_production_task_generate_task_no", "label": "_generate_task_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L253"}, {"id": "crud_production_task_task_to_dict", "label": "_task_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L267"}, {"id": "crud_production_task_step_to_dict", "label": "_step_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L294"}, {"id": "crud_production_task_step_reagent_to_dict", "label": "_step_reagent_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L321"}, {"id": "crud_production_task_step_configured_reagent_to_dict", "label": "_step_configured_reagent_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L338"}, {"id": "crud_production_task_step_consumable_to_dict", "label": "_step_consumable_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L354"}, {"id": "crud_production_task_step_output_to_dict", "label": "_step_output_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L371"}, {"id": "crud_production_task_step_data_collection_to_dict", "label": "_step_data_collection_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L383"}, {"id": "crud_production_task_task_input_to_dict", "label": "_task_input_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L395"}, {"id": "crud_production_task_task_output_to_dict", "label": "_task_output_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L417"}, {"id": "crud_production_task_soft_delete_sub", "label": "_soft_delete_sub()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L442"}, {"id": "crud_production_task_resolve_sub_table_order_num", "label": "_resolve_sub_table_order_num()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L455"}, {"id": "crud_production_task_step_sub_tables_to_dict", "label": "_step_sub_tables_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L464"}, {"id": "crud_production_task_clone_step_reagents", "label": "_clone_step_reagents()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L490"}, {"id": "crud_production_task_clone_step_consumables", "label": "_clone_step_consumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L513"}, {"id": "crud_production_task_clone_step_outputs", "label": "_clone_step_outputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L536"}, Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_reception_lab_code_py", "label": "sample_reception_lab_code.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L1"}, {"id": "crud_sample_reception_lab_code_parse_reception_date", "label": "parse_reception_date()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L18"}, {"id": "crud_sample_reception_lab_code_reception_time_date_str", "label": "reception_time_date_str()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L28"}, {"id": "crud_sample_reception_lab_code_format_lab_storage_code", "label": "format_lab_storage_code()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L32"}, {"id": "crud_sample_reception_lab_code_max_existing_seq", "label": "_max_existing_seq()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L36"}, {"id": "crud_sample_reception_lab_code_sync_sequence_from_existing", "label": "_sync_sequence_from_existing()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L60"}, {"id": "crud_sample_reception_lab_code_allocate_one_seq", "label": "_allocate_one_seq()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L101"}, {"id": "crud_sample_reception_lab_code_allocate_lab_storage_codes", "label": "allocate_lab_storage_codes()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L145"}, {"id": "crud_sample_reception_lab_code_validate_and_parse_lab_storage_code", "label": "validate_and_parse_lab_storage_code()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L168"}, {"id": "crud_sample_reception_lab_code_assert_lab_storage_code_available", "label": "assert_lab_storage_code_available()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L189"}, {"id": "crud_sample_reception_lab_code_sync_lab_storage_seq_after_use", "label": "sync_lab_storage_seq_after_use()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L207"}, {"id": "crud_sample_reception_lab_code_rationale_1", "label": "\u5b9e\u9a8c\u5ba4\u5165\u5e93\u7f16\u7801\uff1aRK + \u63a5\u6536\u65e5\u671f YYYYMMDD + 3 \u4f4d\u5e8f\u53f7", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L1"}, {"id": "crud_sample_reception_lab_code_rationale_172", "label": "\u6821\u9a8c\u5165\u5e93\u7f16\u7801\u975e\u7a7a\uff1b\u82e5\u4e3a RK+\u65e5\u671f+\u5e8f\u53f7 \u683c\u5f0f\u5219\u89e3\u6790 biz_date/seq \u4f9b\u5e8f\u53f7\u540c\u6b65\uff0c\u5426\u5219\u4ec5\u8fd4\u56de\u7f16\u7801\u672c\u8eab\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L172"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_reception_lab_code_py", "target": "re", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_reception_lab_code_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L3", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_reception_lab_code_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_reception_lab_code_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py", "source_location": "L6", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_reception_lab_code_py", "target": "sqlalchemy_orm", "relation": "imports_from", "confidence": "EXTRACTED", "sourceLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_production_material_stock_batch_py", "label": "production_material_stock_batch.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L1"}, {"id": "crud_production_material_stock_batch_fmt_date", "label": "_fmt_date()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L16"}, {"id": "crud_production_material_stock_batch_parse_date", "label": "_parse_date()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L20"}, {"id": "crud_production_material_stock_batch_parse_expire_date", "label": "_parse_expire_date()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L34"}, {"id": "crud_production_material_stock_batch_parse_optional_date", "label": "_parse_optional_date()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L38"}, {"id": "crud_production_material_stock_batch_require_str", "label": "_require_str()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L47"}, {"id": "crud_production_material_stock_batch_optional_str", "label": "_optional_str()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L54"}, {"id": "crud_production_material_stock_batch_require_decimal", "label": "_require_decimal()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L61"}, {"id": "crud_production_material_stock_batch_stock_in_no_exists", "label": "stock_in_no_exists()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L73"}, {"id": "crud_production_material_stock_batch_batch_row_to_dict", "label": "_batch_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L89"}, {"id": "crud_production_material_stock_batch_usage_batch_snapshots", "label": "_usage_batch_snapshots()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L126"}, {"id": "crud_production_material_stock_batch_get_material_for_update", "label": "_get_material_for_update()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L148"}, {"id": "crud_production_material_stock_batch_list_batches", "label": "list_batches()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L166"}, {"id": "crud_production_material_stock_batch_batch_options", "label": "batch_options()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L234"}, {"id": "crud_production_material_stock_batch_create_batch_and_usage", "label": "_create_batch_and_usage()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L314"}, {"id": "crud_production_material_stock_batch_stock_in_one", "label": "stock_in_one()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L418"}, {"id": "crud_production_material_stock_batch_batch_stock_in", "label": "batch_stock_in()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L463"}, {"id": "crud_production_material_stock_batch_stock_out_batch", "label": "_stock_out_batch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L524"}, {"id": "crud_production_material_stock_batch_batch_stock_out", "label": "batch_stock_out()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L606"}, {"id": "crud_production_material_stock_batch_validate_discard_reason", "label": "_validate_discard_reason()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py", "source_location": "L659"}, {"id": "crud_pLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_py", "label": "qc_task.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L1"}, {"id": "crud_qc_task_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L36"}, {"id": "crud_qc_task_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L42"}, {"id": "crud_qc_task_gen_task_no", "label": "_gen_task_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L46"}, {"id": "crud_qc_task_conclusion_label", "label": "_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L59"}, {"id": "crud_qc_task_task_to_dict", "label": "_task_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L64"}, {"id": "crud_qc_task_task_work_order_context", "label": "_task_work_order_context()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L98"}, {"id": "crud_qc_task_enrich_tasks_reception_fields", "label": "_enrich_tasks_reception_fields()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L135"}, {"id": "crud_qc_task_task_row_to_dict", "label": "_task_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L243"}, {"id": "crud_qc_task_create_task_for_line", "label": "create_task_for_line()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L254"}, {"id": "crud_qc_task_list_tasks", "label": "list_tasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L301"}, {"id": "crud_qc_task_list_mine_tasks", "label": "list_mine_tasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L382"}, {"id": "crud_qc_task_assert_task_assignee", "label": "assert_task_assignee()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L473"}, {"id": "crud_qc_task_list_tasks_by_work_order", "label": "list_tasks_by_work_order()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L480"}, {"id": "crud_qc_task_get_task", "label": "get_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L498"}, {"id": "crud_qc_task_get_task_detail", "label": "get_task_detail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L507"}, {"id": "crud_qc_task_start_task", "label": "start_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L540"}, {"id": "crud_qc_task_set_task_remark", "label": "_set_task_remark()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L557"}, {"id": "crud_qc_task_complete_task", "label": "complete_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L561"}, {"id": "crud_qc_task_apply_task_result", "label": "apply_task_result()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L605"}, {"id": "crud_qc_task_update_task_attachments", "label": "update_task_attachments()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L657"}, {"id": "crud_qc_task_create_qc_task_manual", "label": "create_qc_task_manual()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L687"}, {"id": "crud_qc_task_delete_qc_task", "label": "delete_qc_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L736"}, {"id": "crud_qc_task_rationale_616", "label": "\u4fdd\u5b58\u68c0\u6d4b\u7ed3\u679c\u4e0e\u7ed3\u8bba\uff1b\u4efb\u52a1\u672a\u5b8c\u6210\u65f6\u987a\u5e26\u6807\u8bb0\u4e3a\u5df2\u5b8c\u6210\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py", "source_location": "L616"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_taLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_production_py", "label": "production.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L1"}, {"id": "api_production_legacy_material_write_gone", "label": "_legacy_material_write_gone()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L76"}, {"id": "api_production_get_tenant_no", "label": "_get_tenant_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L80"}, {"id": "api_production_get_current_user_id", "label": "_get_current_user_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L88"}, {"id": "api_production_assert_production_task_write_access", "label": "_assert_production_task_write_access()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L92"}, {"id": "api_production_assert_production_task_step_write_access", "label": "_assert_production_task_step_write_access()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L113"}, {"id": "api_production_consumablecreatebody", "label": "ConsumableCreateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L140"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_production_consumableupdatebody", "label": "ConsumableUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L154"}, {"id": "api_production_list_consumables", "label": "list_consumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L169"}, {"id": "api_production_list_all_consumables", "label": "list_all_consumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L183"}, {"id": "api_production_create_consumable", "label": "create_consumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L193"}, {"id": "api_production_update_consumable", "label": "update_consumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L202"}, {"id": "api_production_delete_consumable", "label": "delete_consumable()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L212"}, {"id": "api_production_stockinbody", "label": "StockInBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L220"}, {"id": "api_production_stockoutbody", "label": "StockOutBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L226"}, {"id": "api_production_batchstockinitem", "label": "BatchStockInItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L234"}, {"id": "api_production_batchstockinbody", "label": "BatchStockInBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L241"}, {"id": "api_production_batchstockoutitem", "label": "BatchStockOutItem", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L247"}, {"id": "api_production_batchstockoutbody", "label": "BatchStockOutBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L253"}, {"id": "api_production_consumable_stock_in", "label": "consumable_stock_in()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L262"}, {"id": "api_production_consumable_stock_out", "label": "consumable_stock_out()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L284"}, {"id": "api_production_consumable_batch_stock_in", "label": "consumable_batch_stock_in()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L308"}, {"id": "api_production_consumable_batch_stock_out", "label": "consumable_batch_stock_out()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py", "source_location": "L326"}, {"id": "api_production_list_conLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_qc_py", "label": "qc.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L1"}, {"id": "api_qc_thirdpartycompanybody", "label": "ThirdPartyCompanyBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L48"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_qc_thirdpartycompanyupdatebody", "label": "ThirdPartyCompanyUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L66"}, {"id": "api_qc_list_qc_third_party_companies", "label": "list_qc_third_party_companies()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L85"}, {"id": "api_qc_list_qc_third_party_company_options", "label": "list_qc_third_party_company_options()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L107"}, {"id": "api_qc_create_qc_third_party_company", "label": "create_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L121"}, {"id": "api_qc_update_qc_third_party_company", "label": "update_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L156"}, {"id": "api_qc_delete_qc_third_party_company", "label": "delete_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L193"}, {"id": "api_qc_thirdpartyitembody", "label": "ThirdPartyItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L213"}, {"id": "api_qc_thirdpartyitemupdatebody", "label": "ThirdPartyItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L225"}, {"id": "api_qc_list_qc_third_party_items", "label": "list_qc_third_party_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L238"}, {"id": "api_qc_list_qc_third_party_items_active", "label": "list_qc_third_party_items_active()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L267"}, {"id": "api_qc_create_qc_third_party_item", "label": "create_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L282"}, {"id": "api_qc_update_qc_third_party_item", "label": "update_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L311"}, {"id": "api_qc_delete_qc_third_party_item", "label": "delete_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L342"}, {"id": "api_qc_labtestitembody", "label": "LabTestItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L362"}, {"id": "api_qc_labtestitemupdatebody", "label": "LabTestItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L373"}, {"id": "api_qc_itemparambody", "label": "ItemParamBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L387"}, {"id": "api_qc_taskresultbody", "label": "TaskResultBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L392"}, {"id": "api_qc_taskcompletewithresultbody", "label": "TaskCompleteWithResultBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L397"}, {"id": "api_qc_list_qc_lab_test_items", "label": "list_qc_lab_test_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L407"}, {"id": "api_qc_list_qc_lab_test_items_active", "label": "list_qc_lab_test_items_active()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L429"}, {"id": "api_qc_create_qc_lab_test_item", "label": "create_qc_lab_test_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L443"}, {"id": "api_qc_update_qc_lab_test_item", "label": "update_qc_lab_test_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L471"}, {"id": "api_Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_work_order_py", "label": "qc_work_order.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L1"}, {"id": "crud_qc_work_order_resolve_outbound_biz_type_for_schedule", "label": "resolve_outbound_biz_type_for_schedule()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L89"}, {"id": "crud_qc_work_order_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L130"}, {"id": "crud_qc_work_order_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L136"}, {"id": "crud_qc_work_order_normalize_date_bound", "label": "_normalize_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L140"}, {"id": "crud_qc_work_order_reception_source_label", "label": "_reception_source_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L147"}, {"id": "crud_qc_work_order_qc_biz_type_label", "label": "_qc_biz_type_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L152"}, {"id": "crud_qc_work_order_work_order_qc_biz_type", "label": "_work_order_qc_biz_type()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L157"}, {"id": "crud_qc_work_order_validate_cell_product_id", "label": "_validate_cell_product_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L164"}, {"id": "crud_qc_work_order_enrich_work_order_cell_products", "label": "_enrich_work_order_cell_products()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L176"}, {"id": "crud_qc_work_order_enrich_work_order_step_outputs", "label": "_enrich_work_order_step_outputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L205"}, {"id": "crud_qc_work_order_enrich_work_order_qc_targets", "label": "_enrich_work_order_qc_targets()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L244"}, {"id": "crud_qc_work_order_enrich_outbound_work_orders", "label": "_enrich_outbound_work_orders()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L251"}, {"id": "crud_qc_work_order_outbound_qc_work_order_ids_by_keyword", "label": "_outbound_qc_work_order_ids_by_keyword()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L372"}, {"id": "crud_qc_work_order_accept_conclusion_label", "label": "_accept_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L419"}, {"id": "crud_qc_work_order_load_sample_type_name_map", "label": "_load_sample_type_name_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L424"}, {"id": "crud_qc_work_order_effective_reception_source", "label": "_effective_reception_source()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L436"}, {"id": "crud_qc_work_order_effective_donation_sample_id", "label": "_effective_donation_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L445"}, {"id": "crud_qc_work_order_effective_protocol_sample_id", "label": "_effective_protocol_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L454"}, {"id": "crud_qc_work_order_sample_type_name_for_item", "label": "_sample_type_name_for_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L462"}, {"id": "crud_qc_work_order_sample_type_name_for_reception", "label": "_sample_type_name_for_reception()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L480"}, {"id": "crud_qc_work_order_enrich_work_order_list_items", "label": "_enrich_work_order_list_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/bLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_work_order_py", "label": "qc_work_order.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L1"}, {"id": "crud_qc_work_order_resolve_outbound_biz_type_for_schedule", "label": "resolve_outbound_biz_type_for_schedule()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L90"}, {"id": "crud_qc_work_order_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L131"}, {"id": "crud_qc_work_order_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L137"}, {"id": "crud_qc_work_order_normalize_date_bound", "label": "_normalize_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L141"}, {"id": "crud_qc_work_order_reception_source_label", "label": "_reception_source_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L148"}, {"id": "crud_qc_work_order_qc_biz_type_label", "label": "_qc_biz_type_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L153"}, {"id": "crud_qc_work_order_work_order_qc_biz_type", "label": "_work_order_qc_biz_type()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L158"}, {"id": "crud_qc_work_order_validate_cell_product_id", "label": "_validate_cell_product_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L165"}, {"id": "crud_qc_work_order_enrich_work_order_cell_products", "label": "_enrich_work_order_cell_products()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L177"}, {"id": "crud_qc_work_order_enrich_work_order_step_outputs", "label": "_enrich_work_order_step_outputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L206"}, {"id": "crud_qc_work_order_enrich_work_order_qc_targets", "label": "_enrich_work_order_qc_targets()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L245"}, {"id": "crud_qc_work_order_enrich_outbound_work_orders", "label": "_enrich_outbound_work_orders()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L252"}, {"id": "crud_qc_work_order_outbound_qc_work_order_ids_by_keyword", "label": "_outbound_qc_work_order_ids_by_keyword()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L373"}, {"id": "crud_qc_work_order_accept_conclusion_label", "label": "_accept_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L420"}, {"id": "crud_qc_work_order_load_sample_type_name_map", "label": "_load_sample_type_name_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L425"}, {"id": "crud_qc_work_order_effective_reception_source", "label": "_effective_reception_source()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L437"}, {"id": "crud_qc_work_order_effective_donation_sample_id", "label": "_effective_donation_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L446"}, {"id": "crud_qc_work_order_effective_protocol_sample_id", "label": "_effective_protocol_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L455"}, {"id": "crud_qc_work_order_sample_type_name_for_item", "label": "_sample_type_name_for_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L463"}, {"id": "crud_qc_work_order_sample_type_name_for_reception", "label": "_sample_type_name_for_reception()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L481"}, {"id": "crud_qc_work_order_enrich_work_order_list_items", "label": "_enrich_work_order_list_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/bLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_inspection_batch_py", "label": "qc_inspection_batch.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L1"}, {"id": "crud_qc_inspection_batch_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L27"}, {"id": "crud_qc_inspection_batch_unique_ids", "label": "_unique_ids()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L33"}, {"id": "crud_qc_inspection_batch_validate_batch_payload", "label": "_validate_batch_payload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L45"}, {"id": "crud_qc_inspection_batch_order_source_for_wo", "label": "_order_source_for_wo()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L69"}, {"id": "crud_qc_inspection_batch_next_batch_no", "label": "_next_batch_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L78"}, {"id": "crud_qc_inspection_batch_allocate_batch_name", "label": "_allocate_batch_name()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L97"}, {"id": "crud_qc_inspection_batch_sync_batch_assignees", "label": "sync_batch_assignees()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L119"}, {"id": "crud_qc_inspection_batch_batch_assignee_user_ids", "label": "_batch_assignee_user_ids()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L168"}, {"id": "crud_qc_inspection_batch_assignee_names", "label": "_assignee_names()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L182"}, {"id": "crud_qc_inspection_batch_apply_assignees_to_batch_tasks", "label": "_apply_assignees_to_batch_tasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L194"}, {"id": "crud_qc_inspection_batch_batch_has_blocking_tasks", "label": "_batch_has_blocking_tasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L223"}, {"id": "crud_qc_inspection_batch_soft_delete_batch", "label": "_soft_delete_batch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L237"}, {"id": "crud_qc_inspection_batch_sync_batch_lab_items", "label": "_sync_batch_lab_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L285"}, {"id": "crud_qc_inspection_batch_sync_batch_third_items", "label": "_sync_batch_third_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L413"}, {"id": "crud_qc_inspection_batch_batch_item_ids", "label": "_batch_item_ids()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L557"}, {"id": "crud_qc_inspection_batch_batch_to_dict", "label": "_batch_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L578"}, {"id": "crud_qc_inspection_batch_list_inspection_batches", "label": "list_inspection_batches()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L607"}, {"id": "crud_qc_inspection_batch_configure_work_order_batches", "label": "configure_work_order_batches()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L655"}, {"id": "crud_qc_inspection_batch_normalize_legacy_configure_to_batches", "label": "normalize_legacy_configure_to_batches()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L820"}, {"id": "crud_qc_inspection_batch_rationale_821", "label": "\u5c06\u6241\u5e73 labItemIds \u914d\u7f6e\u8f6c\u4e3a\u5355\u6279\u6b21\u7ed3\u6784\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L821"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_bLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_qc_py", "label": "qc.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L1"}, {"id": "api_qc_thirdpartycompanybody", "label": "ThirdPartyCompanyBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L50"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_qc_thirdpartycompanyupdatebody", "label": "ThirdPartyCompanyUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L68"}, {"id": "api_qc_list_qc_third_party_companies", "label": "list_qc_third_party_companies()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L87"}, {"id": "api_qc_list_qc_third_party_company_options", "label": "list_qc_third_party_company_options()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L109"}, {"id": "api_qc_create_qc_third_party_company", "label": "create_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L123"}, {"id": "api_qc_update_qc_third_party_company", "label": "update_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L158"}, {"id": "api_qc_delete_qc_third_party_company", "label": "delete_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L195"}, {"id": "api_qc_thirdpartyitembody", "label": "ThirdPartyItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L215"}, {"id": "api_qc_thirdpartyitemupdatebody", "label": "ThirdPartyItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L227"}, {"id": "api_qc_list_qc_third_party_items", "label": "list_qc_third_party_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L240"}, {"id": "api_qc_list_qc_third_party_items_active", "label": "list_qc_third_party_items_active()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L269"}, {"id": "api_qc_create_qc_third_party_item", "label": "create_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L284"}, {"id": "api_qc_update_qc_third_party_item", "label": "update_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L313"}, {"id": "api_qc_delete_qc_third_party_item", "label": "delete_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L344"}, {"id": "api_qc_labtestitembody", "label": "LabTestItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L364"}, {"id": "api_qc_labtestitemupdatebody", "label": "LabTestItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L375"}, {"id": "api_qc_itemparambody", "label": "ItemParamBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L389"}, {"id": "api_qc_taskresultbody", "label": "TaskResultBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L394"}, {"id": "api_qc_taskcompletewithresultbody", "label": "TaskCompleteWithResultBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L399"}, {"id": "api_qc_list_qc_lab_test_items", "label": "list_qc_lab_test_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L409"}, {"id": "api_qc_list_qc_lab_test_items_active", "label": "list_qc_lab_test_items_active()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L431"}, {"id": "api_qc_create_qc_lab_test_item", "label": "create_qc_lab_test_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L445"}, {"id": "api_qc_update_qc_lab_test_item", "label": "update_qc_lab_test_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L473"}, {"id": "api_Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_work_order_py", "label": "qc_work_order.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L1"}, {"id": "crud_qc_work_order_resolve_outbound_biz_type_for_schedule", "label": "resolve_outbound_biz_type_for_schedule()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L90"}, {"id": "crud_qc_work_order_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L131"}, {"id": "crud_qc_work_order_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L137"}, {"id": "crud_qc_work_order_normalize_date_bound", "label": "_normalize_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L141"}, {"id": "crud_qc_work_order_reception_source_label", "label": "_reception_source_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L148"}, {"id": "crud_qc_work_order_qc_biz_type_label", "label": "_qc_biz_type_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L153"}, {"id": "crud_qc_work_order_work_order_qc_biz_type", "label": "_work_order_qc_biz_type()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L158"}, {"id": "crud_qc_work_order_validate_cell_product_id", "label": "_validate_cell_product_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L165"}, {"id": "crud_qc_work_order_enrich_work_order_cell_products", "label": "_enrich_work_order_cell_products()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L177"}, {"id": "crud_qc_work_order_enrich_work_order_step_outputs", "label": "_enrich_work_order_step_outputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L206"}, {"id": "crud_qc_work_order_enrich_work_order_qc_targets", "label": "_enrich_work_order_qc_targets()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L245"}, {"id": "crud_qc_work_order_enrich_outbound_work_orders", "label": "_enrich_outbound_work_orders()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L252"}, {"id": "crud_qc_work_order_outbound_qc_work_order_ids_by_keyword", "label": "_outbound_qc_work_order_ids_by_keyword()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L373"}, {"id": "crud_qc_work_order_accept_conclusion_label", "label": "_accept_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L420"}, {"id": "crud_qc_work_order_load_sample_type_name_map", "label": "_load_sample_type_name_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L425"}, {"id": "crud_qc_work_order_effective_reception_source", "label": "_effective_reception_source()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L437"}, {"id": "crud_qc_work_order_effective_donation_sample_id", "label": "_effective_donation_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L446"}, {"id": "crud_qc_work_order_effective_protocol_sample_id", "label": "_effective_protocol_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L455"}, {"id": "crud_qc_work_order_sample_type_name_for_item", "label": "_sample_type_name_for_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L463"}, {"id": "crud_qc_work_order_sample_type_name_for_reception", "label": "_sample_type_name_for_reception()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L481"}, {"id": "crud_qc_work_order_enrich_work_order_list_items", "label": "_enrich_work_order_list_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/bLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_work_order_py", "label": "qc_work_order.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L1"}, {"id": "crud_qc_work_order_resolve_outbound_biz_type_for_schedule", "label": "resolve_outbound_biz_type_for_schedule()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L90"}, {"id": "crud_qc_work_order_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L131"}, {"id": "crud_qc_work_order_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L137"}, {"id": "crud_qc_work_order_normalize_date_bound", "label": "_normalize_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L141"}, {"id": "crud_qc_work_order_reception_source_label", "label": "_reception_source_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L148"}, {"id": "crud_qc_work_order_qc_biz_type_label", "label": "_qc_biz_type_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L153"}, {"id": "crud_qc_work_order_work_order_qc_biz_type", "label": "_work_order_qc_biz_type()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L158"}, {"id": "crud_qc_work_order_validate_cell_product_id", "label": "_validate_cell_product_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L165"}, {"id": "crud_qc_work_order_enrich_work_order_cell_products", "label": "_enrich_work_order_cell_products()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L177"}, {"id": "crud_qc_work_order_enrich_work_order_step_outputs", "label": "_enrich_work_order_step_outputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L206"}, {"id": "crud_qc_work_order_enrich_work_order_qc_targets", "label": "_enrich_work_order_qc_targets()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L245"}, {"id": "crud_qc_work_order_enrich_outbound_work_orders", "label": "_enrich_outbound_work_orders()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L252"}, {"id": "crud_qc_work_order_outbound_qc_work_order_ids_by_keyword", "label": "_outbound_qc_work_order_ids_by_keyword()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L373"}, {"id": "crud_qc_work_order_accept_conclusion_label", "label": "_accept_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L420"}, {"id": "crud_qc_work_order_load_sample_type_name_map", "label": "_load_sample_type_name_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L425"}, {"id": "crud_qc_work_order_effective_reception_source", "label": "_effective_reception_source()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L437"}, {"id": "crud_qc_work_order_effective_donation_sample_id", "label": "_effective_donation_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L446"}, {"id": "crud_qc_work_order_effective_protocol_sample_id", "label": "_effective_protocol_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L455"}, {"id": "crud_qc_work_order_sample_type_name_for_item", "label": "_sample_type_name_for_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L463"}, {"id": "crud_qc_work_order_sample_type_name_for_reception", "label": "_sample_type_name_for_reception()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L481"}, {"id": "crud_qc_work_order_enrich_work_order_list_items", "label": "_enrich_work_order_list_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/bLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_result_py", "label": "qc_task_result.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L1"}, {"id": "crud_qc_task_result_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L15"}, {"id": "crud_qc_task_result_list_saved_results_by_task", "label": "_list_saved_results_by_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L27"}, {"id": "crud_qc_task_result_resolve_task_item_ref", "label": "_resolve_task_item_ref()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L42"}, {"id": "crud_qc_task_result_merge_saved_into_template", "label": "_merge_saved_into_template()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L69"}, {"id": "crud_qc_task_result_list_results_by_task", "label": "list_results_by_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L100"}, {"id": "crud_qc_task_result_save_results_for_task", "label": "save_results_for_task()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L117"}, {"id": "crud_qc_task_result_rationale_43", "label": "\u8fd4\u56de (item_source, item_id) \u4f9b biz_qc_item_param \u67e5\u8be2\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L43"}, {"id": "crud_qc_task_result_rationale_103", "label": "\u8fd4\u56de\u4efb\u52a1\u7ed3\u679c\u586b\u5199\u8868\u5355\uff1a\u9879\u76ee\u53c2\u6570\u6a21\u677f + \u5df2\u4fdd\u5b58\u503c\uff08\u65e0\u6a21\u677f\u65f6\u4ec5\u8fd4\u56de\u5df2\u4fdd\u5b58\u8bb0\u5f55\uff09\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L103"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_result_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L3", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_result_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_result_py", "target": "sqlalchemy_orm", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L6", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_result_py", "target": "app_core_utils", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L8", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_result_py", "target": "app_crud", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L9", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_result_py", "target": "app_crud_qc_task", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L10", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_result_py", "target": "app_models_models", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L11", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_result_py", "target": "app_models_qc_param", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L12", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_result_py", "target": "crud_qc_task_result_row_to_dict", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py", "source_location": "L15", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_task_result_py", "targeLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_inspection_batch_py", "label": "qc_inspection_batch.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L1"}, {"id": "crud_qc_inspection_batch_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L27"}, {"id": "crud_qc_inspection_batch_unique_ids", "label": "_unique_ids()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L33"}, {"id": "crud_qc_inspection_batch_validate_batch_payload", "label": "_validate_batch_payload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L45"}, {"id": "crud_qc_inspection_batch_order_source_for_wo", "label": "_order_source_for_wo()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L66"}, {"id": "crud_qc_inspection_batch_next_batch_no", "label": "_next_batch_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L75"}, {"id": "crud_qc_inspection_batch_allocate_batch_name", "label": "_allocate_batch_name()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L94"}, {"id": "crud_qc_inspection_batch_sync_batch_assignees", "label": "sync_batch_assignees()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L116"}, {"id": "crud_qc_inspection_batch_batch_assignee_user_ids", "label": "_batch_assignee_user_ids()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L165"}, {"id": "crud_qc_inspection_batch_assignee_names", "label": "_assignee_names()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L179"}, {"id": "crud_qc_inspection_batch_apply_assignees_to_batch_tasks", "label": "_apply_assignees_to_batch_tasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L191"}, {"id": "crud_qc_inspection_batch_batch_has_blocking_tasks", "label": "_batch_has_blocking_tasks()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L220"}, {"id": "crud_qc_inspection_batch_soft_delete_batch", "label": "_soft_delete_batch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L234"}, {"id": "crud_qc_inspection_batch_sync_batch_lab_items", "label": "_sync_batch_lab_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L282"}, {"id": "crud_qc_inspection_batch_sync_batch_third_items", "label": "_sync_batch_third_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L410"}, {"id": "crud_qc_inspection_batch_batch_item_ids", "label": "_batch_item_ids()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L554"}, {"id": "crud_qc_inspection_batch_batch_to_dict", "label": "_batch_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L575"}, {"id": "crud_qc_inspection_batch_list_inspection_batches", "label": "list_inspection_batches()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L604"}, {"id": "crud_qc_inspection_batch_configure_work_order_batches", "label": "configure_work_order_batches()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L652"}, {"id": "crud_qc_inspection_batch_normalize_legacy_configure_to_batches", "label": "normalize_legacy_configure_to_batches()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L818"}, {"id": "crud_qc_inspection_batch_rationale_819", "label": "\u5c06\u6241\u5e73 labItemIds \u914d\u7f6e\u8f6c\u4e3a\u5355\u6279\u6b21\u7ed3\u6784\u3002", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py", "source_location": "L819"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_bLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_qc_py", "label": "qc.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L1"}, {"id": "api_qc_thirdpartycompanybody", "label": "ThirdPartyCompanyBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L48"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_qc_thirdpartycompanyupdatebody", "label": "ThirdPartyCompanyUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L66"}, {"id": "api_qc_list_qc_third_party_companies", "label": "list_qc_third_party_companies()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L85"}, {"id": "api_qc_list_qc_third_party_company_options", "label": "list_qc_third_party_company_options()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L107"}, {"id": "api_qc_create_qc_third_party_company", "label": "create_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L121"}, {"id": "api_qc_update_qc_third_party_company", "label": "update_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L156"}, {"id": "api_qc_delete_qc_third_party_company", "label": "delete_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L193"}, {"id": "api_qc_thirdpartyitembody", "label": "ThirdPartyItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L213"}, {"id": "api_qc_thirdpartyitemupdatebody", "label": "ThirdPartyItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L225"}, {"id": "api_qc_list_qc_third_party_items", "label": "list_qc_third_party_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L238"}, {"id": "api_qc_list_qc_third_party_items_active", "label": "list_qc_third_party_items_active()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L267"}, {"id": "api_qc_create_qc_third_party_item", "label": "create_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L282"}, {"id": "api_qc_update_qc_third_party_item", "label": "update_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L311"}, {"id": "api_qc_delete_qc_third_party_item", "label": "delete_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L342"}, {"id": "api_qc_labtestitembody", "label": "LabTestItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L362"}, {"id": "api_qc_labtestitemupdatebody", "label": "LabTestItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L373"}, {"id": "api_qc_itemparambody", "label": "ItemParamBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L387"}, {"id": "api_qc_taskresultbody", "label": "TaskResultBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L392"}, {"id": "api_qc_taskcompletewithresultbody", "label": "TaskCompleteWithResultBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L397"}, {"id": "api_qc_list_qc_lab_test_items", "label": "list_qc_lab_test_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L407"}, {"id": "api_qc_list_qc_lab_test_items_active", "label": "list_qc_lab_test_items_active()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L429"}, {"id": "api_qc_create_qc_lab_test_item", "label": "create_qc_lab_test_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L443"}, {"id": "api_qc_update_qc_lab_test_item", "label": "update_qc_lab_test_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L471"}, {"id": "api_Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_work_order_py", "label": "qc_work_order.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L1"}, {"id": "crud_qc_work_order_resolve_outbound_biz_type_for_schedule", "label": "resolve_outbound_biz_type_for_schedule()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L89"}, {"id": "crud_qc_work_order_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L130"}, {"id": "crud_qc_work_order_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L136"}, {"id": "crud_qc_work_order_normalize_date_bound", "label": "_normalize_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L140"}, {"id": "crud_qc_work_order_reception_source_label", "label": "_reception_source_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L147"}, {"id": "crud_qc_work_order_qc_biz_type_label", "label": "_qc_biz_type_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L152"}, {"id": "crud_qc_work_order_work_order_qc_biz_type", "label": "_work_order_qc_biz_type()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L157"}, {"id": "crud_qc_work_order_validate_cell_product_id", "label": "_validate_cell_product_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L164"}, {"id": "crud_qc_work_order_enrich_work_order_cell_products", "label": "_enrich_work_order_cell_products()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L176"}, {"id": "crud_qc_work_order_enrich_work_order_step_outputs", "label": "_enrich_work_order_step_outputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L205"}, {"id": "crud_qc_work_order_enrich_work_order_qc_targets", "label": "_enrich_work_order_qc_targets()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L244"}, {"id": "crud_qc_work_order_enrich_outbound_work_orders", "label": "_enrich_outbound_work_orders()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L251"}, {"id": "crud_qc_work_order_outbound_qc_work_order_ids_by_keyword", "label": "_outbound_qc_work_order_ids_by_keyword()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L372"}, {"id": "crud_qc_work_order_accept_conclusion_label", "label": "_accept_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L419"}, {"id": "crud_qc_work_order_load_sample_type_name_map", "label": "_load_sample_type_name_map()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L424"}, {"id": "crud_qc_work_order_effective_reception_source", "label": "_effective_reception_source()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L436"}, {"id": "crud_qc_work_order_effective_donation_sample_id", "label": "_effective_donation_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L445"}, {"id": "crud_qc_work_order_effective_protocol_sample_id", "label": "_effective_protocol_sample_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L454"}, {"id": "crud_qc_work_order_sample_type_name_for_item", "label": "_sample_type_name_for_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L462"}, {"id": "crud_qc_work_order_sample_type_name_for_reception", "label": "_sample_type_name_for_reception()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py", "source_location": "L480"}, {"id": "crud_qc_work_order_enrich_work_order_list_items", "label": "_enrich_work_order_list_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/bLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_production_task_py", "label": "production_task.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L1"}, {"id": "crud_production_task_require_requisition_for_catalog_material", "label": "_require_requisition_for_catalog_material()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L49"}, {"id": "crud_production_task_production_conclusion_label", "label": "_production_conclusion_label()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L101"}, {"id": "crud_production_task_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L108"}, {"id": "crud_production_task_normalize_date_bound", "label": "_normalize_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L112"}, {"id": "crud_production_task_enrich_outbound_task_items", "label": "_enrich_outbound_task_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L119"}, {"id": "crud_production_task_generate_task_no", "label": "_generate_task_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L253"}, {"id": "crud_production_task_task_to_dict", "label": "_task_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L267"}, {"id": "crud_production_task_step_to_dict", "label": "_step_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L294"}, {"id": "crud_production_task_step_reagent_to_dict", "label": "_step_reagent_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L321"}, {"id": "crud_production_task_step_configured_reagent_to_dict", "label": "_step_configured_reagent_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L338"}, {"id": "crud_production_task_step_consumable_to_dict", "label": "_step_consumable_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L354"}, {"id": "crud_production_task_step_output_to_dict", "label": "_step_output_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L371"}, {"id": "crud_production_task_step_data_collection_to_dict", "label": "_step_data_collection_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L383"}, {"id": "crud_production_task_task_input_to_dict", "label": "_task_input_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L395"}, {"id": "crud_production_task_task_output_to_dict", "label": "_task_output_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L417"}, {"id": "crud_production_task_soft_delete_sub", "label": "_soft_delete_sub()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L442"}, {"id": "crud_production_task_resolve_sub_table_order_num", "label": "_resolve_sub_table_order_num()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L455"}, {"id": "crud_production_task_step_sub_tables_to_dict", "label": "_step_sub_tables_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L464"}, {"id": "crud_production_task_clone_step_reagents", "label": "_clone_step_reagents()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L490"}, {"id": "crud_production_task_clone_step_consumables", "label": "_clone_step_consumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L513"}, {"id": "crud_production_task_clone_step_outputs", "label": "_clone_step_outputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py", "source_location": "L536"}, Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_env_detect_py", "label": "env_detect.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L1"}, {"id": "api_env_detect_get_tenant_no", "label": "_get_tenant_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L22"}, {"id": "api_env_detect_get_current_user_id", "label": "_get_current_user_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L32"}, {"id": "api_env_detect_page_payload", "label": "_page_payload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L39"}, {"id": "api_env_detect_envdetectitembody", "label": "EnvDetectItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L52"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_env_detect_envdetectitemupdatebody", "label": "EnvDetectItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L62"}, {"id": "api_env_detect_list_env_detect_items", "label": "list_env_detect_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L73"}, {"id": "api_env_detect_list_active_env_detect_items", "label": "list_active_env_detect_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L117"}, {"id": "api_env_detect_get_env_detect_item", "label": "get_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L132"}, {"id": "api_env_detect_create_env_detect_item", "label": "create_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L150"}, {"id": "api_env_detect_update_env_detect_item", "label": "update_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L181"}, {"id": "api_env_detect_delete_env_detect_item", "label": "delete_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L211"}, {"id": "api_env_detect_parse_detect_date", "label": "_parse_detect_date()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L231"}, {"id": "api_env_detect_parse_detect_date_bound", "label": "_parse_detect_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L241"}, {"id": "api_env_detect_envdetectrecordbody", "label": "EnvDetectRecordBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L251"}, {"id": "api_env_detect_envdetectrecordupdatebody", "label": "EnvDetectRecordUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L263"}, {"id": "api_env_detect_list_env_detect_records", "label": "list_env_detect_records()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L276"}, {"id": "api_env_detect_get_env_detect_record", "label": "get_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L336"}, {"id": "api_env_detect_create_env_detect_record", "label": "create_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L354"}, {"id": "api_env_detect_update_env_detect_record", "label": "update_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L395"}, {"id": "api_env_detect_delete_env_detect_record", "label": "delete_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L437"}, {"id": "api_env_detect_rationale_1", "label": "\u73af\u5883\u68c0\u6d4b \u2014 \u68c0\u6d4b\u9879\u7ef4\u62a4 + \u767b\u8bb0\u7ba1\u7406 API", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_api_env_detect_py", "target": "datetime", "relation": "imports_froLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "label": "qc_item_param.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L1"}, {"id": "crud_qc_item_param_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L13"}, {"id": "crud_qc_item_param_parse_options_list", "label": "_parse_options_list()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L27"}, {"id": "crud_qc_item_param_validate_param", "label": "_validate_param()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L43"}, {"id": "crud_qc_item_param_list_params_by_item", "label": "list_params_by_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L55"}, {"id": "crud_qc_item_param_save_params_for_item", "label": "save_params_for_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L71"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "json", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L3", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "sqlalchemy_orm", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L7", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "app_core_utils", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L9", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "app_models_qc_param", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L10", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "crud_qc_item_param_row_to_dict", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L13", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "crud_qc_item_param_parse_options_list", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L27", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "crud_qc_item_param_validate_param", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L43", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "crud_qc_item_param_list_params_by_item", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L55", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "crud_qc_item_param_save_params_for_item", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L71", "weight": 1.0}, {"source": "crud_qc_item_param_validate_param", "target": "crud_qc_item_param_parse_options_list", "relation": "calls", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L48", "weight": 1.0}, {"source": "crud_qc_item_param_list_params_by_item", "target": "crud_qc_item_param_row_to_dict", "relation": "calls", "confidence": "EXTRACTED", "source_file": "Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_env_detect_py", "label": "env_detect.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L1"}, {"id": "api_env_detect_get_tenant_no", "label": "_get_tenant_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L21"}, {"id": "api_env_detect_get_current_user_id", "label": "_get_current_user_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L31"}, {"id": "api_env_detect_page_payload", "label": "_page_payload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L38"}, {"id": "api_env_detect_envdetectitembody", "label": "EnvDetectItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L51"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_env_detect_envdetectitemupdatebody", "label": "EnvDetectItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L61"}, {"id": "api_env_detect_list_env_detect_items", "label": "list_env_detect_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L72"}, {"id": "api_env_detect_list_active_env_detect_items", "label": "list_active_env_detect_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L116"}, {"id": "api_env_detect_get_env_detect_item", "label": "get_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L131"}, {"id": "api_env_detect_create_env_detect_item", "label": "create_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L149"}, {"id": "api_env_detect_update_env_detect_item", "label": "update_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L180"}, {"id": "api_env_detect_delete_env_detect_item", "label": "delete_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L210"}, {"id": "api_env_detect_envdetectrecordbody", "label": "EnvDetectRecordBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L230"}, {"id": "api_env_detect_envdetectrecordupdatebody", "label": "EnvDetectRecordUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L242"}, {"id": "api_env_detect_list_env_detect_records", "label": "list_env_detect_records()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L255"}, {"id": "api_env_detect_get_env_detect_record", "label": "get_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L315"}, {"id": "api_env_detect_create_env_detect_record", "label": "create_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L333"}, {"id": "api_env_detect_update_env_detect_record", "label": "update_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L374"}, {"id": "api_env_detect_delete_env_detect_record", "label": "delete_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L416"}, {"id": "api_env_detect_rationale_1", "label": "\u73af\u5883\u68c0\u6d4b \u2014 \u68c0\u6d4b\u9879\u7ef4\u62a4 + \u767b\u8bb0\u7ba1\u7406 API", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_api_env_detect_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_api_env_detect_py", "target": "fastapi", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L4", "weight": 1.0},Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_env_detect_py", "label": "env_detect.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L1"}, {"id": "api_env_detect_get_tenant_no", "label": "_get_tenant_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L21"}, {"id": "api_env_detect_get_current_user_id", "label": "_get_current_user_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L31"}, {"id": "api_env_detect_page_payload", "label": "_page_payload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L38"}, {"id": "api_env_detect_envdetectitembody", "label": "EnvDetectItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L51"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_env_detect_envdetectitemupdatebody", "label": "EnvDetectItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L61"}, {"id": "api_env_detect_list_env_detect_items", "label": "list_env_detect_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L72"}, {"id": "api_env_detect_list_active_env_detect_items", "label": "list_active_env_detect_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L116"}, {"id": "api_env_detect_get_env_detect_item", "label": "get_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L131"}, {"id": "api_env_detect_create_env_detect_item", "label": "create_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L149"}, {"id": "api_env_detect_update_env_detect_item", "label": "update_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L180"}, {"id": "api_env_detect_delete_env_detect_item", "label": "delete_env_detect_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L210"}, {"id": "api_env_detect_envdetectrecordbody", "label": "EnvDetectRecordBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L230"}, {"id": "api_env_detect_envdetectrecordupdatebody", "label": "EnvDetectRecordUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L242"}, {"id": "api_env_detect_list_env_detect_records", "label": "list_env_detect_records()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L255"}, {"id": "api_env_detect_get_env_detect_record", "label": "get_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L315"}, {"id": "api_env_detect_create_env_detect_record", "label": "create_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L333"}, {"id": "api_env_detect_update_env_detect_record", "label": "update_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L374"}, {"id": "api_env_detect_delete_env_detect_record", "label": "delete_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L416"}, {"id": "api_env_detect_rationale_1", "label": "\u73af\u5883\u68c0\u6d4b \u2014 \u68c0\u6d4b\u9879\u7ef4\u62a4 + \u767b\u8bb0\u7ba1\u7406 API", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_api_env_detect_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_api_env_detect_py", "target": "fastapi", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py", "source_location": "L4", "weight": 1.0},Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_qc_py", "label": "qc.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L1"}, {"id": "api_qc_thirdpartycompanybody", "label": "ThirdPartyCompanyBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L48"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_qc_thirdpartycompanyupdatebody", "label": "ThirdPartyCompanyUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L66"}, {"id": "api_qc_list_qc_third_party_companies", "label": "list_qc_third_party_companies()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L85"}, {"id": "api_qc_list_qc_third_party_company_options", "label": "list_qc_third_party_company_options()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L107"}, {"id": "api_qc_create_qc_third_party_company", "label": "create_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L121"}, {"id": "api_qc_update_qc_third_party_company", "label": "update_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L156"}, {"id": "api_qc_delete_qc_third_party_company", "label": "delete_qc_third_party_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L193"}, {"id": "api_qc_thirdpartyitembody", "label": "ThirdPartyItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L213"}, {"id": "api_qc_thirdpartyitemupdatebody", "label": "ThirdPartyItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L225"}, {"id": "api_qc_list_qc_third_party_items", "label": "list_qc_third_party_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L238"}, {"id": "api_qc_list_qc_third_party_items_active", "label": "list_qc_third_party_items_active()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L267"}, {"id": "api_qc_create_qc_third_party_item", "label": "create_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L282"}, {"id": "api_qc_update_qc_third_party_item", "label": "update_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L311"}, {"id": "api_qc_delete_qc_third_party_item", "label": "delete_qc_third_party_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L342"}, {"id": "api_qc_labtestitembody", "label": "LabTestItemBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L362"}, {"id": "api_qc_labtestitemupdatebody", "label": "LabTestItemUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L373"}, {"id": "api_qc_itemparambody", "label": "ItemParamBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L387"}, {"id": "api_qc_taskresultbody", "label": "TaskResultBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L392"}, {"id": "api_qc_taskcompletewithresultbody", "label": "TaskCompleteWithResultBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L397"}, {"id": "api_qc_list_qc_lab_test_items", "label": "list_qc_lab_test_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L407"}, {"id": "api_qc_list_qc_lab_test_items_active", "label": "list_qc_lab_test_items_active()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L429"}, {"id": "api_qc_create_qc_lab_test_item", "label": "create_qc_lab_test_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L443"}, {"id": "api_qc_update_qc_lab_test_item", "label": "update_qc_lab_test_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py", "source_location": "L471"}, {"id": "api_Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "label": "qc_item_param.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L1"}, {"id": "crud_qc_item_param_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L13"}, {"id": "crud_qc_item_param_parse_options_list", "label": "_parse_options_list()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L27"}, {"id": "crud_qc_item_param_validate_param", "label": "_validate_param()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L43"}, {"id": "crud_qc_item_param_list_params_by_item", "label": "list_params_by_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L58"}, {"id": "crud_qc_item_param_save_params_for_item", "label": "save_params_for_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L74"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "json", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L3", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "sqlalchemy_orm", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L7", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "app_core_utils", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L9", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "app_models_qc_param", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L10", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "crud_qc_item_param_row_to_dict", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L13", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "crud_qc_item_param_parse_options_list", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L27", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "crud_qc_item_param_validate_param", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L43", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "crud_qc_item_param_list_params_by_item", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L58", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_qc_item_param_py", "target": "crud_qc_item_param_save_params_for_item", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L74", "weight": 1.0}, {"source": "crud_qc_item_param_validate_param", "target": "crud_qc_item_param_parse_options_list", "relation": "calls", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py", "source_location": "L48", "weight": 1.0}, {"source": "crud_qc_item_param_list_params_by_item", "target": "crud_qc_item_param_row_to_dict", "relation": "calls", "confidence": "EXTRACTED", "source_file": "Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_models_production_material_py", "label": "production_material.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L1"}, {"id": "models_production_material_bizproductionmaterial", "label": "BizProductionMaterial", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L8"}, {"id": "base", "label": "Base", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "models_production_material_bizproductionmaterialstockbatch", "label": "BizProductionMaterialStockBatch", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L31"}, {"id": "models_production_material_bizproductionmaterialusage", "label": "BizProductionMaterialUsage", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L64"}, {"id": "models_production_material_bizproductionmaterialformula", "label": "BizProductionMaterialFormula", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L114"}, {"id": "models_production_material_bizproductionmaterialprep", "label": "BizProductionMaterialPrep", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L136"}, {"id": "models_production_material_bizproductionmaterialprepline", "label": "BizProductionMaterialPrepLine", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L164"}, {"id": "models_production_material_bizproductionmaterialstockcheck", "label": "BizProductionMaterialStockCheck", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L187"}, {"id": "models_production_material_bizproductionmaterialstockcheckbatchline", "label": "BizProductionMaterialStockCheckBatchLine", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L206"}, {"id": "models_production_material_bizproductionmaterialstockcheckunusedline", "label": "BizProductionMaterialStockCheckUnusedLine", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L239"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_models_production_material_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_models_production_material_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L3", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_models_production_material_py", "target": "app_core_database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_models_production_material_py", "target": "models_production_material_bizproductionmaterial", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L8", "weight": 1.0}, {"source": "models_production_material_bizproductionmaterial", "target": "base", "relation": "inherits", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L8", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_models_production_material_py", "target": "models_production_material_bizproductionmaterialstockbatch", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L31", "weight": 1.0}, {"source": "models_production_material_bizproductionmaterialstockbatch", "target": "base", "relation": "inherits", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py", "source_location": "L31", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_models_production_material_py", "target": "models_production_material_bizproductionmaterialusage", "relation": "contains", "confidence": "EXTRACTED", "sourceLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_models_qc_param_py", "label": "qc_param.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py", "source_location": "L1"}, {"id": "models_qc_param_bizqcitemparam", "label": "BizQcItemParam", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py", "source_location": "L8"}, {"id": "base", "label": "Base", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "models_qc_param_bizqctaskresult", "label": "BizQcTaskResult", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py", "source_location": "L32"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_models_qc_param_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_models_qc_param_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py", "source_location": "L3", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_models_qc_param_py", "target": "app_core_database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_models_qc_param_py", "target": "models_qc_param_bizqcitemparam", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py", "source_location": "L8", "weight": 1.0}, {"source": "models_qc_param_bizqcitemparam", "target": "base", "relation": "inherits", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py", "source_location": "L8", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_models_qc_param_py", "target": "models_qc_param_bizqctaskresult", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py", "source_location": "L32", "weight": 1.0}, {"source": "models_qc_param_bizqctaskresult", "target": "base", "relation": "inherits", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py", "source_location": "L32", "weight": 1.0}], "raw_calls": []}
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_models_models_py", "label": "models.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L1"}, {"id": "models_models_userrole", "label": "UserRole", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L10"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "models_models_sysuser", "label": "SysUser", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L22"}, {"id": "base", "label": "Base", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "models_models_sysrole", "label": "SysRole", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L48"}, {"id": "models_models_sysuserrole", "label": "SysUserRole", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L68"}, {"id": "models_models_sysrolemenu", "label": "SysRoleMenu", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L87"}, {"id": "models_models_sysroledatascopedetail", "label": "SysRoleDataScopeDetail", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L106"}, {"id": "models_models_sysmenu", "label": "SysMenu", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L126"}, {"id": "models_models_sysdept", "label": "SysDept", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L152"}, {"id": "models_models_systenant", "label": "SysTenant", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L175"}, {"id": "models_models_syssite", "label": "SysSite", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L195"}, {"id": "models_models_syspost", "label": "SysPost", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L221"}, {"id": "models_models_sysuserpost", "label": "SysUserPost", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L241"}, {"id": "models_models_bizitemunit", "label": "BizItemUnit", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L260"}, {"id": "models_models_bizexpresscompany", "label": "BizExpressCompany", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L279"}, {"id": "models_models_bizcustomer", "label": "BizCustomer", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L299"}, {"id": "models_models_bizcellsampletype", "label": "BizCellSampleType", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L322"}, {"id": "models_models_bizcollectionregion", "label": "BizCollectionRegion", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L345"}, {"id": "models_models_bizcollectionhospital", "label": "BizCollectionHospital", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L363"}, {"id": "models_models_bizcollectionprotocolno", "label": "BizCollectionProtocolNo", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L382"}, {"id": "models_models_bizbiznosequence", "label": "BizBizNoSequence", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L404"}, {"id": "models_models_bizsamplecode", "label": "BizSampleCode", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L424"}, {"id": "models_models_sysdicttype", "label": "SysDictType", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L452"}, {"id": "models_models_sysethnic", "label": "SysEthnic", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L471"}, {"id": "models_models_sysdictdata", "label": "SysDictData", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location"Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "label": "env_detect_record.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L1"}, {"id": "crud_env_detect_record_split_csv", "label": "_split_csv()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L15"}, {"id": "crud_env_detect_record_join_csv", "label": "_join_csv()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L19"}, {"id": "crud_env_detect_record_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L23"}, {"id": "crud_env_detect_record_generate_record_no", "label": "_generate_record_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L47"}, {"id": "crud_env_detect_record_resolve_inspector_snapshots", "label": "_resolve_inspector_snapshots()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L69"}, {"id": "crud_env_detect_record_resolve_item_snapshot", "label": "_resolve_item_snapshot()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L102"}, {"id": "crud_env_detect_record_get_env_detect_record", "label": "get_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L113"}, {"id": "crud_env_detect_record_list_env_detect_records", "label": "list_env_detect_records()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L124"}, {"id": "crud_env_detect_record_create_env_detect_record", "label": "create_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L181"}, {"id": "crud_env_detect_record_update_env_detect_record", "label": "update_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L230"}, {"id": "crud_env_detect_record_soft_delete_env_detect_record", "label": "soft_delete_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L282"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L7", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "sqlalchemy_orm", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L8", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "app_core_utils", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L10", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "app_crud", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L11", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "app_models_models", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L12", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "crud_env_detect_record_split_csv", "relation": "contains", "confidence": "EXTRACTED"Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_reception_py", "label": "sample_reception.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L1"}, {"id": "crud_sample_reception_donation_sample_id_col", "label": "_donation_sample_id_col()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L36"}, {"id": "crud_sample_reception_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L41"}, {"id": "crud_sample_reception_normalize_date_bound", "label": "_normalize_date_bound()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L45"}, {"id": "crud_sample_reception_dec", "label": "_dec()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L52"}, {"id": "crud_sample_reception_reception_to_dict", "label": "_reception_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L58"}, {"id": "crud_sample_reception_sample_detail_rows_query", "label": "_sample_detail_rows_query()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L83"}, {"id": "crud_sample_reception_donation_sample_detail_rows_query", "label": "_donation_sample_detail_rows_query()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L117"}, {"id": "crud_sample_reception_donation_sample_pending_query", "label": "_donation_sample_pending_query()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L151"}, {"id": "crud_sample_reception_donation_rows_to_sample_list_items", "label": "_donation_rows_to_sample_list_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L188"}, {"id": "crud_sample_reception_sample_pending_query", "label": "_sample_pending_query()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L284"}, {"id": "crud_sample_reception_rows_to_sample_list_items", "label": "_rows_to_sample_list_items()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L321"}, {"id": "crud_sample_reception_list_pending_protocol_samples", "label": "list_pending_protocol_samples()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L427"}, {"id": "crud_sample_reception_list_received_protocol_samples", "label": "list_received_protocol_samples()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L500"}, {"id": "crud_sample_reception_get_reception_by_id", "label": "get_reception_by_id()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L639"}, {"id": "crud_sample_reception_create_sample_reception", "label": "create_sample_reception()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L707"}, {"id": "crud_sample_reception_update_sample_reception", "label": "update_sample_reception()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L971"}, {"id": "crud_sample_reception_reception_detail_item", "label": "_reception_detail_item()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L1086"}, {"id": "crud_sample_reception_reception_sample_code", "label": "_reception_sample_code()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L1103"}, {"id": "crud_sample_reception_get_receptions_map_for_samples", "label": "get_receptions_map_for_samples()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L1118"}, {"id": "crud_sample_reception_get_receptions_map_for_donation_samples", "label": "get_receptions_map_for_donation_samples()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py", "source_location": "L1163"}, {"id": "crud_sample_reception_get_lab_storage_code_map_by_sample_codes", "label": "get_lab_storLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "label": "env_detect_record.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L1"}, {"id": "crud_env_detect_record_split_csv", "label": "_split_csv()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L15"}, {"id": "crud_env_detect_record_join_csv", "label": "_join_csv()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L19"}, {"id": "crud_env_detect_record_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L23"}, {"id": "crud_env_detect_record_generate_record_no", "label": "_generate_record_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L47"}, {"id": "crud_env_detect_record_resolve_inspector_snapshots", "label": "_resolve_inspector_snapshots()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L69"}, {"id": "crud_env_detect_record_resolve_item_snapshot", "label": "_resolve_item_snapshot()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L102"}, {"id": "crud_env_detect_record_get_env_detect_record", "label": "get_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L113"}, {"id": "crud_env_detect_record_list_env_detect_records", "label": "list_env_detect_records()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L124"}, {"id": "crud_env_detect_record_create_env_detect_record", "label": "create_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L181"}, {"id": "crud_env_detect_record_update_env_detect_record", "label": "update_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L230"}, {"id": "crud_env_detect_record_soft_delete_env_detect_record", "label": "soft_delete_env_detect_record()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L282"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L7", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "sqlalchemy_orm", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L8", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "app_core_utils", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L10", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "app_crud", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L11", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "app_models_models", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py", "source_location": "L12", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_env_detect_record_py", "target": "crud_env_detect_record_split_csv", "relation": "contains", "confidence": "EXTRACTED"Line truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_models_models_py", "label": "models.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L1"}, {"id": "models_models_userrole", "label": "UserRole", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L10"}, {"id": "str", "label": "str", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "models_models_sysuser", "label": "SysUser", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L22"}, {"id": "base", "label": "Base", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "models_models_sysrole", "label": "SysRole", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L48"}, {"id": "models_models_sysuserrole", "label": "SysUserRole", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L68"}, {"id": "models_models_sysrolemenu", "label": "SysRoleMenu", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L87"}, {"id": "models_models_sysroledatascopedetail", "label": "SysRoleDataScopeDetail", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L106"}, {"id": "models_models_sysmenu", "label": "SysMenu", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L126"}, {"id": "models_models_sysdept", "label": "SysDept", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L152"}, {"id": "models_models_systenant", "label": "SysTenant", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L175"}, {"id": "models_models_syssite", "label": "SysSite", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L195"}, {"id": "models_models_syspost", "label": "SysPost", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L221"}, {"id": "models_models_sysuserpost", "label": "SysUserPost", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L241"}, {"id": "models_models_bizitemunit", "label": "BizItemUnit", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L260"}, {"id": "models_models_bizexpresscompany", "label": "BizExpressCompany", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L279"}, {"id": "models_models_bizcustomer", "label": "BizCustomer", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L299"}, {"id": "models_models_bizcellsampletype", "label": "BizCellSampleType", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L322"}, {"id": "models_models_bizcollectionregion", "label": "BizCollectionRegion", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L345"}, {"id": "models_models_bizcollectionhospital", "label": "BizCollectionHospital", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L363"}, {"id": "models_models_bizcollectionprotocolno", "label": "BizCollectionProtocolNo", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L382"}, {"id": "models_models_bizbiznosequence", "label": "BizBizNoSequence", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L404"}, {"id": "models_models_bizsamplecode", "label": "BizSampleCode", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L424"}, {"id": "models_models_sysdicttype", "label": "SysDictType", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L452"}, {"id": "models_models_sysethnic", "label": "SysEthnic", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location": "L471"}, {"id": "models_models_sysdictdata", "label": "SysDictData", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py", "source_location"Line truncated
|
||||
@@ -1373,6 +1373,46 @@ class BizQcWorkOrder(Base):
|
||||
del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记")
|
||||
|
||||
|
||||
class BizQcWorkOrderInspectionBatch(Base):
|
||||
"""质检工单检测批次 biz_qc_work_order_inspection_batch"""
|
||||
|
||||
__tablename__ = "biz_qc_work_order_inspection_batch"
|
||||
|
||||
id = Column(String(64), primary_key=True, comment="主键ID")
|
||||
work_order_id = Column(String(64), nullable=False, comment="工单ID")
|
||||
order_source = Column(String(20), nullable=False, default="inbound", comment="工单来源")
|
||||
batch_no = Column(String(32), nullable=False, comment="批次编号")
|
||||
batch_name = Column(String(200), nullable=False, comment="批次展示名")
|
||||
tenant_no = Column(String(64), nullable=False, default="zkxw", comment="租户编号")
|
||||
order_num = Column(Integer, nullable=True, comment="排序号")
|
||||
remark = Column(String(512), nullable=True, comment="备注")
|
||||
create_by = Column(String(64), nullable=True, comment="创建人id")
|
||||
create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
|
||||
create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
|
||||
update_by = Column(String(64), nullable=True, comment="更新人id")
|
||||
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
|
||||
del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记")
|
||||
|
||||
|
||||
class BizQcBatchAssignee(Base):
|
||||
"""质检检测批次负责人 biz_qc_batch_assignee"""
|
||||
|
||||
__tablename__ = "biz_qc_batch_assignee"
|
||||
|
||||
id = Column(String(64), primary_key=True, comment="主键")
|
||||
batch_id = Column(String(64), nullable=False, comment="检测批次ID")
|
||||
user_id = Column(String(64), nullable=False, comment="负责人用户ID")
|
||||
tenant_no = Column(String(64), nullable=False, default="zkxw", comment="租户编号")
|
||||
order_num = Column(Integer, nullable=True, default=0, comment="展示顺序")
|
||||
remark = Column(String(512), nullable=True, comment="备注")
|
||||
create_by = Column(String(64), nullable=True, comment="创建人id")
|
||||
create_dept_id = Column(String(64), nullable=True, comment="创建人部门ID")
|
||||
create_time = Column(DateTime, nullable=True, comment="创建时间")
|
||||
update_by = Column(String(64), nullable=True, comment="更新人id")
|
||||
update_time = Column(DateTime, nullable=True, comment="更新时间")
|
||||
del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记")
|
||||
|
||||
|
||||
class BizQcWorkOrderLabItem(Base):
|
||||
"""质检工单-实验室项目明细 biz_qc_work_order_lab_item"""
|
||||
|
||||
@@ -1381,6 +1421,7 @@ class BizQcWorkOrderLabItem(Base):
|
||||
id = Column(String(64), primary_key=True, comment="主键ID")
|
||||
work_order_id = Column(String(64), nullable=False, comment="工单ID")
|
||||
order_source = Column(String(20), nullable=False, default="inbound", comment="工单来源: inbound=入库, temporary=临时")
|
||||
batch_id = Column(String(64), nullable=True, comment="检测批次ID")
|
||||
lab_test_item_id = Column(String(64), nullable=False, comment="实验室项目ID")
|
||||
item_code = Column(String(64), nullable=False, comment="项目编码快照")
|
||||
item_name = Column(String(200), nullable=False, comment="项目名称快照")
|
||||
@@ -1403,6 +1444,7 @@ class BizQcWorkOrderThirdItem(Base):
|
||||
id = Column(String(64), primary_key=True, comment="主键ID")
|
||||
work_order_id = Column(String(64), nullable=False, comment="工单ID")
|
||||
order_source = Column(String(20), nullable=False, default="inbound", comment="工单来源: inbound=入库, temporary=临时")
|
||||
batch_id = Column(String(64), nullable=True, comment="检测批次ID")
|
||||
third_party_item_id = Column(String(64), nullable=False, comment="第三方项目ID")
|
||||
company_id = Column(String(64), nullable=False, comment="公司ID")
|
||||
company_name = Column(String(200), nullable=False, comment="公司名快照")
|
||||
@@ -1427,6 +1469,7 @@ class BizQcTask(Base):
|
||||
|
||||
id = Column(String(64), primary_key=True, comment="主键ID")
|
||||
work_order_id = Column(String(64), nullable=False, comment="工单ID")
|
||||
batch_id = Column(String(64), nullable=True, comment="检测批次ID")
|
||||
order_source = Column(String(20), nullable=False, default="inbound", comment="工单来源: inbound=入库, temporary=临时")
|
||||
task_no = Column(String(32), nullable=False, comment="任务号")
|
||||
task_type = Column(String(16), nullable=False, comment="sysz实验室 dsfjc第三方")
|
||||
@@ -3548,6 +3591,7 @@ class BizEnvDetectRecord(Base):
|
||||
id = Column(String(64), primary_key=True, comment="主键ID")
|
||||
record_no = Column(String(32), nullable=False, comment="登记编号")
|
||||
detect_time = Column(DateTime, nullable=False, comment="检测时间")
|
||||
result_time = Column(DateTime, nullable=True, comment="结果时间")
|
||||
inspector_ids = Column(String(500), nullable=False, comment="检测人用户ID,逗号分隔")
|
||||
inspector_names = Column(String(500), nullable=False, comment="检测人姓名快照,逗号分隔")
|
||||
env_detect_item_id = Column(String(64), nullable=False, comment="检测项目ID")
|
||||
|
||||
@@ -41,6 +41,7 @@ class BizProductionMaterialStockBatch(Base):
|
||||
stock_in_no = Column(String(64), nullable=False, comment="入库编号")
|
||||
stock_in_date = Column(Date, nullable=False, comment="入库日期")
|
||||
expire_date = Column(Date, nullable=False, comment="过期日期")
|
||||
production_date = Column(Date, nullable=True, comment="生产日期")
|
||||
catalog_no = Column(String(128), nullable=False, comment="货号")
|
||||
batch_no = Column(String(128), nullable=False, comment="批号")
|
||||
manufacturer = Column(String(200), nullable=False, comment="厂家")
|
||||
|
||||
@@ -15,6 +15,8 @@ class BizQcItemParam(Base):
|
||||
param_code = Column(String(64), nullable=False, comment="参数编码")
|
||||
param_unit = Column(String(32), nullable=True, comment="单位")
|
||||
param_type = Column(String(16), nullable=False, default="text", comment="number/text/select")
|
||||
options = Column(String(2000), nullable=True, comment="单选选项列表,JSON数组格式")
|
||||
default_value = Column(String(500), nullable=True, comment="单选默认值")
|
||||
required_flag = Column(CHAR(1), nullable=False, default="0", comment="1必填 0非必填")
|
||||
tenant_no = Column(String(64), nullable=False, default="zkxw", comment="租户编号")
|
||||
order_num = Column(Integer, nullable=True, comment="排序号")
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
+15375
-11363
File diff suppressed because it is too large.
Load diff
@@ -1,11 +1,11 @@
|
||||
# Graph Report - app (2026-06-25)
|
||||
# Graph Report - app (2026-06-26)
|
||||
|
||||
## Corpus Check
|
||||
- Large corpus: 211 files · ~251,177 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
|
||||
- Large corpus: 212 files · ~254,769 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
|
||||
|
||||
## Summary
|
||||
- 4285 nodes · 22669 edges · 43 communities detected
|
||||
- Extraction: 32% EXTRACTED · 68% INFERRED · 0% AMBIGUOUS · INFERRED: 15304 edges (avg confidence: 0.59)
|
||||
- 4340 nodes · 23048 edges · 54 communities detected
|
||||
- Extraction: 32% EXTRACTED · 68% INFERRED · 0% AMBIGUOUS · INFERRED: 15583 edges (avg confidence: 0.59)
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Community Hubs (Navigation)
|
||||
@@ -46,249 +46,306 @@
|
||||
- [[_COMMUNITY_Community 34|Community 34]]
|
||||
- [[_COMMUNITY_Community 35|Community 35]]
|
||||
- [[_COMMUNITY_Community 36|Community 36]]
|
||||
- [[_COMMUNITY_Community 37|Community 37]]
|
||||
- [[_COMMUNITY_Community 38|Community 38]]
|
||||
- [[_COMMUNITY_Community 39|Community 39]]
|
||||
- [[_COMMUNITY_Community 40|Community 40]]
|
||||
- [[_COMMUNITY_Community 41|Community 41]]
|
||||
- [[_COMMUNITY_Community 42|Community 42]]
|
||||
- [[_COMMUNITY_Community 43|Community 43]]
|
||||
- [[_COMMUNITY_Community 44|Community 44]]
|
||||
- [[_COMMUNITY_Community 45|Community 45]]
|
||||
- [[_COMMUNITY_Community 46|Community 46]]
|
||||
- [[_COMMUNITY_Community 47|Community 47]]
|
||||
- [[_COMMUNITY_Community 50|Community 50]]
|
||||
- [[_COMMUNITY_Community 51|Community 51]]
|
||||
- [[_COMMUNITY_Community 52|Community 52]]
|
||||
- [[_COMMUNITY_Community 53|Community 53]]
|
||||
- [[_COMMUNITY_Community 54|Community 54]]
|
||||
- [[_COMMUNITY_Community 55|Community 55]]
|
||||
|
||||
## God Nodes (most connected - your core abstractions)
|
||||
1. `success_response()` - 653 edges
|
||||
2. `error_response()` - 539 edges
|
||||
3. `SysUser` - 462 edges
|
||||
4. `BizProductionMaterial` - 300 edges
|
||||
5. `BizProductionMaterialUsage` - 300 edges
|
||||
6. `BizQcTaskResult` - 299 edges
|
||||
7. `BizQcMaterialUsage` - 297 edges
|
||||
8. `BizQcMaterial` - 288 edges
|
||||
9. `BizProductionMaterialStockBatch` - 287 edges
|
||||
10. `BizMaterialUsage` - 284 edges
|
||||
1. `success_response()` - 658 edges
|
||||
2. `error_response()` - 544 edges
|
||||
3. `SysUser` - 466 edges
|
||||
4. `BizProductionMaterial` - 305 edges
|
||||
5. `BizQcTaskResult` - 305 edges
|
||||
6. `BizProductionMaterialUsage` - 304 edges
|
||||
7. `BizQcMaterialUsage` - 301 edges
|
||||
8. `BizQcMaterial` - 292 edges
|
||||
9. `BizProductionMaterialStockBatch` - 291 edges
|
||||
10. `BizMaterialUsage` - 288 edges
|
||||
|
||||
## Surprising Connections (you probably didn't know these)
|
||||
- `统一记录 API 请求/响应出入参的中间件` --uses--> `SysApiRequestLog` [INFERRED]
|
||||
core/api_request_log_middleware.py → models/models.py
|
||||
- `list_my_qc_material_usages()` --calls--> `strip_row_fields()` [INFERRED]
|
||||
api/qc.py → core/menu_guard.py
|
||||
- `中试服务申请单管理 API(申请单、患者信息、输注方案、输注计划、出库联动)` --uses--> `SysUser` [INFERRED]
|
||||
api/pilot_application.py → models/models.py
|
||||
- `中试服务交付管理 API(交付信息、交付物料、交付方式)` --uses--> `SysUser` [INFERRED]
|
||||
api/pilot_delivery.py → models/models.py
|
||||
- `中试服务体检管理 API(体检信息、预约项目、实际项目)` --uses--> `SysUser` [INFERRED]
|
||||
api/pilot_checkup.py → models/models.py
|
||||
- `get_menu_list()` --calls--> `success_response()` [INFERRED]
|
||||
api/menu.py → core/response.py
|
||||
- `保留匹配节点及其全部上级,供关键词检索后仍能正确组树。` --uses--> `SysDept` [INFERRED]
|
||||
crud/dept.py → models/models.py
|
||||
- `物品单位 CRUD(biz_item_unit)` --uses--> `BizItemUnit` [INFERRED]
|
||||
crud/item_unit.py → models/models.py
|
||||
- `快递公司 CRUD(biz_express_company)` --uses--> `BizExpressCompany` [INFERRED]
|
||||
crud/express_company.py → models/models.py
|
||||
|
||||
## Communities
|
||||
|
||||
### Community 0 - "Community 0"
|
||||
Cohesion: 0.01
|
||||
Nodes (862): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+854 more)
|
||||
Nodes (821): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+813 more)
|
||||
|
||||
### Community 1 - "Community 1"
|
||||
Cohesion: 0.01
|
||||
Nodes (605): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+597 more)
|
||||
Nodes (600): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+592 more)
|
||||
|
||||
### Community 2 - "Community 2"
|
||||
Cohesion: 0.01
|
||||
Nodes (432): generate_uuid(), ApiRequestLogCRUD, delete(), get_multi_with_filters(), create_cell_sample_type(), get_cell_sample_type(), list_cell_sample_types(), 细胞样本类型 CRUD(biz_cell_sample_type) (+424 more)
|
||||
Cohesion: 0.09
|
||||
Nodes (344): 环境检测 — 检测项维护 + 登记管理 API, 保险公司及险种价格管理 API(保险公司 + 开票信息 + 险种价格), ProcessDefCreateBody, ProcessDefUpdateBody, PublishVersionBody, 审批意见:前端传 commentText,兼容 comment。, StartInstanceBody, TaskActionBody (+336 more)
|
||||
|
||||
### Community 3 - "Community 3"
|
||||
Cohesion: 0.08
|
||||
Nodes (367): 环境检测 — 检测项维护 + 登记管理 API, 保险公司及险种价格管理 API(保险公司 + 开票信息 + 险种价格), AccessLogCreateBody, AccessLogUpdateBody, CleanRoomCreateBody, CleanRoomUpdateBody, ExhibitionAppointmentCreateBody, ExhibitionAppointmentUpdateBody (+359 more)
|
||||
Cohesion: 0.01
|
||||
Nodes (314): generate_uuid(), batch_stock_in(), batch_stock_out(), consumable_code_exists(), create_consumable(), _dec(), get_consumable(), _is_enabled_status() (+306 more)
|
||||
|
||||
### Community 4 - "Community 4"
|
||||
Cohesion: 0.01
|
||||
Nodes (300): _normalize_date_bound(), _persist_protocol_sub_resources(), list_ethnics_for_select(), apply_data_scope(), _get_child_dept_ids(), get_user_dept_id(), _resolve_user_role_scopes(), format_date() (+292 more)
|
||||
Cohesion: 0.02
|
||||
Nodes (248): _normalize_date_bound(), _persist_protocol_sub_resources(), format_date(), generate_id(), optional_date(), parse_date(), 将字符串 / date / datetime 转为 date 或 None, camel_to_snake() (+240 more)
|
||||
|
||||
### Community 5 - "Community 5"
|
||||
Cohesion: 0.07
|
||||
Nodes (231): CellSampleTypeCreateBody, CellSampleTypeUpdateBody, CollectionRegionCreateBody, CollectionRegionUpdateBody, CustomerCreateBody, CustomerUpdateBody, HospitalCreateBody, HospitalUpdateBody (+223 more)
|
||||
Nodes (252): CellSampleTypeCreateBody, CellSampleTypeUpdateBody, CollectionRegionCreateBody, CollectionRegionUpdateBody, CustomerCreateBody, CustomerUpdateBody, HospitalCreateBody, HospitalUpdateBody (+244 more)
|
||||
|
||||
### Community 6 - "Community 6"
|
||||
Cohesion: 0.02
|
||||
Nodes (191): eq_unicode(), like_unicode(), MySQL 字符串比较/模糊匹配时统一排序规则,避免 Illegal mix of collations。, 跨表字符串等值比较(JOIN / WHERE)时统一为 utf8mb4_unicode_ci。, 将列显式设为 utf8mb4_unicode_ci。, unicode_ci(), batch_review(), _dec() (+183 more)
|
||||
Nodes (225): list_ethnics_for_select(), AccessLogCreateBody, AccessLogUpdateBody, CleanRoomCreateBody, CleanRoomUpdateBody, create_access_log(), create_storage_slot(), create_uv_disinfect_log() (+217 more)
|
||||
|
||||
### Community 7 - "Community 7"
|
||||
Cohesion: 0.02
|
||||
Nodes (167): _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), get_material_entity(), get_my_usages(), _is_enabled_status() (+159 more)
|
||||
Nodes (226): eq_unicode(), like_unicode(), MySQL 字符串比较/模糊匹配时统一排序规则,避免 Illegal mix of collations。, 跨表字符串等值比较(JOIN / WHERE)时统一为 utf8mb4_unicode_ci。, 将列显式设为 utf8mb4_unicode_ci。, unicode_ci(), batch_review(), _dec() (+218 more)
|
||||
|
||||
### Community 8 - "Community 8"
|
||||
Cohesion: 0.02
|
||||
Nodes (110): get_designer_data(), _error_json(), 数据库异常:返回 JSON 并保留 CORS 头,避免浏览器只报跨域错误, 未捕获异常:统一 JSON 500,确保跨域场景下仍有 Access-Control-Allow-Origin, sqlalchemy_exception_handler(), unhandled_exception_handler(), BaseHTTPMiddleware, parse_admin_request_json() (+102 more)
|
||||
Cohesion: 0.03
|
||||
Nodes (167): batch_discard(), batch_options(), _batch_row_to_dict(), batch_stock_in(), batch_stock_out(), _create_batch_and_usage(), delete_batch(), _discard_batch() (+159 more)
|
||||
|
||||
### Community 9 - "Community 9"
|
||||
Cohesion: 0.02
|
||||
Nodes (135): get_role_menus(), list_storage_slots(), get_protocol_nos_used_in_protocols(), create_dict_type(), dict_type_code_exists(), get_dict_type(), list_dict_types(), 字典类型 CRUD(sys_dict_type) (+127 more)
|
||||
Nodes (107): get_designer_data(), _error_json(), 数据库异常:返回 JSON 并保留 CORS 头,避免浏览器只报跨域错误, 未捕获异常:统一 JSON 500,确保跨域场景下仍有 Access-Control-Allow-Origin, sqlalchemy_exception_handler(), unhandled_exception_handler(), BaseHTTPMiddleware, ApiCryptoError (+99 more)
|
||||
|
||||
### Community 10 - "Community 10"
|
||||
Cohesion: 0.04
|
||||
Nodes (75): list_roles_for_select(), _avatar_url_field(), _build_current_user_payload(), _build_user_info_payload(), change_current_user_password(), get_current_user_profile(), _jwt_user_payload(), logout() (+67 more)
|
||||
Cohesion: 0.03
|
||||
Nodes (124): map_payments_by_schedule_ids(), get_protocol_nos_used_in_protocols(), create_dict_type(), dict_type_code_exists(), get_dict_type(), list_dict_types(), 字典类型 CRUD(sys_dict_type), _row_to_dict() (+116 more)
|
||||
|
||||
### Community 11 - "Community 11"
|
||||
Cohesion: 0.08
|
||||
Nodes (60): batch_delete_research_donations(), change_donation_status(), convert_from_storage(), convert_to_storage(), create_research_donation(), delete_research_donation(), _get_current_user_id(), get_research_donation_detail() (+52 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (67): get_next_cell_product_code(), _ancestor_link_from_cell_product_input(), _ancestor_sample_chain_link(), _apply_cell_product_status_change(), _build_ancestor_chain(), _build_descendant_chain(), _build_facility_path_label(), build_split_product_codes() (+59 more)
|
||||
|
||||
### Community 12 - "Community 12"
|
||||
Cohesion: 0.07
|
||||
Nodes (57): _ancestor_link_from_cell_product_input(), _ancestor_sample_chain_link(), _apply_cell_product_status_change(), _build_ancestor_chain(), _build_descendant_chain(), _build_facility_path_label(), build_split_product_codes(), create_cell_product() (+49 more)
|
||||
Cohesion: 0.08
|
||||
Nodes (58): batch_delete_research_donations(), change_donation_status(), convert_from_storage(), convert_to_storage(), create_research_donation(), delete_research_donation(), _get_current_user_id(), get_research_donation_detail() (+50 more)
|
||||
|
||||
### Community 13 - "Community 13"
|
||||
Cohesion: 0.08
|
||||
Nodes (58): api_save_application(), auto_generate_schedules(), complete_application(), create_application(), create_basic_experiment_sale_schedules(), create_infusion_plan(), create_schedule(), _create_schedule_products() (+50 more)
|
||||
Cohesion: 0.07
|
||||
Nodes (49): _jwt_user_payload(), Web 端登录用 RSA 公钥(PKCS#1 v1.5,与 JSEncrypt 一致), Web 端登录:账号为 sys_user.user_no,密码为 sys_user.password(bcrypt)。, refresh_token(), web_login(), web_login_rsa_public_key(), lifespan(), create_access_token() (+41 more)
|
||||
|
||||
### Community 14 - "Community 14"
|
||||
Cohesion: 0.09
|
||||
Nodes (49): api_save_application(), auto_generate_schedules(), complete_application(), create_application(), create_basic_experiment_sale_schedules(), create_infusion_plan(), create_schedule(), _create_schedule_products() (+41 more)
|
||||
|
||||
### Community 15 - "Community 15"
|
||||
Cohesion: 0.11
|
||||
Nodes (35): batch_create_sterilize_logs(), batch_create_wash_logs(), batch_discard_garments(), batch_soft_delete_garments(), _count_map(), create_garment(), create_sterilize_log(), create_wash_log() (+27 more)
|
||||
|
||||
### Community 15 - "Community 15"
|
||||
Cohesion: 0.12
|
||||
Nodes (11): get_wechat_pay_client(), get_wechat_pay_v2(), 微信支付工具模块 支持微信支付 V3 API 文档参考: https://pay.weixin.qq.com/docs/v3/apis/index.ht, 统一下单接口 (V3) Args: out_trade_no: 商户订单号 total, 申请退款 Args: out_trade_no: 商户订单号 total_amount, 小程序调起支付的二次签名参数(与公众号 JSAPI 规则一致), 统一下单 (V2 API) Args: out_trade_no: 商户订单号 tot, 生成签名 V3 (SHA256 with RSA) (+3 more)
|
||||
|
||||
### Community 16 - "Community 16"
|
||||
Cohesion: 0.19
|
||||
Nodes (27): _amount_for_row(), _batch_map(), deduct_for_task(), _deduct_task_usage_legacy_batch(), _display_remark(), _fmt_date_val(), _linked_qc_task_no_map(), list_linked_task_usages() (+19 more)
|
||||
Cohesion: 0.12
|
||||
Nodes (10): get_wechat_pay_client(), get_wechat_pay_v2(), 微信支付工具模块 支持微信支付 V3 API 文档参考: https://pay.weixin.qq.com/docs/v3/apis/index.ht, 统一下单接口 (V3) Args: out_trade_no: 商户订单号 total, 小程序调起支付的二次签名参数(与公众号 JSAPI 规则一致), 统一下单 (V2 API) Args: out_trade_no: 商户订单号 tot, 生成签名 V3 (SHA256 with RSA), wechat_pay() (+2 more)
|
||||
|
||||
### Community 17 - "Community 17"
|
||||
Cohesion: 0.15
|
||||
Nodes (17): create_customer(), get_customer(), id_card_taken(), list_customers(), 客户 CRUD(biz_customer), _row_to_dict(), soft_delete_customer(), update_customer() (+9 more)
|
||||
Cohesion: 0.2
|
||||
Nodes (19): _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), get_material_entity(), get_my_usages(), _is_enabled_status() (+11 more)
|
||||
|
||||
### Community 18 - "Community 18"
|
||||
Cohesion: 0.15
|
||||
Nodes (18): delete_hospital(), create_collection_region(), create_hospital(), get_collection_region(), get_hospital(), list_hospitals(), soft_delete_collection_region(), soft_delete_hospital() (+10 more)
|
||||
Cohesion: 0.21
|
||||
Nodes (15): batch_generate_protocol_nos(), batch_issue_protocol_nos(), batch_revoke_protocol_nos(), create_protocol_no(), get_protocol_no(), list_protocol_nos(), _parse_issued_time(), protocol_no_exists() (+7 more)
|
||||
|
||||
### Community 19 - "Community 19"
|
||||
Cohesion: 0.22
|
||||
Nodes (14): batch_generate_sample_codes(), batch_issue_sample_codes(), batch_revoke_sample_codes(), create_sample_code(), get_sample_code(), list_sample_codes(), _parse_issued_time(), 样本编码池 CRUD(biz_sample_code) (+6 more)
|
||||
|
||||
### Community 20 - "Community 20"
|
||||
Cohesion: 0.22
|
||||
Nodes (13): create_collection_region(), create_hospital(), get_collection_region(), get_hospital(), _hospital_names_by_region_ids(), _hospital_to_dict(), list_collection_regions(), list_hospitals() (+5 more)
|
||||
|
||||
### Community 21 - "Community 21"
|
||||
Cohesion: 0.24
|
||||
Nodes (9): 微信消息通知服务 支持微信小程序模板消息推送 使用方式: from app.core.wechat_message import Wech, 发送模板消息 Args: openid: 用户openid templ, send_delivery_notice(), send_delivery_warning(), send_order_status(), send_payment_success(), send_refund_result(), send_urge_notification() (+1 more)
|
||||
|
||||
### Community 21 - "Community 21"
|
||||
### Community 22 - "Community 22"
|
||||
Cohesion: 0.23
|
||||
Nodes (12): Config, ProductBase, ProductCategoryBase, ProductCategoryCreate, ProductCategoryResponse, ProductCreate, ProductResponse, ProductUnitBase (+4 more)
|
||||
|
||||
### Community 22 - "Community 22"
|
||||
Cohesion: 0.24
|
||||
Nodes (12): appointment_no_exists(), create_exhibition_appointment(), _format_visit_date(), _generate_appointment_no(), get_exhibition_appointment(), list_exhibition_appointments(), 展览预约 CRUD(biz_exhibition_appointment), 生成预约编号:YYYYMMDD + 6位序号(如 20260515000001) (+4 more)
|
||||
|
||||
### Community 23 - "Community 23"
|
||||
Cohesion: 0.27
|
||||
Nodes (11): _build_tree(), _cascade_soft_delete(), _collect_with_ancestors(), create_dept(), get_dept(), list_depts(), list_depts_tree(), 保留匹配节点及其全部上级,供关键词检索后仍能正确组树。 (+3 more)
|
||||
Cohesion: 0.31
|
||||
Nodes (11): create_equipment(), _dec(), equipment_code_exists(), equipment_is_referenced(), get_equipment(), list_equipments(), _norm_status(), _parse_date() (+3 more)
|
||||
|
||||
### Community 24 - "Community 24"
|
||||
Cohesion: 0.24
|
||||
Nodes (11): deduct_for_step(), _display_remark(), list_stock_logs(), _parse_receiver_purpose_from_remark(), 试剂变动记录 CRUD(biz_reagent_stock_log), 撤销步骤此前 step_save 扣减,便于重新填报。, 扣减试剂库存并生成变动记录。调用方控制事务,本函数不 commit。, _resolve_receiver_purpose() (+3 more)
|
||||
|
||||
### Community 25 - "Community 25"
|
||||
Cohesion: 0.32
|
||||
Nodes (11): create_env_detect_record(), _generate_record_no(), get_env_detect_record(), _join_csv(), list_env_detect_records(), _resolve_inspector_snapshots(), _resolve_item_snapshot(), _row_to_dict() (+3 more)
|
||||
|
||||
### Community 26 - "Community 26"
|
||||
Cohesion: 0.24
|
||||
Nodes (11): deduct_for_step(), _display_remark(), list_stock_logs(), _parse_receiver_purpose_from_remark(), 耗材变动记录 CRUD(biz_consumable_stock_log), 撤销步骤此前 step_save 扣减,便于重新填报。, 扣减耗材库存并生成变动记录。调用方控制事务,本函数不 commit。, _resolve_receiver_purpose() (+3 more)
|
||||
|
||||
### Community 26 - "Community 26"
|
||||
Cohesion: 0.27
|
||||
Nodes (11): _build_tree(), _cascade_soft_delete(), _collect_with_ancestors(), create_dept(), get_dept(), list_depts(), list_depts_tree(), 保留匹配节点及其全部上级,供关键词检索后仍能正确组树。 (+3 more)
|
||||
|
||||
### Community 27 - "Community 27"
|
||||
Cohesion: 0.29
|
||||
Nodes (9): _build_tree(), _cascade_soft_delete(), create_menu(), get_menu(), list_menus(), list_menus_tree(), _row_to_dict(), soft_delete_menu() (+1 more)
|
||||
|
||||
### Community 28 - "Community 28"
|
||||
Cohesion: 0.31
|
||||
Nodes (8): create_sop_document(), get_sop_document(), list_sop_documents(), SOP文档 CRUD(biz_sop_document), _row_to_dict(), soft_delete_sop_document(), sop_code_exists(), update_sop_document()
|
||||
Cohesion: 0.27
|
||||
Nodes (8): create_customer(), get_customer(), id_card_taken(), list_customers(), 客户 CRUD(biz_customer), _row_to_dict(), soft_delete_customer(), update_customer()
|
||||
|
||||
### Community 29 - "Community 29"
|
||||
Cohesion: 0.31
|
||||
Nodes (8): create_express_company(), express_code_exists(), get_express_company(), list_express_companies(), 快递公司 CRUD(biz_express_company), _row_to_dict(), soft_delete_express_company(), update_express_company()
|
||||
|
||||
### Community 30 - "Community 30"
|
||||
Cohesion: 0.38
|
||||
Nodes (9): create_check_item(), get_check_item(), item_code_exists(), list_active_check_items(), list_check_items(), _order_query(), _row_to_dict(), soft_delete_check_item() (+1 more)
|
||||
|
||||
### Community 30 - "Community 30"
|
||||
Cohesion: 0.22
|
||||
Nodes (8): 菜单 code 权限守卫(V0.3:通过 sys_user_role → sys_role_menu → sys_menu.perms), 运营端角色守卫:admin / super_admin 可访问。, 接口菜单权限守卫(已统一放行 menuCode 校验,仅保留运营端登录)。, 接口菜单权限守卫(已统一放行 menuCode 校验,仅保留运营端登录)。, require_admin_or_super_admin(), require_any_menu_code(), require_menu_code(), strip_row_fields()
|
||||
|
||||
### Community 31 - "Community 31"
|
||||
Cohesion: 0.29
|
||||
Nodes (2): BaseModel, SoftDeleteModel
|
||||
Cohesion: 0.27
|
||||
Nodes (8): create_dict_data(), get_dict_data(), list_dict_data(), list_dict_data_options(), 字典数据 CRUD(sys_dict_data), _row_to_dict(), soft_delete_dict_data(), update_dict_data()
|
||||
|
||||
### Community 32 - "Community 32"
|
||||
Cohesion: 0.38
|
||||
Nodes (6): derive_legacy_status_from_three(), derive_three_status_from_legacy(), 阶段A兼容:从旧 status 推导三字段。 约束:旧 status 本身混合了支付/配送/订单生命周期,因此只能尽力推断; 若业务侧已有更精确, 阶段A兼容:从三字段反推旧 status(用于旧前端/旧筛选参数兼容)。, ThreeStatus, _to_decimal()
|
||||
Nodes (9): create_env_detect_item(), get_env_detect_item(), item_code_exists(), list_active_env_detect_items(), list_env_detect_items(), _order_query(), _row_to_dict(), soft_delete_env_detect_item() (+1 more)
|
||||
|
||||
### Community 33 - "Community 33"
|
||||
Cohesion: 0.31
|
||||
Nodes (8): category_code_exists(), create_process_category(), get_process_category(), list_process_categories(), 工艺工序分类 CRUD(biz_process_category), _row_to_dict(), soft_delete_process_category(), update_process_category()
|
||||
|
||||
### Community 34 - "Community 34"
|
||||
Cohesion: 0.31
|
||||
Nodes (8): create_item_unit(), get_item_unit(), list_item_units(), 物品单位 CRUD(biz_item_unit), _row_to_dict(), soft_delete_item_unit(), unit_code_exists(), update_item_unit()
|
||||
|
||||
### Community 35 - "Community 35"
|
||||
Cohesion: 0.31
|
||||
Nodes (8): create_sop_document(), get_sop_document(), list_sop_documents(), SOP文档 CRUD(biz_sop_document), _row_to_dict(), soft_delete_sop_document(), sop_code_exists(), update_sop_document()
|
||||
|
||||
### Community 36 - "Community 36"
|
||||
Cohesion: 0.31
|
||||
Nodes (8): create_cell_sample_type(), get_cell_sample_type(), list_cell_sample_types(), 细胞样本类型 CRUD(biz_cell_sample_type), _row_to_dict(), soft_delete_cell_sample_type(), type_code_exists(), update_cell_sample_type()
|
||||
|
||||
### Community 37 - "Community 37"
|
||||
Cohesion: 0.31
|
||||
Nodes (8): create_output_type(), get_output_type(), list_output_types(), 工艺产出物类型 CRUD(biz_output_type), _row_to_dict(), soft_delete_output_type(), type_code_exists(), update_output_type()
|
||||
|
||||
### Community 38 - "Community 38"
|
||||
Cohesion: 0.36
|
||||
Nodes (7): create_post(), get_post(), list_posts(), post_code_exists(), _row_to_dict(), soft_delete_post(), update_post()
|
||||
|
||||
### Community 39 - "Community 39"
|
||||
Cohesion: 0.36
|
||||
Nodes (7): create_tenant(), get_tenant(), list_tenants(), _row_to_dict(), soft_delete_tenant(), tenant_no_exists(), update_tenant()
|
||||
|
||||
### Community 40 - "Community 40"
|
||||
Cohesion: 0.36
|
||||
Nodes (7): create_site(), get_site(), list_sites(), _row_to_dict(), site_code_exists(), soft_delete_site(), update_site()
|
||||
|
||||
### Community 41 - "Community 41"
|
||||
Cohesion: 0.29
|
||||
Nodes (2): BaseModel, SoftDeleteModel
|
||||
|
||||
### Community 42 - "Community 42"
|
||||
Cohesion: 0.38
|
||||
Nodes (6): derive_legacy_status_from_three(), derive_three_status_from_legacy(), 阶段A兼容:从旧 status 推导三字段。 约束:旧 status 本身混合了支付/配送/订单生命周期,因此只能尽力推断; 若业务侧已有更精确, 阶段A兼容:从三字段反推旧 status(用于旧前端/旧筛选参数兼容)。, ThreeStatus, _to_decimal()
|
||||
|
||||
### Community 43 - "Community 43"
|
||||
Cohesion: 0.5
|
||||
Nodes (3): BaseSettings, Config, Settings
|
||||
|
||||
### Community 34 - "Community 34"
|
||||
### Community 44 - "Community 44"
|
||||
Cohesion: 0.5
|
||||
Nodes (2): _auto_fill_create_dept_id(), ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID
|
||||
|
||||
### Community 35 - "Community 35"
|
||||
### Community 45 - "Community 45"
|
||||
Cohesion: 0.67
|
||||
Nodes (2): get_menu_list(), 运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,5 个一级菜单分组)
|
||||
|
||||
### Community 46 - "Community 46"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传
|
||||
|
||||
### Community 36 - "Community 36"
|
||||
### Community 47 - "Community 47"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)
|
||||
|
||||
### Community 39 - "Community 39"
|
||||
### Community 50 - "Community 50"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送订单状态通知 Args: openid: 用户openid ord
|
||||
|
||||
### Community 40 - "Community 40"
|
||||
### Community 51 - "Community 51"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送支付成功通知 Args: openid: 用户openid ord
|
||||
|
||||
### Community 41 - "Community 41"
|
||||
### Community 52 - "Community 52"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送配送通知 Args: openid: 配送员openid task
|
||||
|
||||
### Community 42 - "Community 42"
|
||||
### Community 53 - "Community 53"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送配送时效预警 Args: openid: 配送员openid ta
|
||||
|
||||
### Community 43 - "Community 43"
|
||||
### Community 54 - "Community 54"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送退款结果通知 Args: openid: 用户openid ord
|
||||
|
||||
### Community 44 - "Community 44"
|
||||
### Community 55 - "Community 55"
|
||||
Cohesion: 1.0
|
||||
Nodes (1): 发送催单通知给配送员 Args: deliver_openid: 配送员openid
|
||||
|
||||
## Knowledge Gaps
|
||||
- **129 isolated node(s):** `刷新会话 TTL(refreshToken 续期;已登录用户每次 API 校验通过后滑动续期)`, `写入 refreshToken(用于 one-time 使用/吊销)`, `根据 token 获取当前用户(包含 Redis 会话校验;会话滑动续期)`, `登录凭据 RSA 解密(与前端 JSEncrypt PKCS#1 v1.5 兼容)。`, `加载 RSA 密钥对:优先环境变量,否则使用内置固定默认密钥。` (+124 more)
|
||||
These have ≤1 connection - possible missing edges or undocumented components.
|
||||
- **Thin community `Community 31`** (8 nodes): `BaseModel`, `.to_dict()`, `get_active()`, `base.py`, `SoftDeleteModel`, `.restore()`, `.soft_delete()`, `__tablename__()`
|
||||
- **Thin community `Community 41`** (8 nodes): `BaseModel`, `.to_dict()`, `get_active()`, `base.py`, `SoftDeleteModel`, `.restore()`, `.soft_delete()`, `__tablename__()`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 34`** (4 nodes): `_auto_fill_create_dept_id()`, `get_db()`, `database.py`, `ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID`
|
||||
- **Thin community `Community 44`** (4 nodes): `_auto_fill_create_dept_id()`, `get_db()`, `database.py`, `ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 35`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
|
||||
- **Thin community `Community 45`** (3 nodes): `get_menu_list()`, `menu.py`, `运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,5 个一级菜单分组)`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 36`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
|
||||
- **Thin community `Community 46`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 39`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord`
|
||||
- **Thin community `Community 47`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 40`** (1 nodes): `发送支付成功通知 Args: openid: 用户openid ord`
|
||||
- **Thin community `Community 50`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 41`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task`
|
||||
- **Thin community `Community 51`** (1 nodes): `发送支付成功通知 Args: openid: 用户openid ord`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 42`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta`
|
||||
- **Thin community `Community 52`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 43`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord`
|
||||
- **Thin community `Community 53`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 44`** (1 nodes): `发送催单通知给配送员 Args: deliver_openid: 配送员openid`
|
||||
- **Thin community `Community 54`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 55`** (1 nodes): `发送催单通知给配送员 Args: deliver_openid: 配送员openid`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
|
||||
## Suggested Questions
|
||||
_Questions this graph is uniquely positioned to answer:_
|
||||
|
||||
- **Why does `SysUser` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 9`, `Community 10`, `Community 11`, `Community 19`, `Community 24`, `Community 26`?**
|
||||
_High betweenness centrality (0.141) - this node is a cross-community bridge._
|
||||
- **Why does `generate_uuid()` connect `Community 2` to `Community 0`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 14`, `Community 16`, `Community 17`, `Community 18`, `Community 19`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`?**
|
||||
_High betweenness centrality (0.076) - this node is a cross-community bridge._
|
||||
- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 4`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 13`, `Community 18`?**
|
||||
_High betweenness centrality (0.061) - this node is a cross-community bridge._
|
||||
- **Are the 707 inferred relationships involving `str` (e.g. with `unhandled_exception_handler()` and `get_current_user_by_token()`) actually correct?**
|
||||
_`str` has 707 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 652 inferred relationships involving `success_response()` (e.g. with `list_storage_release_reviews()` and `get_storage_release_review_detail()`) actually correct?**
|
||||
_`success_response()` has 652 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 538 inferred relationships involving `error_response()` (e.g. with `_json_error_response()` and `list_storage_release_reviews()`) actually correct?**
|
||||
_`error_response()` has 538 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 460 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤) data_scope 值: 1 = 全部数据 2 = 本部门数据 3` and `从 SysUser 读取用户的 dept_id。`) actually correct?**
|
||||
_`SysUser` has 460 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Why does `SysUser` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 12`, `Community 13`, `Community 18`, `Community 19`, `Community 24`, `Community 25`?**
|
||||
_High betweenness centrality (0.109) - this node is a cross-community bridge._
|
||||
- **Why does `generate_uuid()` connect `Community 3` to `Community 0`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 15`, `Community 17`, `Community 18`, `Community 19`, `Community 20`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 33`, `Community 34`, `Community 35`, `Community 36`, `Community 37`, `Community 38`, `Community 39`, `Community 40`?**
|
||||
_High betweenness centrality (0.098) - this node is a cross-community bridge._
|
||||
- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 6`, `Community 9`, `Community 11`, `Community 12`, `Community 45`, `Community 13`, `Community 14`?**
|
||||
_High betweenness centrality (0.051) - this node is a cross-community bridge._
|
||||
- **Are the 714 inferred relationships involving `str` (e.g. with `unhandled_exception_handler()` and `get_current_user_by_token()`) actually correct?**
|
||||
_`str` has 714 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 657 inferred relationships involving `success_response()` (e.g. with `list_storage_release_reviews()` and `get_storage_release_review_detail()`) actually correct?**
|
||||
_`success_response()` has 657 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 543 inferred relationships involving `error_response()` (e.g. with `_json_error_response()` and `list_storage_release_reviews()`) actually correct?**
|
||||
_`error_response()` has 543 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 464 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤) data_scope 值: 1 = 全部数据 2 = 本部门数据 3` and `从 SysUser 读取用户的 dept_id。`) actually correct?**
|
||||
_`SysUser` has 464 INFERRED edges - model-reasoned connections that need verification._
|
||||
@@ -57,12 +57,12 @@
|
||||
</div>
|
||||
<div id="legend"></div>
|
||||
</div>
|
||||
<div id="stats">4285 nodes · 22669 edges · 49 communities</div>
|
||||
<div id="stats">4340 nodes · 23048 edges · 60 communities</div>
|
||||
</div>
|
||||
<script>
|
||||
const RAW_NODES = [{"id": "init_py", "label": "__init__.py", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 37, "community_name": "Community 37", "source_file": "__init__.py", "file_type": "code", "degree": 0}, {"id": "main_py", "label": "main.py", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "main.py", "community": 8, "community_name": "Community 8", "source_file": "main.py", "file_type": "code", "degree": 7}, {"id": "app_main_lifespan", "label": "lifespan()", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 10, "community_name": "Community 10", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_error_json", "label": "_error_json()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "_error_json()", "community": 8, "community_name": "Community 8", "source_file": "main.py", "file_type": "code", "degree": 3}, {"id": "app_main_sqlalchemy_exception_handler", "label": "sqlalchemy_exception_handler()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "sqlalchemy_exception_handler()", "community": 8, "community_name": "Community 8", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_unhandled_exception_handler", "label": "unhandled_exception_handler()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "unhandled_exception_handler()", "community": 8, "community_name": "Community 8", "source_file": "main.py", "file_type": "code", "degree": 5}, {"id": "app_main_mask_secret", "label": "_mask_secret()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "_mask_secret()", "community": 8, "community_name": "Community 8", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_root", "label": "root()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "root()", "community": 8, "community_name": "Community 8", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_health_check", "label": "health_check()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "health_check()", "community": 8, "community_name": "Community 8", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_rationale_81", "label": "\u6570\u636e\u5e93\u5f02\u5e38\uff1a\u8fd4\u56de JSON \u5e76\u4fdd\u7559 CORS \u5934\uff0c\u907f\u514d\u6d4f\u89c8\u5668\u53ea\u62a5\u8de8\u57df\u9519\u8bef", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "\u6570\u636e\u5e93\u5f02\u5e38\uff1a\u8fd4\u56de JSON \u5e76\u4fdd\u7559 CORS \u5934\uff0c\u907f\u514d\u6d4f\u89c8\u5668\u53ea\u62a5\u8de8\u57df\u9519\u8bef", "community": 8, "community_name": "Community 8", "source_file": "main.py", "file_type": "rationale", "degree": 3}, {"id": "app_main_rationale_92", "label": "\u672a\u6355\u83b7\u5f02\u5e38\uff1a\u7edf\u4e00 JSON 500\uff0c\u786e\u4fdd\u8de8\u57df\u573a\u666f\u4e0b\u4ecd\u6709 Access-Control-Allow-Origin", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "\u672a\u6355\u83b7\u5f02\u5e38\uff1a\u7edf\u4e00 JSON 500\uff0c\u786e\u4fdd\u8de8\u57df\u573a\u666f\u4e0b\u4ecd\u6709 Access-Control-Allow-Origin", "community": 8, "community_name": "Community 8", "source_file": "main.py", "file_type": "rationale", "degree": 3}, {"id": "tasks_init_py", "label": "__init__.py", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 10, "community_name": "Community 10", "source_file": "tasks/__init__.py", "file_type": "code", Line truncated
|
||||
const RAW_EDGES = [{"from": "main_py", "to": "app_main_lifespan", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_error_json", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_sqlalchemy_exception_handler", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_unhandled_exception_handler", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_mask_secret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_root", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_health_check", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_lifespan", "to": "core_login_crypto_ensure_initialized", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_lifespan", "to": "tasks_init_init_scheduled_tasks", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_lifespan", "to": "tasks_init_shutdown_scheduler", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_error_json", "to": "app_main_sqlalchemy_exception_handler", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_error_json", "to": "app_main_unhandled_exception_handler", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_sqlalchemy_exception_handler", "to": "app_main_rationale_81", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_sqlalchemy_exception_handler", "to": "exception", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_unhandled_exception_handler", "to": "app_main_rationale_92", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_unhandled_exception_handler", "to": "exception", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_unhandled_exception_handler", "to": "str", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_81", "to": "core_api_request_log_middleware_apirequestlogmiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_81", "to": "core_api_crypto_middleware_apicryptomiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_92", "to": "core_api_request_log_middleware_apirequestlogmiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_92", "to": "core_api_crypto_middleware_apicryptomiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "tasks_init_py", "to": "tasks_init_init_scheduled_tasks", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "tasks_init_py", "to": "tasks_init_shutdown_scheduler", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_redis_session_enabled", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_redis_client", "labeLine truncated
|
||||
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 899}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 648}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 488}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 372}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 344}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 233}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 202}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 179}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 177}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 151}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 86}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 64}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 61}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 60}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 38}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 31}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 28}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 21}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 21}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 16}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 13}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 13}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 13}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 12}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 12}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 12}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 12}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 11}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 10}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 10}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 9}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 8}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 7}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 4}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 4}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 2}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 2}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 1}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 1}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 1}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 1}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 1}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 1}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 1}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 1}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 1}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 1}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 1}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 1}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 0}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 0}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 0}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 0}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 0}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 0}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 0}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 0}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 0}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 0}];
|
||||
const RAW_NODES = [{"id": "init_py", "label": "__init__.py", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 48, "community_name": "Community 48", "source_file": "__init__.py", "file_type": "code", "degree": 0}, {"id": "main_py", "label": "main.py", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "main.py", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 7}, {"id": "app_main_lifespan", "label": "lifespan()", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 13, "community_name": "Community 13", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_error_json", "label": "_error_json()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "_error_json()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 3}, {"id": "app_main_sqlalchemy_exception_handler", "label": "sqlalchemy_exception_handler()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "sqlalchemy_exception_handler()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_unhandled_exception_handler", "label": "unhandled_exception_handler()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "unhandled_exception_handler()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 5}, {"id": "app_main_mask_secret", "label": "_mask_secret()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "_mask_secret()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_root", "label": "root()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "root()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_health_check", "label": "health_check()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "health_check()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_rationale_81", "label": "\u6570\u636e\u5e93\u5f02\u5e38\uff1a\u8fd4\u56de JSON \u5e76\u4fdd\u7559 CORS \u5934\uff0c\u907f\u514d\u6d4f\u89c8\u5668\u53ea\u62a5\u8de8\u57df\u9519\u8bef", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "\u6570\u636e\u5e93\u5f02\u5e38\uff1a\u8fd4\u56de JSON \u5e76\u4fdd\u7559 CORS \u5934\uff0c\u907f\u514d\u6d4f\u89c8\u5668\u53ea\u62a5\u8de8\u57df\u9519\u8bef", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "rationale", "degree": 3}, {"id": "app_main_rationale_92", "label": "\u672a\u6355\u83b7\u5f02\u5e38\uff1a\u7edf\u4e00 JSON 500\uff0c\u786e\u4fdd\u8de8\u57df\u573a\u666f\u4e0b\u4ecd\u6709 Access-Control-Allow-Origin", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "\u672a\u6355\u83b7\u5f02\u5e38\uff1a\u7edf\u4e00 JSON 500\uff0c\u786e\u4fdd\u8de8\u57df\u573a\u666f\u4e0b\u4ecd\u6709 Access-Control-Allow-Origin", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "rationale", "degree": 3}, {"id": "tasks_init_py", "label": "__init__.py", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 13, "community_name": "Community 13", "source_file": "tasks/__init__.py", "file_type": "code", Line truncated
|
||||
const RAW_EDGES = [{"from": "main_py", "to": "app_main_lifespan", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_error_json", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_sqlalchemy_exception_handler", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_unhandled_exception_handler", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_mask_secret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_root", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_py", "to": "app_main_health_check", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_lifespan", "to": "core_login_crypto_ensure_initialized", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_lifespan", "to": "tasks_init_init_scheduled_tasks", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_lifespan", "to": "tasks_init_shutdown_scheduler", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_error_json", "to": "app_main_sqlalchemy_exception_handler", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_error_json", "to": "app_main_unhandled_exception_handler", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_sqlalchemy_exception_handler", "to": "app_main_rationale_81", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_sqlalchemy_exception_handler", "to": "exception", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_unhandled_exception_handler", "to": "app_main_rationale_92", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_main_unhandled_exception_handler", "to": "exception", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_unhandled_exception_handler", "to": "str", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_81", "to": "core_api_request_log_middleware_apirequestlogmiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_81", "to": "core_api_crypto_middleware_apicryptomiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_92", "to": "core_api_request_log_middleware_apirequestlogmiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "app_main_rationale_92", "to": "core_api_crypto_middleware_apicryptomiddleware", "label": "uses", "title": "uses [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "tasks_init_py", "to": "tasks_init_init_scheduled_tasks", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "tasks_init_py", "to": "tasks_init_shutdown_scheduler", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_redis_session_enabled", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_redis_client", "labeLine truncated
|
||||
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 855}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 644}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 349}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 340}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 286}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 255}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 244}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 241}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 179}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 174}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 141}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 71}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 62}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 58}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 50}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 38}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 29}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 20}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 17}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 16}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 15}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 13}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 13}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 13}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 12}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 12}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 12}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 11}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 11}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 10}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 10}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 10}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 10}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 10}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 10}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 10}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 10}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 10}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 9}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 9}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 9}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 8}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 7}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 4}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 4}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 3}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 2}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 2}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 1}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 1}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 1}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 1}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 1}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 1}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 1}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 1}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 1}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 1}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 1}];
|
||||
|
||||
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
|
||||
function esc(s) {
|
||||
|
||||
+20275
-15232
File diff suppressed because it is too large.
Load diff
@@ -26,9 +26,9 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/core/api_crypto_middleware.py": 1778581508.2309763,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/core/wechat_message.py": 1778578258.0458734,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/material.py": 1781427174.243315,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py": 1781427178.0074935,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py": 1779022399.0175831,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py": 1782351467.7127345,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/production_material.py": 1782404882.9262497,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/qc_param.py": 1782379593.174925,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/models.py": 1782381881.8049347,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/cleanroom_garment.py": 1781347080.6165943,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/__init__.py": 1781344070.5899634,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/models/research_donation.py": 1780458012.8329656,
|
||||
@@ -74,16 +74,16 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/leave.py": 1778666088.7680702,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/storage_release_review.py": 1781536745.221194,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/equipment.py": 1781524075.5310335,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py": 1782350322.6331227,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py": 1782381972.0363982,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/process_route.py": 1782289879.5489628,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py": 1780479191.5382729,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py": 1779331731.6720955,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py": 1782379630.9640372,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_review.py": 1781603141.940902,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material_stock_check.py": 1781423988.9720724,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/material_stock_batch.py": 1781521998.393167,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/post.py": 1779265648.38155,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_check_result.py": 1779255909.8554008,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py": 1781513705.4688208,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_stock_batch.py": 1782404955.550011,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/user.py": 1780539127.1805215,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_work_order.py": 1781696877.7453213,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/material.py": 1781522283.6438622,
|
||||
@@ -97,7 +97,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/material_usage.py": 1781427187.4456425,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_usage.py": 1781513732.7796721,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sop_document.py": 1779265721.9928973,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py": 1782360197.8427687,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_task.py": 1782404282.3374326,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_third_party_item.py": 1779265661.482352,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/reagent.py": 1779512669.9847593,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/collection_protocol.py": 1782195334.7812605,
|
||||
@@ -138,23 +138,24 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_item.py": 1781145689.9525824,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/process_category.py": 1779265700.0606413,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/item_unit.py": 1779265653.7504313,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py": 1782350337.3184292,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_work_order.py": 1782399959.6748888,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_handover_inventory.py": 1781598316.476379,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py": 1781145773.959546,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/env_detect_record.py": 1782376492.2365673,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_release_material.py": 1781612877.0137436,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/process.py": 1782289878.7772164,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_service.py": 1781599314.0124536,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/customer.py": 1779686149.7508218,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/workflow.py": 1779265993.677624,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_sms_notification.py": 1781063495.0317714,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py": 1781532303.452117,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception.py": 1782377432.963105,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_pack.py": 1779265715.416005,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_inspection_batch.py": 1782384683.8310702,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/production_material_prep.py": 1781514953.3551314,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_material.py": 1779284415.64655,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/collection_protocol_no.py": 1779882001.753651,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/outbound_handover.py": 1780455574.0993364,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/storage_facility.py": 1782290554.4607918,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py": 1780462849.099601,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_reception_lab_code.py": 1782377429.191194,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/cell_sample_type.py": 1781747645.1762104,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/pilot_outbound_status_sync.py": 1781595840.6955194,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/consumable_stock_log.py": 1779515477.284446,
|
||||
@@ -162,7 +163,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/base.py": 1778578258.062207,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/protocol_donation_convert.py": 1779161468.6582925,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/protocol_sample_collection.py": 1781063441.1529672,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py": 1779265680.3885922,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_item_param.py": 1782380067.962216,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/leave.py": 1779265839.500242,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/output_type.py": 1779265703.7363207,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/exhibition_appointment.py": 1778801075.5211918,
|
||||
@@ -171,8 +172,8 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/outbound_release_review.py": 1779968232.5759368,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/public.py": 1782122639.96012,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/material.py": 1781522000.6097813,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py": 1781513734.218474,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py": 1782120920.0829217,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production_material.py": 1782404982.2474263,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py": 1782405787.3654518,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/market.py": 1781522283.6823432,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/collection_protocol.py": 1782195334.2335806,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/cleanroom_garment.py": 1781347256.2326367,
|
||||
@@ -189,7 +190,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/menu.py": 1781749943.5843754,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/pilot_delivery.py": 1779655584.820777,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/admin.py": 1782268401.1532724,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py": 1781145712.2433698,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/env_detect.py": 1782376501.8919773,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/research_donation.py": 1782195482.219445,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/ethnic.py": 1779266243.9511197,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/pilot_checkup.py": 1779935751.2658868,
|
||||
@@ -198,7 +199,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/sample_sms_notification.py": 1780325524.907156,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/sample_reception.py": 1781535825.750677,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py": 1781410837.9443986,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py": 1782362266.599568,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py": 1782403704.9644573,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/protocol_sample_collection.py": 1780457788.2093296,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/leave.py": 1779266168.8693042,
|
||||
"/Users/wuzilong/work/00code/zkxw/backend/app/api/clinical_payment.py": 1781750841.074568,
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- 环境检测登记:新增结果时间
|
||||
ALTER TABLE `biz_env_detect_record`
|
||||
ADD COLUMN `result_time` datetime DEFAULT NULL COMMENT '结果时间' AFTER `detect_time`;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- 生产物料入库批次:增加生产日期
|
||||
ALTER TABLE `biz_production_material_stock_batch`
|
||||
ADD COLUMN `production_date` date DEFAULT NULL COMMENT '生产日期' AFTER `expire_date`;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- 检测项目参数模板:单选类型支持选项列表与默认值
|
||||
ALTER TABLE `biz_qc_item_param`
|
||||
ADD COLUMN `options` varchar(2000) DEFAULT NULL COMMENT '单选选项列表,JSON数组格式' AFTER `param_type`,
|
||||
ADD COLUMN `default_value` varchar(500) DEFAULT NULL COMMENT '单选默认值' AFTER `options`;
|
||||
@@ -0,0 +1,46 @@
|
||||
-- 质检管理 · 质检物料库:新增「查看单价金额」按钮权限(F 类型,仅角色权限树勾选)
|
||||
INSERT INTO `sys_menu` (
|
||||
`id`,
|
||||
`menu_name`,
|
||||
`parent_id`,
|
||||
`menu_type`,
|
||||
`path`,
|
||||
`component`,
|
||||
`perms`,
|
||||
`is_frame`,
|
||||
`visible`,
|
||||
`status`,
|
||||
`tenant_no`,
|
||||
`order_num`,
|
||||
`remark`,
|
||||
`create_by`,
|
||||
`create_dept_id`,
|
||||
`create_time`,
|
||||
`update_by`,
|
||||
`update_time`,
|
||||
`del_flag`
|
||||
)
|
||||
SELECT
|
||||
'70000000000000000000000000000090',
|
||||
'查看单价金额',
|
||||
'70000000000000000000000000000009',
|
||||
'F',
|
||||
'',
|
||||
'',
|
||||
'biz:qcMaterial:viewAmount',
|
||||
1,
|
||||
'0',
|
||||
'1',
|
||||
'zkxw',
|
||||
1,
|
||||
'控制质检物料库各 Tab 列表、查看弹窗与导出中的单价、金额字段展示',
|
||||
NULL,
|
||||
'',
|
||||
NOW(),
|
||||
NULL,
|
||||
NOW(),
|
||||
0
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM `sys_menu` WHERE `id` = '70000000000000000000000000000090'
|
||||
);
|
||||
@@ -0,0 +1,83 @@
|
||||
-- 历史质检工单:为每工单创建默认检测批次 B01,并回填 batch_id
|
||||
|
||||
-- 注意:按租户/环境执行前请备份;若已存在批次可跳过对应工单
|
||||
|
||||
INSERT INTO `biz_qc_work_order_inspection_batch` (
|
||||
`id`, `work_order_id`, `order_source`, `batch_no`, `batch_name`,
|
||||
`tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`,
|
||||
`create_time`, `update_by`, `update_time`, `del_flag`
|
||||
)
|
||||
SELECT
|
||||
UUID() AS id,
|
||||
wo.id AS work_order_id,
|
||||
CASE wo.work_order_type
|
||||
WHEN 'temporary' THEN 'temporary'
|
||||
WHEN 'outbound' THEN 'outbound'
|
||||
ELSE 'inbound'
|
||||
END AS order_source,
|
||||
CONCAT(wo.work_order_no, '-B01') AS batch_no,
|
||||
CONCAT(DATE_FORMAT(COALESCE(wo.create_time, NOW()), '%Y%m%d'), '检测') AS batch_name,
|
||||
wo.tenant_no,
|
||||
1 AS order_num,
|
||||
'历史数据迁移默认批次' AS remark,
|
||||
wo.create_by,
|
||||
COALESCE(wo.create_dept_id, '') AS create_dept_id,
|
||||
NOW() AS create_time,
|
||||
wo.update_by,
|
||||
NOW() AS update_time,
|
||||
0 AS del_flag
|
||||
FROM `biz_qc_work_order` wo
|
||||
WHERE wo.del_flag = 0
|
||||
AND wo.work_order_status IN ('ypz', 'ywc')
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM `biz_qc_work_order_inspection_batch` b
|
||||
WHERE b.work_order_id = wo.id AND b.del_flag = 0
|
||||
);
|
||||
|
||||
-- 回填实验室明细 batch_id
|
||||
UPDATE `biz_qc_work_order_lab_item` li
|
||||
INNER JOIN `biz_qc_work_order_inspection_batch` b
|
||||
ON b.work_order_id = li.work_order_id AND b.del_flag = 0 AND b.batch_no LIKE '%-B01'
|
||||
SET li.batch_id = b.id
|
||||
WHERE li.del_flag = 0 AND (li.batch_id IS NULL OR li.batch_id = '');
|
||||
|
||||
-- 回填第三方明细 batch_id
|
||||
UPDATE `biz_qc_work_order_third_item` ti
|
||||
INNER JOIN `biz_qc_work_order_inspection_batch` b
|
||||
ON b.work_order_id = ti.work_order_id AND b.del_flag = 0 AND b.batch_no LIKE '%-B01'
|
||||
SET ti.batch_id = b.id
|
||||
WHERE ti.del_flag = 0 AND (ti.batch_id IS NULL OR ti.batch_id = '');
|
||||
|
||||
-- 回填任务 batch_id
|
||||
UPDATE `biz_qc_task` t
|
||||
INNER JOIN `biz_qc_work_order_inspection_batch` b
|
||||
ON b.work_order_id = t.work_order_id AND b.del_flag = 0 AND b.batch_no LIKE '%-B01'
|
||||
SET t.batch_id = b.id
|
||||
WHERE t.del_flag = 0 AND (t.batch_id IS NULL OR t.batch_id = '');
|
||||
|
||||
-- 从任务负责人迁移批次负责人(去重)
|
||||
INSERT INTO `biz_qc_batch_assignee` (
|
||||
`id`, `batch_id`, `user_id`, `tenant_no`, `order_num`,
|
||||
`create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`
|
||||
)
|
||||
SELECT
|
||||
UUID(),
|
||||
b.id,
|
||||
ta.user_id,
|
||||
b.tenant_no,
|
||||
0,
|
||||
b.create_by,
|
||||
b.create_dept_id,
|
||||
NOW(),
|
||||
b.update_by,
|
||||
NOW(),
|
||||
0
|
||||
FROM `biz_qc_work_order_inspection_batch` b
|
||||
INNER JOIN `biz_qc_task` t ON t.batch_id = b.id AND t.del_flag = 0
|
||||
INNER JOIN `biz_qc_task_assignee` ta ON ta.task_id = t.id AND ta.del_flag = 0
|
||||
WHERE b.del_flag = 0
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM `biz_qc_batch_assignee` ba
|
||||
WHERE ba.batch_id = b.id AND ba.user_id = ta.user_id AND ba.del_flag = 0
|
||||
)
|
||||
GROUP BY b.id, ta.user_id, b.tenant_no, b.create_by, b.create_dept_id, b.update_by;
|
||||
@@ -0,0 +1,54 @@
|
||||
-- 质检检测批次:新表 + 明细 batch_id + 历史数据迁移
|
||||
|
||||
-- 1. 检测批次主表
|
||||
CREATE TABLE IF NOT EXISTS `biz_qc_work_order_inspection_batch` (
|
||||
`id` varchar(64) NOT NULL COMMENT '主键ID',
|
||||
`work_order_id` varchar(64) NOT NULL COMMENT '工单ID',
|
||||
`order_source` varchar(20) NOT NULL DEFAULT 'inbound' COMMENT '工单来源',
|
||||
`batch_no` varchar(32) NOT NULL COMMENT '批次编号',
|
||||
`batch_name` varchar(200) NOT NULL COMMENT '批次展示名',
|
||||
`tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
|
||||
`order_num` int(11) DEFAULT NULL COMMENT '排序号',
|
||||
`remark` varchar(512) DEFAULT NULL COMMENT '备注',
|
||||
`create_by` varchar(64) DEFAULT NULL COMMENT '创建人id',
|
||||
`create_dept_id` varchar(64) NOT NULL DEFAULT '' COMMENT '创建人部门ID',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(64) DEFAULT NULL COMMENT '更新人id',
|
||||
`update_time` datetime NOT NULL COMMENT '更新时间',
|
||||
`del_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标记',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_qc_wo_batch_wo` (`work_order_id`,`del_flag`),
|
||||
KEY `idx_qc_wo_batch_no` (`tenant_no`,`batch_no`,`del_flag`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='质检工单检测批次';
|
||||
|
||||
-- 2. 批次负责人
|
||||
CREATE TABLE IF NOT EXISTS `biz_qc_batch_assignee` (
|
||||
`id` varchar(64) NOT NULL COMMENT '主键',
|
||||
`batch_id` varchar(64) NOT NULL COMMENT '检测批次ID',
|
||||
`user_id` varchar(64) NOT NULL COMMENT '负责人用户ID',
|
||||
`tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
|
||||
`order_num` int(11) DEFAULT '0' COMMENT '展示顺序',
|
||||
`remark` varchar(512) DEFAULT NULL COMMENT '备注',
|
||||
`create_by` varchar(64) DEFAULT NULL COMMENT '创建人id',
|
||||
`create_dept_id` varchar(64) DEFAULT NULL COMMENT '创建人部门ID',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(64) DEFAULT NULL COMMENT '更新人id',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`del_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标记',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_qc_batch_assignee_batch` (`batch_id`,`del_flag`),
|
||||
KEY `idx_qc_batch_assignee_user` (`user_id`,`tenant_no`,`del_flag`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='质检检测批次负责人';
|
||||
|
||||
-- 3. 明细表增加 batch_id
|
||||
ALTER TABLE `biz_qc_work_order_lab_item`
|
||||
ADD COLUMN `batch_id` varchar(64) DEFAULT NULL COMMENT '检测批次ID' AFTER `order_source`;
|
||||
|
||||
ALTER TABLE `biz_qc_work_order_third_item`
|
||||
ADD COLUMN `batch_id` varchar(64) DEFAULT NULL COMMENT '检测批次ID' AFTER `order_source`;
|
||||
|
||||
ALTER TABLE `biz_qc_task`
|
||||
ADD COLUMN `batch_id` varchar(64) DEFAULT NULL COMMENT '检测批次ID' AFTER `work_order_id`;
|
||||
|
||||
-- 4. 历史数据迁移:每工单默认批次 B01(需在应用层或下列 SQL 按环境执行)
|
||||
-- 见 migrate_qc_inspection_batch_data.sql
|
||||
@@ -1413,6 +1413,7 @@ CREATE TABLE `biz_env_detect_record` (
|
||||
`id` varchar(64) NOT NULL COMMENT '主键ID',
|
||||
`record_no` varchar(32) NOT NULL COMMENT '登记编号',
|
||||
`detect_time` datetime NOT NULL COMMENT '检测时间',
|
||||
`result_time` datetime DEFAULT NULL COMMENT '结果时间',
|
||||
`inspector_ids` varchar(500) NOT NULL COMMENT '检测人用户ID,逗号分隔',
|
||||
`inspector_names` varchar(500) NOT NULL COMMENT '检测人姓名快照,逗号分隔',
|
||||
`env_detect_item_id` varchar(64) NOT NULL COMMENT '检测项目ID',
|
||||
@@ -3177,6 +3178,7 @@ CREATE TABLE `biz_production_material_stock_batch` (
|
||||
`stock_in_no` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '入库编号(租户内唯一)',
|
||||
`stock_in_date` date NOT NULL COMMENT '入库日期',
|
||||
`expire_date` date NOT NULL COMMENT '过期日期',
|
||||
`production_date` date DEFAULT NULL COMMENT '生产日期',
|
||||
`catalog_no` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '货号',
|
||||
`batch_no` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '批号',
|
||||
`manufacturer` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '厂家',
|
||||
@@ -4168,6 +4170,8 @@ CREATE TABLE `biz_qc_item_param` (
|
||||
`param_code` varchar(64) NOT NULL COMMENT '参数编码',
|
||||
`param_unit` varchar(32) DEFAULT NULL COMMENT '单位',
|
||||
`param_type` varchar(16) NOT NULL DEFAULT 'text' COMMENT 'number/text/select',
|
||||
`options` varchar(2000) DEFAULT NULL COMMENT '单选选项列表,JSON数组格式',
|
||||
`default_value` varchar(500) DEFAULT NULL COMMENT '单选默认值',
|
||||
`required_flag` char(1) NOT NULL DEFAULT '0' COMMENT '1必填 0非必填',
|
||||
`tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
|
||||
`order_num` int(11) DEFAULT NULL COMMENT '排序号',
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# 质检工单「所有」Tab 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:** Add an「所有」tab before category tabs on QC work order and My QC Task pages, with shared filters, per-row type tags, and cross-type list support.
|
||||
|
||||
**Architecture:** Extend `QcWorkOrderTabKey` with `all`; backend `list_work_orders` supports cross-type keyword and excludes hidden clinical type; frontend uses standalone flat cards with `resolveCardMetaForRow()` and dynamic view dialogs.
|
||||
|
||||
**Tech Stack:** Python/FastAPI backend, Vue 3 + Element Plus frontend
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-06-25-qc-work-order-all-tab-design.md`
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Tab utils + category helpers
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/utils/qc-work-order-tabs.ts`
|
||||
- Create: `web-admin/src/utils/qc-work-order-category.ts`
|
||||
|
||||
- [ ] Add `all` tab config, default tab, category options, `toAllTabListQuery()`
|
||||
- [ ] Add `qcWorkOrderCategoryLabel/TagType`, trigger filter value helpers
|
||||
|
||||
### Task 2: Card meta for all tab
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/utils/qc-work-order-card-meta.ts`
|
||||
|
||||
- [ ] Add `all` config, `resolveCardMetaForRow()`, meta field subsets per type
|
||||
|
||||
### Task 3: Backend list API
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/crud/qc_work_order.py`
|
||||
|
||||
- [ ] Cross-type keyword (outbound join when `work_order_type` empty)
|
||||
- [ ] Exclude `clinical_application` when listing all types
|
||||
- [ ] All-tab trigger source values (`temp_production`, `temp_manual`, `production` non-temp)
|
||||
|
||||
### Task 4: Page composable + mine filters
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts`
|
||||
- Modify: `web-admin/src/utils/qc-mine-task-groups.ts`
|
||||
|
||||
- [ ] `qcCategory` in searchForm, list query mapping, mine task fetch without type limit
|
||||
|
||||
### Task 5: Tab panel filters + view dialog
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/views/quality-inspection/qc-work-order/tabs/QcWorkOrderTabPanel.vue`
|
||||
- Create: `web-admin/src/views/quality-inspection/qc-work-order/tabs/AllTab.vue`
|
||||
- Modify: `web-admin/src/views/quality-inspection/qc-work-order/tabs/tab-registry.ts`
|
||||
|
||||
### Task 6: Card components
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSingleCard.vue`
|
||||
- Modify: `web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderCardList.vue`
|
||||
|
||||
- [ ] Type tag, per-row meta, work order no title on all tab
|
||||
|
||||
### Task 7: Verify
|
||||
|
||||
- [ ] Update spec status to 已确认
|
||||
- [ ] `./scripts/update-graph.sh frontend` (and backend if needed)
|
||||
@@ -0,0 +1,777 @@
|
||||
# 入库质检工单 · 协议单多样本 Tab 分组 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:** 在细胞存储质检、科研捐赠质检两个 Tab 中,将同一协议单下多个样本质检工单合并为一张协议组卡片,组内用 Tab 切换样本,样本内保留触发来源 Tab。
|
||||
|
||||
**Architecture:** 前端新增 `groupInboundQcWorkOrdersByProtocol()` 与 `QcWorkOrderProtocolGroup.vue` 作为协议外层;复用 `QcWorkOrderSampleGroup` 作为样本内层(`hideContextBar`);`QcWorkOrderCardList` 在 `inbound-grouped` 布局时渲染协议组。后端 `list_work_orders` 关键词增加 `protocol_no` 匹配。两页(manage/mine)共用 CardList,mine 关键词补 `protocolNo`。
|
||||
|
||||
**Tech Stack:** Python 3.9 / FastAPI / SQLAlchemy(backend);Vue 3 / TypeScript / Element Plus(web-admin)
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-06-25-qc-work-order-protocol-group-design.md`
|
||||
|
||||
---
|
||||
|
||||
## File Map
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `web-admin/src/utils/qc-work-order-groups.ts` | 协议分组模型、`groupInboundQcWorkOrdersByProtocol`、gate 工单/进度统计 helper |
|
||||
| `web-admin/src/utils/qc-work-order-card-meta.ts` | 协议组头副标题、协议状态 Tag、组级 `paymentSummary` 选取 |
|
||||
| `web-admin/src/utils/qc-work-order-tabs.ts` | 入库 Tab 关键词 placeholder 含协议号/捐赠单号 |
|
||||
| `web-admin/src/utils/qc-mine-task-groups.ts` | mine 前端关键词增加 `protocolNo` |
|
||||
| `web-admin/src/views/.../QcWorkOrderProtocolGroup.vue` | **新建** 协议组卡片(组头 + 样本 Tab + 内嵌 SampleGroup) |
|
||||
| `web-admin/src/views/.../QcWorkOrderSampleGroup.vue` | `hideContextBar`、`hideProtocolFeeSummary` prop |
|
||||
| `web-admin/src/views/.../QcWorkOrderSingleCard.vue` | 尊重 `hideProtocolFeeSummary` |
|
||||
| `web-admin/src/views/.../QcWorkOrderCardList.vue` | inbound 布局改用 `QcWorkOrderProtocolGroup` |
|
||||
| `backend/app/crud/qc_work_order.py` | 列表关键词 OR 增加 `protocol_no.like` |
|
||||
|
||||
**不修改:** `buildAllTabListItems`(「所有」Tab)、出库/临时 Tab、`buildMineCardListModel`(mine 走 flat rows + CardList 分组)。
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 协议分组工具函数
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/utils/qc-work-order-groups.ts`
|
||||
|
||||
- [ ] **Step 1: 在文件末尾、`buildAllTabListItems` 之前追加类型与 helper**
|
||||
|
||||
在 `isGateTriggerSource` 之后、`buildAllTabListItems` 之前插入:
|
||||
|
||||
```typescript
|
||||
export function resolveInboundProtocolGroupKey(row: QcWorkOrder): string {
|
||||
const id = (row.collectionProtocolId || '').trim()
|
||||
if (id) return id
|
||||
const no = (row.protocolNo || '').trim()
|
||||
if (no) return `protocol-no:${no}`
|
||||
return row.id
|
||||
}
|
||||
|
||||
export function resolveInboundSampleGroupKey(row: QcWorkOrder): string {
|
||||
return (row.sampleCode || '').trim() || row.id
|
||||
}
|
||||
|
||||
/** 样本组内用于组头/Tab 状态的 gate 工单(接收优先,否则首条) */
|
||||
export function resolveGateWorkOrderForSampleGroup(
|
||||
workOrders: QcWorkOrder[]
|
||||
): QcWorkOrder | undefined {
|
||||
if (!workOrders.length) return undefined
|
||||
return (
|
||||
workOrders.find((w) => isGateTriggerSource(w.triggerSource)) ||
|
||||
workOrders[0]
|
||||
)
|
||||
}
|
||||
|
||||
export type QcWorkOrderProtocolGroupModel = {
|
||||
groupKey: string
|
||||
protocolId: string
|
||||
protocolNo: string
|
||||
receptionSource: 'cell_storage' | 'research_donation'
|
||||
sampleGroups: QcWorkOrderSampleGroupModel[]
|
||||
workOrders: QcWorkOrder[]
|
||||
}
|
||||
|
||||
function protocolGroupSortTime(group: QcWorkOrderProtocolGroupModel): string {
|
||||
let max = ''
|
||||
for (const wo of group.workOrders) {
|
||||
const t = String(wo.createTime || '')
|
||||
if (t > max) max = t
|
||||
}
|
||||
return max
|
||||
}
|
||||
|
||||
/** 入库 Tab:按协议单分组,组内再按样本分组 */
|
||||
export function groupInboundQcWorkOrdersByProtocol(
|
||||
rows: QcWorkOrder[]
|
||||
): QcWorkOrderProtocolGroupModel[] {
|
||||
const map = new Map<string, QcWorkOrder[]>()
|
||||
for (const row of rows) {
|
||||
const key = resolveInboundProtocolGroupKey(row)
|
||||
const list = map.get(key)
|
||||
if (list) list.push(row)
|
||||
else map.set(key, [row])
|
||||
}
|
||||
const groups = Array.from(map.entries()).map(([groupKey, workOrders]) => {
|
||||
const sampleGroups = groupInboundQcWorkOrders(workOrders)
|
||||
const head = workOrders[0]
|
||||
const source =
|
||||
(head?.receptionSource || 'cell_storage') === 'research_donation'
|
||||
? 'research_donation'
|
||||
: 'cell_storage'
|
||||
return {
|
||||
groupKey,
|
||||
protocolId: (head?.collectionProtocolId || '').trim(),
|
||||
protocolNo: (head?.protocolNo || '').trim(),
|
||||
receptionSource: source as 'cell_storage' | 'research_donation',
|
||||
sampleGroups,
|
||||
workOrders
|
||||
}
|
||||
})
|
||||
return groups.sort(
|
||||
(a, b) => protocolGroupSortTime(b).localeCompare(protocolGroupSortTime(a))
|
||||
)
|
||||
}
|
||||
|
||||
/** 协议组进度:已配置样本数 / 样本总数(按 gate 工单 workOrderStatus !== dpz) */
|
||||
export function countConfiguredSamplesInProtocolGroup(
|
||||
group: QcWorkOrderProtocolGroupModel
|
||||
): { configured: number; total: number } {
|
||||
const total = group.sampleGroups.length
|
||||
let configured = 0
|
||||
for (const sg of group.sampleGroups) {
|
||||
const gate = resolveGateWorkOrderForSampleGroup(sg.workOrders)
|
||||
if (gate && gate.workOrderStatus !== 'dpz') configured += 1
|
||||
}
|
||||
return { configured, total }
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 本地 smoke(Node REPL 或临时 script,可选)**
|
||||
|
||||
在 `web-admin` 目录用两条 mock 工单(同 `collectionProtocolId`、不同 `sampleCode`)调用 `groupInboundQcWorkOrdersByProtocol`,期望返回 1 个 group、`sampleGroups.length === 2`。
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/utils/qc-work-order-groups.ts
|
||||
git commit -m "feat(web-admin): add inbound QC work order protocol grouping utils"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: 协议组头 card-meta helper
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/utils/qc-work-order-card-meta.ts`
|
||||
|
||||
- [ ] **Step 1: 增加 import 与 helper**
|
||||
|
||||
文件顶部 import 区增加:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
countConfiguredSamplesInProtocolGroup,
|
||||
type QcWorkOrderProtocolGroupModel
|
||||
} from '@/utils/qc-work-order-groups'
|
||||
import type { QcProtocolPaymentSummary } from '@/api/qc-work-order'
|
||||
```
|
||||
|
||||
在 `buildDonationGroupContext` 之后追加:
|
||||
|
||||
```typescript
|
||||
export function buildProtocolGroupProgressLabel(
|
||||
group: QcWorkOrderProtocolGroupModel
|
||||
): string {
|
||||
const { configured, total } = countConfiguredSamplesInProtocolGroup(group)
|
||||
if (total <= 0) return ''
|
||||
if (configured <= 0) return ''
|
||||
return `${configured}/${total} 已配置`
|
||||
}
|
||||
|
||||
export function resolveProtocolGroupStatus(row: QcWorkOrder): {
|
||||
label: string
|
||||
tagType: TagType
|
||||
} {
|
||||
const status = String(row.protocolStatus || '')
|
||||
const source = row.receptionSource || 'cell_storage'
|
||||
return {
|
||||
label: protocolStatusLabelBySource(status, source),
|
||||
tagType: protocolStatusTagTypeBySource(status, source)
|
||||
}
|
||||
}
|
||||
|
||||
/** 协议组级费用摘要:取组内首条有 paymentSummary 的 cell_storage 工单 */
|
||||
export function resolveProtocolGroupPaymentSummary(
|
||||
group: QcWorkOrderProtocolGroupModel
|
||||
): QcProtocolPaymentSummary | null {
|
||||
if (group.receptionSource !== 'cell_storage') return null
|
||||
for (const wo of group.workOrders) {
|
||||
if (wo.paymentSummary) return wo.paymentSummary
|
||||
}
|
||||
return null
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/utils/qc-work-order-card-meta.ts
|
||||
git commit -m "feat(web-admin): add protocol group card meta helpers for inbound QC"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: SampleGroup / SingleCard 支持隐藏组头与卡片级协议费用
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSampleGroup.vue`
|
||||
- Modify: `web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSingleCard.vue`
|
||||
|
||||
- [ ] **Step 1: `QcWorkOrderSampleGroup.vue` — props + 条件渲染**
|
||||
|
||||
`defineProps` 增加:
|
||||
|
||||
```typescript
|
||||
hideContextBar?: boolean
|
||||
hideProtocolFeeSummary?: boolean
|
||||
```
|
||||
|
||||
模板中 `qc-sample-row__ctx` 外层加 `v-if="!hideContextBar"`。
|
||||
|
||||
`QcWorkOrderSingleCard` 传参增加:
|
||||
|
||||
```vue
|
||||
:hide-protocol-fee-summary="hideProtocolFeeSummary"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: `QcWorkOrderSingleCard.vue` — prop + computed**
|
||||
|
||||
props 增加:
|
||||
|
||||
```typescript
|
||||
hideProtocolFeeSummary?: boolean
|
||||
```
|
||||
|
||||
修改 `showProtocolFeeSummary` computed:
|
||||
|
||||
```typescript
|
||||
const showProtocolFeeSummary = computed(
|
||||
() =>
|
||||
!props.hideProtocolFeeSummary &&
|
||||
effectiveCardMeta.value.showProtocolFeeSummary &&
|
||||
!!props.row.paymentSummary
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 浏览器快速确认**
|
||||
|
||||
打开细胞存储 Tab,在改动 CardList 前行为应不变(默认 prop false)。
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSampleGroup.vue \
|
||||
web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSingleCard.vue
|
||||
git commit -m "feat(web-admin): allow hiding sample context bar and card-level protocol fee"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: 新建 `QcWorkOrderProtocolGroup.vue`
|
||||
|
||||
**Files:**
|
||||
- Create: `web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderProtocolGroup.vue`
|
||||
|
||||
- [ ] **Step 1: 创建组件(完整骨架)**
|
||||
|
||||
```vue
|
||||
<!-- 质检工单 · 同协议多样本分组(协议组头 + 样本 Tab + SampleGroup) -->
|
||||
<template>
|
||||
<article class="qc-protocol-row">
|
||||
<div class="qc-protocol-row__ctx">
|
||||
<span class="qc-protocol-row__idx">{{ groupIndex }}</span>
|
||||
<span class="qc-protocol-row__code">{{ group.protocolNo || '—' }}</span>
|
||||
<el-tag v-if="protocolStatus.label" :type="protocolStatus.tagType" size="small">
|
||||
{{ protocolStatus.label }}
|
||||
</el-tag>
|
||||
<span class="qc-protocol-row__sub">
|
||||
{{ sampleCountLabel }}
|
||||
<template v-if="progressLabel"> · {{ progressLabel }}</template>
|
||||
</span>
|
||||
<span v-if="group.workOrders.length > 1" class="qc-protocol-row__badge">
|
||||
{{ group.workOrders.length }} 条质检
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<QcWorkOrderProtocolPaymentPanel
|
||||
v-if="protocolPaymentSummary"
|
||||
:summary="protocolPaymentSummary"
|
||||
compact
|
||||
class="qc-protocol-row__fee"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-if="group.sampleGroups.length > 1"
|
||||
class="qc-protocol-sample-tabs"
|
||||
>
|
||||
<div class="qc-protocol-sample-tabs__row" role="tablist" aria-label="同协议样本">
|
||||
<button
|
||||
v-for="(sampleGroup, tabIndex) in group.sampleGroups"
|
||||
:key="sampleTabKey(sampleGroup)"
|
||||
type="button"
|
||||
role="tab"
|
||||
class="qc-wo-indep-tabs__btn"
|
||||
:class="{ 'is-active': sampleTabKey(sampleGroup) === activeSampleKey }"
|
||||
:aria-selected="sampleTabKey(sampleGroup) === activeSampleKey"
|
||||
@click="activeSampleKey = sampleTabKey(sampleGroup)"
|
||||
>
|
||||
<span class="qc-wo-tab__index">{{ tabIndex + 1 }}</span>
|
||||
<span class="qc-wo-tab__no">{{ sampleGroup.sampleCode || '—' }}</span>
|
||||
<span v-if="sampleTypeLabel(sampleGroup)" class="qc-wo-tab__source qc-wo-tab__source--reception">
|
||||
{{ sampleTypeLabel(sampleGroup) }}
|
||||
</span>
|
||||
<el-tag
|
||||
v-if="gateWorkOrder(sampleGroup)"
|
||||
:type="workOrderStatusTagType(gateWorkOrder(sampleGroup)!.workOrderStatus)"
|
||||
size="small"
|
||||
class="qc-wo-tab__status"
|
||||
>
|
||||
{{ workOrderStatusLabel(gateWorkOrder(sampleGroup)!.workOrderStatus) }}
|
||||
</el-tag>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<QcWorkOrderSampleGroup
|
||||
v-if="activeSampleGroup"
|
||||
:group="activeSampleGroup"
|
||||
:group-index="groupIndex"
|
||||
:card-meta-config="cardMetaConfig"
|
||||
:task-refresh-token="taskRefreshToken"
|
||||
:show-work-order-ops="showWorkOrderOps"
|
||||
:show-work-order-view-only="showWorkOrderViewOnly"
|
||||
:task-list-mode="taskListMode"
|
||||
:preset-tasks-by-work-order-id="presetTasksByWorkOrderId"
|
||||
hide-context-bar
|
||||
:hide-protocol-fee-summary="!!protocolPaymentSummary"
|
||||
@configure="(row) => emit('configure', row)"
|
||||
@view="(row) => emit('view', row)"
|
||||
@command="(cmd, row) => emit('command', cmd, row)"
|
||||
@tasks-changed="emit('tasks-changed')"
|
||||
/>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import type { QcWorkOrder } from '@/api/qc-work-order'
|
||||
import type { QcTask } from '@/api/qc-task'
|
||||
import { workOrderStatusLabel } from '@/utils/qc-labels'
|
||||
import type { TagType } from '@/utils/status-tag-registry'
|
||||
import {
|
||||
type QcWorkOrderProtocolGroupModel,
|
||||
type QcWorkOrderSampleGroupModel,
|
||||
resolveGateWorkOrderForSampleGroup,
|
||||
resolveInboundSampleGroupKey
|
||||
} from '@/utils/qc-work-order-groups'
|
||||
import type { QcWorkOrderCardMetaConfig } from '@/utils/qc-work-order-card-meta'
|
||||
import {
|
||||
buildProtocolGroupProgressLabel,
|
||||
resolveProtocolGroupPaymentSummary,
|
||||
resolveProtocolGroupStatus
|
||||
} from '@/utils/qc-work-order-card-meta'
|
||||
import QcWorkOrderSampleGroup from './QcWorkOrderSampleGroup.vue'
|
||||
import QcWorkOrderProtocolPaymentPanel from './QcWorkOrderProtocolPaymentPanel.vue'
|
||||
|
||||
defineOptions({ name: 'QcWorkOrderProtocolGroup' })
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
group: QcWorkOrderProtocolGroupModel
|
||||
groupIndex: number
|
||||
cardMetaConfig: QcWorkOrderCardMetaConfig
|
||||
taskRefreshToken: number
|
||||
showWorkOrderOps?: boolean
|
||||
showWorkOrderViewOnly?: boolean
|
||||
taskListMode?: 'workOrder' | 'mine'
|
||||
presetTasksByWorkOrderId?: Record<string, QcTask[]>
|
||||
}>(),
|
||||
{
|
||||
showWorkOrderOps: true,
|
||||
showWorkOrderViewOnly: false,
|
||||
taskListMode: 'workOrder'
|
||||
}
|
||||
)
|
||||
|
||||
const emit = defineEmits<{
|
||||
configure: [row: QcWorkOrder]
|
||||
view: [row: QcWorkOrder]
|
||||
command: [cmd: string, row: QcWorkOrder]
|
||||
'tasks-changed': []
|
||||
}>()
|
||||
|
||||
function sampleTabKey(sampleGroup: QcWorkOrderSampleGroupModel) {
|
||||
return sampleGroup.groupKey || resolveInboundSampleGroupKey(sampleGroup.workOrders[0])
|
||||
}
|
||||
|
||||
const activeSampleKey = ref(
|
||||
props.group.sampleGroups[0] ? sampleTabKey(props.group.sampleGroups[0]) : ''
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.group.sampleGroups.map((g) => sampleTabKey(g)).join(','),
|
||||
() => {
|
||||
const keys = props.group.sampleGroups.map((g) => sampleTabKey(g))
|
||||
if (!keys.includes(activeSampleKey.value)) {
|
||||
activeSampleKey.value = keys[0] || ''
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const activeSampleGroup = computed(() =>
|
||||
props.group.sampleGroups.find((g) => sampleTabKey(g) === activeSampleKey.value)
|
||||
)
|
||||
|
||||
const gateRow = computed(() =>
|
||||
resolveGateWorkOrderForSampleGroup(
|
||||
props.group.sampleGroups[0]?.workOrders || props.group.workOrders
|
||||
)
|
||||
)
|
||||
|
||||
const protocolStatus = computed(() =>
|
||||
gateRow.value
|
||||
? resolveProtocolGroupStatus(gateRow.value)
|
||||
: { label: '', tagType: 'info' as TagType }
|
||||
)
|
||||
|
||||
const sampleCountLabel = computed(() => `${props.group.sampleGroups.length} 个样本`)
|
||||
|
||||
const progressLabel = computed(() => buildProtocolGroupProgressLabel(props.group))
|
||||
|
||||
const protocolPaymentSummary = computed(() =>
|
||||
resolveProtocolGroupPaymentSummary(props.group)
|
||||
)
|
||||
|
||||
function sampleTypeLabel(sampleGroup: QcWorkOrderSampleGroupModel) {
|
||||
const gate = resolveGateWorkOrderForSampleGroup(sampleGroup.workOrders)
|
||||
return (gate?.sampleTypeName || sampleGroup.workOrders[0]?.sampleTypeName || '').trim()
|
||||
}
|
||||
|
||||
function gateWorkOrder(sampleGroup: QcWorkOrderSampleGroupModel) {
|
||||
return resolveGateWorkOrderForSampleGroup(sampleGroup.workOrders)
|
||||
}
|
||||
|
||||
function workOrderStatusTagType(status: string): TagType {
|
||||
if (status === 'ywc') return 'success'
|
||||
if (status === 'ypz') return 'warning'
|
||||
if (status === 'yzf') return 'danger'
|
||||
return 'info'
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 追加 scoped SCSS**
|
||||
|
||||
在 `</script>` 后追加样式(复用 `QcWorkOrderSampleGroup` 的 pill Tab 类名,协议组头对齐 `qc-sample-row__ctx`):
|
||||
|
||||
```scss
|
||||
<style scoped lang="scss">
|
||||
.qc-protocol-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.qc-protocol-row__ctx {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px 12px;
|
||||
padding: 12px 16px;
|
||||
background: linear-gradient(180deg, var(--primary-bg, #ecfdf5) 0%, #fff 100%);
|
||||
border-bottom: 1px solid #d1fae5;
|
||||
}
|
||||
|
||||
.qc-protocol-row__idx {
|
||||
flex-shrink: 0;
|
||||
font-size: 12px;
|
||||
color: var(--mint-text-muted, #64748b);
|
||||
min-width: 20px;
|
||||
}
|
||||
|
||||
.qc-protocol-row__code {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||
}
|
||||
|
||||
.qc-protocol-row__sub {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 12px;
|
||||
color: var(--mint-text-muted, #64748b);
|
||||
}
|
||||
|
||||
.qc-protocol-row__badge {
|
||||
flex-shrink: 0;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 2px 10px;
|
||||
border-radius: 999px;
|
||||
background: var(--primary-bg, #ecfdf5);
|
||||
color: #047857;
|
||||
border: 1px solid #d1fae5;
|
||||
}
|
||||
|
||||
.qc-protocol-row__fee {
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.qc-protocol-sample-tabs {
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
background: #f8fafc;
|
||||
}
|
||||
|
||||
.qc-protocol-sample-tabs__row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* 将 QcWorkOrderSampleGroup.vue 中 .qc-wo-indep-tabs__btn 及相关 pill Tab 样式复制到此处 */
|
||||
</style>
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderProtocolGroup.vue
|
||||
git commit -m "feat(web-admin): add protocol group card with sample tabs for inbound QC"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: `QcWorkOrderCardList` 接入协议分组
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderCardList.vue`
|
||||
|
||||
- [ ] **Step 1: import 与 groupedRows 分支**
|
||||
|
||||
script 区:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
groupInboundQcWorkOrders,
|
||||
groupInboundQcWorkOrdersByProtocol,
|
||||
groupOutboundQcWorkOrders,
|
||||
buildAllTabListItems,
|
||||
type QcWorkOrderAllTabListItem
|
||||
} from '@/utils/qc-work-order-groups'
|
||||
import QcWorkOrderProtocolGroup from './QcWorkOrderProtocolGroup.vue'
|
||||
```
|
||||
|
||||
新增 computed:
|
||||
|
||||
```typescript
|
||||
const protocolGroupedRows = computed(() => {
|
||||
if (!cardMetaUsesInboundGroups(props.cardMetaConfig.tabKey)) return []
|
||||
return groupInboundQcWorkOrdersByProtocol(props.rows)
|
||||
})
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 模板 — inbound 分支改用 ProtocolGroup**
|
||||
|
||||
将 `useGroupedList` 分支中:
|
||||
|
||||
```vue
|
||||
<QcWorkOrderSampleGroup
|
||||
v-for="(group, idx) in groupedRows"
|
||||
```
|
||||
|
||||
替换为:
|
||||
|
||||
```vue
|
||||
<QcWorkOrderProtocolGroup
|
||||
v-if="cardMetaUsesInboundGroups(cardMetaConfig.tabKey)"
|
||||
v-for="(group, idx) in protocolGroupedRows"
|
||||
:key="group.groupKey"
|
||||
:group="group"
|
||||
:group-index="cardIndex(idx)"
|
||||
...
|
||||
/>
|
||||
<QcWorkOrderSampleGroup
|
||||
v-else
|
||||
v-for="(group, idx) in groupedRows"
|
||||
...
|
||||
/>
|
||||
```
|
||||
|
||||
或更简洁:`groupedRows` computed 内 inbound 返回空数组,单独 `protocolGroupedRows` 仅 inbound 使用;outbound 仍用 `groupedRows`。
|
||||
|
||||
推荐改 `groupedRows`:
|
||||
|
||||
```typescript
|
||||
const groupedRows = computed(() => {
|
||||
if (cardMetaUsesOutboundGroups(props.cardMetaConfig.tabKey)) {
|
||||
return groupOutboundQcWorkOrders(props.rows)
|
||||
}
|
||||
return []
|
||||
})
|
||||
```
|
||||
|
||||
inbound 专用 `protocolGroupedRows` 见 Step 1。
|
||||
|
||||
- [ ] **Step 3: 浏览器验证 manage 页**
|
||||
|
||||
URL: `http://localhost:3006/#/quality-group/quality-manage/qc-work-order?tab=inbound_cell_storage`
|
||||
|
||||
期望:同协议多样本 → 1 张协议卡 + 样本 Tab;单样本 → 无样本 Tab 行。
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderCardList.vue
|
||||
git commit -m "feat(web-admin): render inbound QC lists as protocol groups with sample tabs"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: 关键词 placeholder + mine 前端过滤
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/utils/qc-work-order-tabs.ts`
|
||||
- Modify: `web-admin/src/utils/qc-mine-task-groups.ts`
|
||||
|
||||
- [ ] **Step 1: `keywordPlaceholderForTab`**
|
||||
|
||||
将 inbound 默认 return 改为:
|
||||
|
||||
```typescript
|
||||
if (tab.key === 'inbound_research_donation') {
|
||||
return '工单号/捐赠单号/样本编码/入库编码'
|
||||
}
|
||||
if (tab.group === 'inbound') {
|
||||
return '工单号/协议号/样本编码/入库编码'
|
||||
}
|
||||
```
|
||||
|
||||
(放在 `tab.group === 'outbound'` 判断之前,且 `inbound_research_donation` 先于 general inbound。)
|
||||
|
||||
- [ ] **Step 2: `keywordMatchesWorkOrder` inbound 字段**
|
||||
|
||||
将 inbound 组 fields 数组改为:
|
||||
|
||||
```typescript
|
||||
: [row.workOrderNo, row.protocolNo, row.sampleCode, row.labStorageCode]
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/utils/qc-work-order-tabs.ts web-admin/src/utils/qc-mine-task-groups.ts
|
||||
git commit -m "feat(web-admin): support protocol number in inbound QC keyword filters"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 7: 后端列表关键词 — `protocol_no`
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/app/crud/qc_work_order.py`
|
||||
|
||||
- [ ] **Step 1: 在 `list_work_orders` 关键词 OR 中追加**
|
||||
|
||||
定位 `_filtered()` 内(约 L1272):
|
||||
|
||||
```python
|
||||
keyword_conditions = [
|
||||
BizQcWorkOrder.work_order_no.like(like),
|
||||
BizQcWorkOrder.sample_code.like(like),
|
||||
BizQcWorkOrder.protocol_no.like(like),
|
||||
]
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 手动 API 验证**
|
||||
|
||||
```bash
|
||||
cd backend && source venv/bin/activate
|
||||
# 假设本地服务已起;替换 TOKEN 与协议号
|
||||
curl -s "http://127.0.0.1:8000/api/web/admin/qc-work-orders?page=1&pageSize=10&workOrderType=inbound&receptionSource=cell_storage&keyword=XY2026" \
|
||||
-H "Authorization: Bearer <token>" | python -m json.tool | head -40
|
||||
```
|
||||
|
||||
期望:返回列表中 `protocolNo` 含关键词的工单。
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/app/crud/qc_work_order.py
|
||||
git commit -m "feat(backend): include protocol number in QC work order list keyword search"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 8: 联调回归与文档收尾
|
||||
|
||||
**Files:**
|
||||
- Modify: `docs/superpowers/specs/2026-06-25-qc-work-order-protocol-group-design.md`(状态 → 已实现)
|
||||
|
||||
- [ ] **Step 1: 前端 lint**
|
||||
|
||||
```bash
|
||||
cd web-admin && pnpm lint
|
||||
```
|
||||
|
||||
期望:无新增 error。
|
||||
|
||||
- [ ] **Step 2: 手工回归清单(两页)**
|
||||
|
||||
| # | 场景 | 页面 | 期望 |
|
||||
|---|------|------|------|
|
||||
| 1 | 同协议 2+ 样本 | 质检工单 · 细胞存储 | 1 协议卡,样本 Tab 可切换 |
|
||||
| 2 | 同协议 1 样本 | 同上 | 无样本 Tab,直接工单区 |
|
||||
| 3 | 同样本 接收+生产 | 同上 | 内层触发来源 Tab 正常 |
|
||||
| 4 | 协议费用 | 细胞存储 | 组头一次,卡片内不重复 |
|
||||
| 5 | 科研捐赠 | 科研捐赠 Tab | 无费用条,捐赠单号组头 |
|
||||
| 6 | 关键词 | 两页 | 协议号/捐赠单号可搜 |
|
||||
| 7 | 所有 Tab | 两页 | 仍平铺,无协议分组 |
|
||||
| 8 | 出库/临时 Tab | 质检工单 | 布局不变 |
|
||||
| 9 | 我的质检任务 | mine · 细胞存储 | 与 manage 分组一致,仅查看 |
|
||||
|
||||
- [ ] **Step 3: 更新知识图谱**
|
||||
|
||||
```bash
|
||||
./scripts/update-graph.sh frontend
|
||||
./scripts/update-graph.sh backend
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 更新 spec 状态**
|
||||
|
||||
`docs/superpowers/specs/2026-06-25-qc-work-order-protocol-group-design.md` 头部 `状态:已实现`。
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add docs/superpowers/specs/2026-06-25-qc-work-order-protocol-group-design.md
|
||||
git commit -m "docs: mark inbound QC protocol group spec as implemented"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Spec Coverage Checklist
|
||||
|
||||
| Spec § | Task |
|
||||
|--------|------|
|
||||
| §2 三层结构 / 分组键 | Task 1 |
|
||||
| §3.1 协议组头 | Task 2, 4 |
|
||||
| §3.2 样本 Tab | Task 4 |
|
||||
| §3.3 hideContextBar + 内层 SampleGroup | Task 3, 4 |
|
||||
| §3 协议费用组级一次 | Task 2, 3, 4 |
|
||||
| §4.4 所有 Tab 不变 | 不修改 `buildAllTabListItems` |
|
||||
| §4.5 mine 共用 + protocolNo 关键词 | Task 5, 6 |
|
||||
| §5.1 后端 protocol_no | Task 7 |
|
||||
| §5.2 placeholder | Task 6 |
|
||||
| §7 验收 1–9 | Task 8 |
|
||||
|
||||
---
|
||||
|
||||
## Plan complete
|
||||
|
||||
Saved to `docs/superpowers/plans/2026-06-25-qc-work-order-protocol-group.md`.
|
||||
|
||||
**Two execution options:**
|
||||
|
||||
1. **Subagent-Driven (recommended)** — 按 Task 1→8 派发子 agent,每 Task 完成后 review
|
||||
2. **Inline Execution** — 本会话内用 `executing-plans` 连续实现,Task 5 完成后浏览器 checkpoint
|
||||
|
||||
需要哪种方式开始写代码?
|
||||
@@ -0,0 +1,326 @@
|
||||
# 质检检测批次 — 设计文档
|
||||
|
||||
> 日期: 2026-06-25
|
||||
> 状态: **待评审 / 待实现**
|
||||
> 范围: web-admin + backend(质检工单、我的质检任务、配置检测 / 调整检测)
|
||||
> 前置: `2026-05-17-quality-inspection-modules-design.md`、`2026-06-12-qc-task-assignee-my-tasks-design.md`(负责人粒度将变更)
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
### 1.1 现状问题
|
||||
|
||||
- 配置检测时,同一工单内 **每个检测主数据项目只能选一次**(`_sync_work_order_*` 以 `lab_test_item_id` / `third_party_item_id` 为唯一键)。
|
||||
- 负责人按 **每个检测项目** 独立指派,配置弹窗右侧「负责人配置」与左侧项目一一对应。
|
||||
- 工单展开区、我的质检任务中,列表 **平铺展示每条质检任务**(≈ 每个检测项目一张卡片)。
|
||||
|
||||
### 1.2 目标
|
||||
|
||||
引入 **检测批次** 作为工单与检测项目之间的容器层:
|
||||
|
||||
- 一个质检工单可配置 **多个检测批次**;
|
||||
- 每个批次内勾选 lab / 第三方项目(**批次内项目不重复**;**跨批次允许重复同一主数据项目**);
|
||||
- 每个批次配置 **多名负责人**,负责该批次下全部项目的任务;
|
||||
- `ypz`(已配置)后仍可 **追加批次**(调整检测);
|
||||
- 批次 **无独立状态机**,仅作分组容器;任务仍保留 `dzx / jxz / ywc`;
|
||||
- 列表 UI:**先展示批次,展开后展示批次内检测项目/任务**。
|
||||
|
||||
---
|
||||
|
||||
## 2. 已确认的产品决策(2026-06-25)
|
||||
|
||||
| # | 问题 | 决策 |
|
||||
|---|------|------|
|
||||
| 1 | 批次负责人 | **允许多人**;完成语义沿用现网:**任一负责人可独立开始/填写结果/完成** |
|
||||
| 2 | 同主数据项目跨批次重复 | **允许**(例如批次 1、批次 2 均可含「无菌检测」) |
|
||||
| 3 | 同批次内同一项目重复 | **不允许** |
|
||||
| 4 | 批次内 lab + 第三方混合 | **允许** |
|
||||
| 5 | 配置时机 | **`dpz` 首次可配多批次**;**`ypz` 后可追加批次**(调整检测) |
|
||||
| 6 | 批次独立状态 | **否** — 批次仅作容器;不增加批次级开始/完成 |
|
||||
| 7 | 批次命名 | **自动编号** + 展示名规则:**`YYYYMMDD检测`**(创建日);可选附带序号区分同日多批次,见 §4.2 |
|
||||
|
||||
### 2.1 与 2026-06-12 负责人设计的差异
|
||||
|
||||
| 项 | 2026-06-12(已实现) | 本变更 |
|
||||
|----|---------------------|--------|
|
||||
| 指派粒度 | 每个检测项目 | **每个检测批次** |
|
||||
| 存储 | `biz_qc_task_assignee` 按 task | 批次表 + `biz_qc_batch_assignee`;任务 assignee **从批次继承同步** |
|
||||
| 配置 UI | 右栏按项目选负责人 | 每批次一块卡片,批次级多选负责人 |
|
||||
|
||||
任务级 `biz_qc_task_assignee` **保留**,作为「我的质检任务」查询与写鉴权的数据源;配置/调整批次负责人时 **写入或更新** 该批次下所有未删除任务的 assignee。
|
||||
|
||||
---
|
||||
|
||||
## 3. 目标架构
|
||||
|
||||
```
|
||||
biz_qc_work_order
|
||||
│
|
||||
│ 1 : N
|
||||
▼
|
||||
biz_qc_work_order_inspection_batch ← 新增
|
||||
│
|
||||
│ 1 : N
|
||||
├──────────────────────┐
|
||||
▼ ▼
|
||||
biz_qc_work_order_lab_item biz_qc_work_order_third_item
|
||||
(+ batch_id) (+ batch_id)
|
||||
│ │
|
||||
│ 1 : 1 │ 1 : 1
|
||||
▼ ▼
|
||||
biz_qc_task
|
||||
│
|
||||
▼
|
||||
biz_qc_task_assignee (从批次负责人继承)
|
||||
```
|
||||
|
||||
**工单完成规则不变**:工单下 **全部任务** `ywc` → 工单 `ywc`。
|
||||
|
||||
**批次进度(仅展示)**:前端按批次聚合任务状态计算,如 `2/3 已完成`,不落库批次状态字段。
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据模型
|
||||
|
||||
### 4.1 新表 `biz_qc_work_order_inspection_batch`
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `id` | VARCHAR(64) | PK |
|
||||
| `work_order_id` | VARCHAR(64) | 工单 ID |
|
||||
| `order_source` | VARCHAR(20) | 与工单一致:`inbound` / `outbound` / `temporary` |
|
||||
| `batch_no` | VARCHAR(32) | 批次编号,工单内唯一,如 `{work_order_no}-B01` |
|
||||
| `batch_name` | VARCHAR(200) | 展示名:`YYYYMMDD检测`;同日多批次可加后缀 `-2` |
|
||||
| `tenant_no` | VARCHAR(64) | 租户 |
|
||||
| `order_num` | INT | 工单内排序 |
|
||||
| 公共字段 | | `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag` |
|
||||
|
||||
索引:`(work_order_id, del_flag)`、`(tenant_no, batch_no, del_flag)`。
|
||||
|
||||
**不设** `batch_status` 字段。
|
||||
|
||||
### 4.2 批次编号与命名规则
|
||||
|
||||
- `batch_no`:`{work_order_no}-B` + 两位序号(`B01`, `B02`, …),工单内递增。
|
||||
- `batch_name`:创建日 `YYYYMMDD` + 字面量 `检测` → 例:`20260625检测`。
|
||||
- 若同一工单同一天创建多个批次:第二个起为 `20260625检测-2`、`20260625检测-3`(避免展示歧义)。
|
||||
|
||||
### 4.3 新表 `biz_qc_batch_assignee`
|
||||
|
||||
结构对齐 `biz_qc_task_assignee`:
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `batch_id` | FK → 批次 |
|
||||
| `user_id` | 负责人 |
|
||||
| `tenant_no`, `order_num`, 公共字段 | |
|
||||
|
||||
唯一性:应用层保证 `batch_id + user_id` 未删除不重复。
|
||||
|
||||
### 4.4 改表现有明细表
|
||||
|
||||
**`biz_qc_work_order_lab_item`**、**`biz_qc_work_order_third_item`** 各增加:
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `batch_id` | VARCHAR(64) NOT NULL(迁移后) |
|
||||
|
||||
**唯一性变更**:
|
||||
|
||||
- 旧:工单内 `lab_test_item_id` 唯一(应用层 dict 键)。
|
||||
- 新:**批次内** `lab_test_item_id` 唯一;**跨批次可重复**。
|
||||
- 第三方:**批次内** `third_party_item_id` 唯一。
|
||||
|
||||
可选 DB 唯一索引(软删场景用应用层校验):
|
||||
|
||||
- `UNIQUE (batch_id, lab_test_item_id)` where del_flag=0(MySQL 5.7 无部分索引,**以应用层校验为准**)。
|
||||
|
||||
### 4.5 任务表(可选冗余)
|
||||
|
||||
`biz_qc_task` 可增加 `batch_id` 冗余,便于按批次列表查询;非必须(可通过 `source_line_id` JOIN 明细得 `batch_id`)。
|
||||
|
||||
### 4.6 历史数据迁移
|
||||
|
||||
对已配置工单(存在 lab/third 明细且 `del_flag=0`):
|
||||
|
||||
1. 每个工单插入 **默认批次 1**(`batch_no` = `{wo}-B01`,`batch_name` = 配置日或迁移日 `YYYYMMDD检测`)。
|
||||
2. 现有明细行 `batch_id` 指向该批次。
|
||||
3. 批次负责人:取该批次下各任务现有 `biz_qc_task_assignee` 的 **并集** 写入 `biz_qc_batch_assignee`;任务 assignee 保持不变。
|
||||
|
||||
---
|
||||
|
||||
## 5. API 设计
|
||||
|
||||
### 5.1 配置 / 调整检测(扩展或 v2)
|
||||
|
||||
**推荐**:扩展 `POST /web/admin/qc-work-orders/{id}/configure`,body 改为批次数组;**废弃**扁平 `labItemIds` + `labItemAssignees` 作为唯一入口(可保留兼容一版,内部转批次)。
|
||||
|
||||
```typescript
|
||||
type WorkOrderConfigureBody = {
|
||||
batches: Array<{
|
||||
id?: string // 调整时:已有批次传 id;新增批次省略
|
||||
assigneeUserIds: string[] // ≥1
|
||||
hasLab: boolean
|
||||
hasThirdParty: boolean
|
||||
labItemIds: string[] // 批次内不重复
|
||||
thirdPartyItemIds: string[]
|
||||
}>
|
||||
}
|
||||
```
|
||||
|
||||
**校验**:
|
||||
|
||||
| 规则 | 说明 |
|
||||
|------|------|
|
||||
| 工单状态 | `dpz` 或 `ypz` 均可提交(`ypz` = 追加/调整批次) |
|
||||
| 每批次 | 至少 1 种检测方式且对应项目非空 |
|
||||
| 批次负责人 | 每批次 `assigneeUserIds.length ≥ 1` |
|
||||
| 批次内项目 | lab / third 列表各自无重复 ID |
|
||||
| 删除批次 | 若批次内存在 `jxz` 或 `ywc` 任务 → **禁止删除整批**(或仅允许删全 `dzx` 的批次,与现网删项规则对齐) |
|
||||
| 移除批次内项目 | 沿用现网:进行中/已完成对应任务不可删 |
|
||||
|
||||
**同步逻辑**(替代 `_sync_work_order_lab_items` 扁平键):
|
||||
|
||||
- 按 `batch_id` 维度比对 lab/third 明细行;
|
||||
- 新增行 → `create_task_for_line` + 从批次 assignee 写入 `biz_qc_task_assignee`;
|
||||
- 保留行 → 更新 `order_num`;**同步任务 assignee 为批次当前负责人集合**;
|
||||
- 删除行 → 软删明细 + 软删任务 + 软删任务 assignee。
|
||||
|
||||
**首次配置**(`dpz`):提交后工单 → `ypz`,写 `configured_time` / `configured_by`。
|
||||
|
||||
**追加批次**(`ypz`):仅新增批次及其明细/任务;不改 `configured_time` 或更新 `update_time` 即可。
|
||||
|
||||
### 5.2 批次列表(供展开 UI)
|
||||
|
||||
`GET /web/admin/qc-work-orders/{id}/inspection-batches`
|
||||
|
||||
响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"list": [
|
||||
{
|
||||
"id": "...",
|
||||
"batchNo": "ZJ202606250001-B01",
|
||||
"batchName": "20260625检测",
|
||||
"orderNum": 1,
|
||||
"assigneeUserIds": ["..."],
|
||||
"assigneeUserNames": "张三、李四",
|
||||
"taskCount": 3,
|
||||
"completedTaskCount": 1,
|
||||
"tasks": [ /* 与现有 task 列表项结构一致 */ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
或在工单详情中内嵌 `batches` 字段,减少请求数。
|
||||
|
||||
### 5.3 我的质检任务
|
||||
|
||||
`GET /qc-tasks/mine`:**不变** — 仍按 `biz_qc_task_assignee` 过滤。
|
||||
|
||||
批次负责人变更时 **必须同步** 该批次下任务的 assignee,保证「我的任务」可见性正确。
|
||||
|
||||
---
|
||||
|
||||
## 6. 前端改造
|
||||
|
||||
### 6.1 配置检测 / 调整检测弹窗(`qc-work-order/index.vue`)
|
||||
|
||||
**由「左项目 + 右负责人」改为「批次卡片列表」**:
|
||||
|
||||
```
|
||||
┌─ 批次 1 · 20260625检测 ──────────────────┐
|
||||
│ 负责人: [多选用户] *必填 │
|
||||
│ □ 实验室自检 □ 第三方检测 │
|
||||
│ 项目多选区(可混合 lab + third) │
|
||||
│ [删除批次] │
|
||||
└──────────────────────────────────────────┘
|
||||
[+ 添加批次]
|
||||
```
|
||||
|
||||
- `dpz`:可一次添加多批次后提交。
|
||||
- `ypz`:打开「调整检测」→ 回显已有批次 + 允许「添加批次」;已有批次可改负责人、增删项目(受任务状态约束)。
|
||||
|
||||
### 6.2 工单展开 / 我的质检任务列表
|
||||
|
||||
**层级**:工单 → **批次行(可折叠)** → 任务卡片(检测项目)。
|
||||
|
||||
新建或改造组件,建议 `QcWorkOrderBatchSubList.vue`:
|
||||
|
||||
- 批次头:批次名、`batchNo`、负责人 Tag、进度 `n/m`、任务状态 Tag 聚合(如全完成显示 success)。
|
||||
- 展开:复用现有 `QcWorkOrderTaskSubList` 任务卡片(传入 `presetTasks` 为该批次 tasks)。
|
||||
|
||||
**我的质检任务**:`buildMineCardListModel` 由 `工单 → tasks[]` 改为 `工单 → batches[] → tasks[]`;筛选/关键词仍可按任务字段匹配。
|
||||
|
||||
### 6.3 UI 模式
|
||||
|
||||
- 配置弹窗:参考 P21 + 多卡片表单(可参考生产工单多步骤配置)。
|
||||
- 批次折叠列表:参考 `el-collapse` 或现有 kanban 子列表样式;遵守 Fresh Mint 规范。
|
||||
|
||||
---
|
||||
|
||||
## 7. 权限与操作(沿用现网)
|
||||
|
||||
| 场景 | 规则 |
|
||||
|------|------|
|
||||
| 工单页督办 | 持有 `biz:qcTask:list` 可操作全部任务 |
|
||||
| 我的任务页 | 仅 `task.assignee` 可开始/填结果 |
|
||||
| 配置/调整检测 | 持有 `biz:qcWorkOrder:list` |
|
||||
|
||||
批次无独立操作按钮;开始/完成仍在任务卡片上。
|
||||
|
||||
---
|
||||
|
||||
## 8. 风险与缓解
|
||||
|
||||
| 风险 | 缓解 |
|
||||
|------|------|
|
||||
| 与 2026-06-12「按项目指派」文档冲突 | 本 spec supersede 指派粒度;迁移脚本合并 assignee 到默认批次 |
|
||||
| 同项目跨批次导致任务/参数混淆 | 任务仍绑定 **明细行 ID** + 主数据快照;参数按 `item_source + item_id` 查模板,与现网一致 |
|
||||
| 调整批次负责人后「我的任务」不一致 | 配置 API 内 `_sync_task_assignees_from_batch` 批量更新 |
|
||||
| 配置弹窗复杂度上升 | 批次卡片 + 校验提示;单测覆盖重复项校验 |
|
||||
| 工作量 | 分阶段:① 数据模型 + 配置 API ② 配置 UI ③ 列表批次化 ④ 迁移 |
|
||||
|
||||
---
|
||||
|
||||
## 9. 实现阶段建议
|
||||
|
||||
| 阶段 | 内容 | 预估 |
|
||||
|------|------|------|
|
||||
| P1 | DDL、Model、迁移脚本、批次 CRUD、configure API 重写 | 3~4 人天 |
|
||||
| P2 | 配置/调整检测弹窗 UI | 2~3 人天 |
|
||||
| P3 | 工单展开 + 我的任务列表批次化 | 2~3 人天 |
|
||||
| P4 | 联调、回归六 Tab、历史数据验证 | 1~2 人天 |
|
||||
| **合计** | | **8~12 人天** |
|
||||
|
||||
---
|
||||
|
||||
## 10. 验收场景(摘要)
|
||||
|
||||
1. `dpz` 工单一次配置 2 个批次,每批不同负责人、不同项目组合 → 工单 `ypz`,任务数 = 各批项目数之和。
|
||||
2. 两批次均含同一 lab 项目 → 生成 2 条明细、2 条任务,参数模板相同、结果独立填写。
|
||||
3. 同批次内勾选重复 lab 项目 → 前端 + 后端拒绝。
|
||||
4. 单批次同时含 lab + third 项目 → 正常生成 `sysz` + `dsfjc` 任务。
|
||||
5. `ypz` 工单追加批次 3 → 仅新增批次 3 的任务,不影响已完成任务。
|
||||
6. 修改批次负责人 → 该批次未完成任务在新负责人「我的任务」中可见。
|
||||
7. 工单列表展开:显示批次列表;展开批次显示项目任务卡片。
|
||||
8. 历史工单迁移后:显示为「批次 1」,行为与迁移前一致。
|
||||
|
||||
---
|
||||
|
||||
## 11. 开放项(可选,不阻塞开工)
|
||||
|
||||
- 批次 `remark` 是否在 UI 暴露(默认隐藏)。
|
||||
- 删除「空批次」(无项目)是否允许在保存时自动剔除。
|
||||
- 第三方费用合计:工单级汇总不变;是否在批次头展示该批 third 费用小计。
|
||||
|
||||
---
|
||||
|
||||
## 12. 下一步
|
||||
|
||||
1. **评审本文档** — 确认无遗漏后标记 `状态: 已批准`。
|
||||
2. **OpenSpec 变更** — 建议 capability:`qc-inspection-batch`,与 `api-conventions` / `database-conventions` 对齐。
|
||||
3. **实现计划** — 使用 `writing-plans` 拆 `tasks.md` 后进入开发。
|
||||
|
||||
如需进入实现,请明确:**是否按本文档直接创建 OpenSpec proposal + 实现计划**。
|
||||
@@ -0,0 +1,243 @@
|
||||
# 质检工单「所有」Tab — 设计文档
|
||||
|
||||
> 日期:2026-06-25
|
||||
> 状态:已确认
|
||||
> 范围:`web-admin` 【质检工单】【我的质检任务】;后端列表 API 跨类型关键词增强
|
||||
> 关联:`2026-06-16-qc-work-order-tab-split-design.md`、`2026-06-12-qc-task-assignee-my-tasks-design.md`
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
### 1.1 需求
|
||||
|
||||
客户在现有 5 个分类 Tab(细胞存储 / 科研捐赠 / 中试服务 / 基础实验 / 临时)**之前**新增 **「所有」** Tab,用于跨类型总览质检工单。
|
||||
|
||||
### 1.2 目标
|
||||
|
||||
- 【质检工单】【我的质检任务】**均**增加「所有」Tab,置于 Tab 栏首位。
|
||||
- 「所有」Tab 展示 5 类可见工单(不含 hidden 的临床应用)。
|
||||
- 卡片标题行增加**质检类型 Tag**(细胞存储 / 科研捐赠 / 中试服务 / 基础实验 / 临时)。
|
||||
- 筛选区采用**精简共用字段**;mine 页在共用基础上增加任务相关筛选。
|
||||
|
||||
### 1.3 非目标
|
||||
|
||||
- 不在「所有」Tab 提供「新增临时工单」工具栏(仍仅在「临时质检」Tab)。
|
||||
- 不在「所有」Tab 复用样本分组 / 输注计划分组布局(混排时分组规则冲突)。
|
||||
- 不在本期实现出库工单的输注/交付时间筛选(保留在各分类 Tab);「所有」Tab 统一使用**创建时间**。
|
||||
- 不展示 hidden 的「临床应用」类型(与现有 5 Tab 策略一致)。
|
||||
|
||||
---
|
||||
|
||||
## 2. Tab 配置变更
|
||||
|
||||
### 2.1 新增 Tab Key
|
||||
|
||||
| Tab Key | 展示标签 | 位置 | 列表布局 |
|
||||
|---------|----------|------|----------|
|
||||
| `all` | 所有 | 首位(默认 Tab) | `standalone`(平铺,不分组) |
|
||||
|
||||
### 2.2 Tab 栏顺序(两页一致)
|
||||
|
||||
```
|
||||
所有 | 细胞存储质检 | 科研捐赠质检 | 中试服务质检 | 基础实验质检 | 临时质检
|
||||
```
|
||||
|
||||
### 2.3 默认 Tab
|
||||
|
||||
- **新默认:** `all`(替换原 `inbound_cell_storage`)。
|
||||
- 路由:`?tab=all`;旧链接 `?tab=inbound` 等兼容映射保持不变。
|
||||
|
||||
### 2.3 类型 Tag 映射(卡片展示)
|
||||
|
||||
复用 `resolveTabKeyFromWorkOrder(row)`,映射为短标签:
|
||||
|
||||
| `resolveTabKeyFromWorkOrder` 结果 | Tag 文案 | Tag 语义色 |
|
||||
|-----------------------------------|----------|------------|
|
||||
| `inbound_cell_storage` | 细胞存储 | `primary` |
|
||||
| `inbound_research_donation` | 科研捐赠 | `primary` |
|
||||
| `outbound_pilot_service` | 中试服务 | `info` |
|
||||
| `outbound_basic_experiment` | 基础实验 | `info` |
|
||||
| `temporary` | 临时 | `warning` |
|
||||
|
||||
`outbound_clinical_application` 不在「所有」Tab 展示(hidden Tab 策略延续)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 筛选区设计
|
||||
|
||||
### 3.1 【质检工单】manage 模式 — 主区域
|
||||
|
||||
| 字段 | 控件 | 说明 |
|
||||
|------|------|------|
|
||||
| 质检类型 | `el-select` | 全部 / 细胞存储 / 科研捐赠 / 中试服务 / 基础实验 / 临时;映射为 `workOrderType` + `receptionSource` / `bizType` 组合传给 API |
|
||||
| 关键词 | `el-input` | placeholder:`工单号 / 样本编码 / 申请单号 / 产品名称等` |
|
||||
| 工单状态 | `el-select` | 待配置 / 已配置 / 已完成 / 已作废 |
|
||||
| 创建时间 | `el-date-picker` daterange | 统一按 `createTimeStart` / `createTimeEnd` |
|
||||
|
||||
**hint 文案:** `出库工单按输注/交付时间筛选请进入对应分类 Tab。`
|
||||
|
||||
### 3.2 【质检工单】manage 模式 — 展开更多
|
||||
|
||||
| 字段 | 控件 | 选项 |
|
||||
|------|------|------|
|
||||
| 工单来源 | `el-select` | 样本接收 / 计划质检 / 生产过程 / 生产派发 / 手动创建 |
|
||||
|
||||
工单来源筛选逻辑:
|
||||
|
||||
- `样本接收` → `triggerSource=reception`
|
||||
- `计划质检` → `triggerSource=schedule`
|
||||
- `生产过程` → `triggerSource=production`(非临时)
|
||||
- `生产派发` → 临时工单且 `triggerSource=production`
|
||||
- `手动创建` → 临时工单且 `triggerSource≠production`
|
||||
|
||||
### 3.3 【我的质检任务】mine 模式 — 主区域
|
||||
|
||||
与 manage **一致**,额外增加:
|
||||
|
||||
| 字段 | 控件 | 说明 |
|
||||
|------|------|------|
|
||||
| 任务状态 | `el-select` | 待执行 / 进行中 / 已完成 |
|
||||
| 任务类型 | `el-select` | 实验室自检 / 第三方检测 |
|
||||
|
||||
主区域栅格:关键词、工单状态、任务状态、创建时间(第一行);任务类型可放展开区或与工单状态同行(实现时按 4 列栅格自适应,窄屏折行)。
|
||||
|
||||
**hint 文案:** `仅展示指派给当前登录人的质检任务。出库工单按输注/交付时间筛选请进入对应分类 Tab。`
|
||||
|
||||
### 3.4 【我的质检任务】mine 模式 — 展开更多
|
||||
|
||||
与 manage 一致:工单来源。
|
||||
|
||||
### 3.5 质检类型 → API 参数映射
|
||||
|
||||
| 选项 | API 参数 |
|
||||
|------|----------|
|
||||
| 全部 | 不传 `workOrderType` / `receptionSource` / `bizType` |
|
||||
| 细胞存储 | `workOrderType=inbound` + `receptionSource=cell_storage` |
|
||||
| 科研捐赠 | `workOrderType=inbound` + `receptionSource=research_donation` |
|
||||
| 中试服务 | `workOrderType=outbound` + `bizType=pilot_service` |
|
||||
| 基础实验 | `workOrderType=outbound` + `bizType=basic_experiment` |
|
||||
| 临时 | `workOrderType=temporary` |
|
||||
|
||||
当用户在「所有」Tab 内选了具体质检类型,行为等价于在该子类型下筛选,但列表仍为平铺 + 类型 Tag 布局。
|
||||
|
||||
---
|
||||
|
||||
## 4. 列表与卡片
|
||||
|
||||
### 4.1 列表布局
|
||||
|
||||
- `all` Tab:`listLayout = standalone`,**不使用** `groupInboundQcWorkOrders` / `groupOutboundQcWorkOrders`。
|
||||
- 分页仍按**工单条数**(与临时 Tab 一致)。
|
||||
|
||||
### 4.2 卡片标题行
|
||||
|
||||
在现有「工单状态 Tag」「触发来源 Tag」之前或之后,增加**质检类型 Tag**(见 §2.3)。
|
||||
|
||||
- 卡片主标题:统一使用 **工单号** `workOrderNo`(不再按入库/出库规则切换为入库编码或产品编码)。
|
||||
- `showTriggerTag`:保持 `true`(与分类 Tab 一致,展示样本接收/计划质检/生产过程等)。
|
||||
|
||||
### 4.3 卡片 meta 字段(按行动态)
|
||||
|
||||
根据 `resolveTabKeyFromWorkOrder(row)` 选取对应分类 Tab 的 `metaFields` 子集,**不整表复用**(避免出库 Tab 专有费用条等在「所有」Tab 误显)。
|
||||
|
||||
| 类型 | meta 字段(按顺序) |
|
||||
|------|---------------------|
|
||||
| 细胞存储 / 科研捐赠 | 质检对象、实验室入库编码、检测方式、创建时间 |
|
||||
| 中试服务 | 申请单号、申请单名称、患者姓名、输注时间、检测方式 |
|
||||
| 基础实验 | 申请单号、课题名称、客户名称、交付时间、检测方式 |
|
||||
| 临时 | 产品名称、产品编码、检测方式、创建时间 |
|
||||
|
||||
备注:有值时展示(沿用 `visible` 规则);协议费用条、出库费用条在「所有」Tab **不展示**(`showProtocolFeeSummary=false`,`showOutboundFeeSummary=false`)。
|
||||
|
||||
### 4.4 细胞产品区块
|
||||
|
||||
- 中试服务 / 基础实验行:若 `triggerSource=schedule` 或 `production`,按原 Tab 规则展示 `showCellProducts` 区块。
|
||||
- 其它类型:不展示细胞产品区块。
|
||||
|
||||
### 4.5 操作与查看弹窗
|
||||
|
||||
- manage:操作按钮规则按**行实际类型**的 `cardMetaConfig`(`allowEditTemporary`、`allowDelete` 等)动态判断。
|
||||
- mine:仅查看工单 + 任务操作(与现有一致)。
|
||||
- 查看弹窗:`QC_WORK_ORDER_VIEW_DIALOG_COMPONENTS[resolveTabKeyFromWorkOrder(row)]`。
|
||||
|
||||
---
|
||||
|
||||
## 5. 后端变更
|
||||
|
||||
### 5.1 跨类型关键词(必须)
|
||||
|
||||
`list_work_orders` 当 `work_order_type` 为空(「所有」+ 质检类型=全部)时,关键词应覆盖:
|
||||
|
||||
| 范围 | 匹配字段 |
|
||||
|------|----------|
|
||||
| 通用 | `work_order_no`、`sample_code` |
|
||||
| 入库 | `lab_storage_code`(经 reception 关联,现有逻辑) |
|
||||
| 出库 | 申请单号、申请单名称、患者、课题、客户(现有 `_outbound_qc_work_order_ids_by_keyword`) |
|
||||
| 临时 | `work_order_no`、关联生产工单号、细胞产品名称/编码(若已 enrich) |
|
||||
|
||||
实现:当 `wt` 为空时,关键词 OR 条件合并入库 + 出库 + 临时字段(与分别传 `outbound` 时行为一致)。
|
||||
|
||||
### 5.2 质检类型子筛选
|
||||
|
||||
无需新 API 字段;前端将 §3.5 映射为现有 `workOrderType` / `receptionSource` / `bizType` 查询参数。
|
||||
|
||||
### 5.3 时间筛选
|
||||
|
||||
「所有」Tab 仅传 `createTimeStart` / `createTimeEnd`;不传 `infusionTimeStart` / `infusionTimeEnd`。
|
||||
|
||||
### 5.4 我的任务 — mine 数据流
|
||||
|
||||
`tabKey=all` 时:
|
||||
|
||||
1. `fetchAllMineTasks` 不按 `workOrderType` 限制(或传全类型 union)。
|
||||
2. `filterMineEntriesByWorkOrderSearch`:`tabKey=all` 时跳过 `resolveTabKeyFromWorkOrder(row) !== tabKey` 校验;关键词/时间/工单状态/工单来源按行类型分别匹配(复用 `keywordMatchesWorkOrder` 时传入 `resolveTabKeyFromWorkOrder(row)`)。
|
||||
3. 质检类型子筛选:前端 filter `resolveTabKeyFromWorkOrder(row)` 与所选子类型一致。
|
||||
|
||||
---
|
||||
|
||||
## 6. 前端实现要点
|
||||
|
||||
### 6.1 工具与类型
|
||||
|
||||
- `QcWorkOrderTabKey` 增加 `'all'`。
|
||||
- `QC_WORK_ORDER_TABS` 首部插入 `all` 配置;`QC_WORK_ORDER_VISIBLE_TABS` 自动包含。
|
||||
- `DEFAULT_QC_WORK_ORDER_TAB` → `'all'`。
|
||||
- 新增 `qcWorkOrderCategoryLabel(row)` / `qcWorkOrderCategoryTagType(row)` 工具函数。
|
||||
- 新增 `getAllTabCardMetaForRow(row)` 或 `CARD_META_BY_TAB.all` + 行级 meta 解析。
|
||||
|
||||
### 6.2 组件
|
||||
|
||||
- 新增 `AllTab.vue`(或复用 `QcWorkOrderTabPanel` + `tabKey=all`)。
|
||||
- `QcWorkOrderSingleCard`:支持 `cardMetaConfig.tabKey === 'all'` 时按行解析 meta;标题行渲染类型 Tag。
|
||||
- `QcWorkOrderCardList`:`all` 时 `useGroupedList=false`;可选传入 `resolveCardMetaPerRow`。
|
||||
- `index.vue`(两页):Tab 列表改用含 `all` 的 visible tabs;默认 tab 解析更新。
|
||||
|
||||
### 6.3 注册表
|
||||
|
||||
- `tab-registry.ts`、`view-dialog-registry.ts`:`all` Tab 无独立 view dialog 组件;查看时按行 `resolveTabKeyFromWorkOrder` 动态选择(`QcWorkOrderTabPanel` 已有模式可扩展)。
|
||||
|
||||
---
|
||||
|
||||
## 7. 验收标准
|
||||
|
||||
1. 两页 Tab 栏首位为「所有」,默认进入「所有」Tab。
|
||||
2. 「所有」Tab 列表含 5 类工单,每条卡片有正确类型 Tag。
|
||||
3. 质检类型=全部时,关键词可搜到入库样本编码、出库申请单号、临时工单号。
|
||||
4. 质检类型子筛选后,列表仅含所选类型。
|
||||
5. 创建时间筛选在「所有」Tab 对所有类型按 `create_time` 生效。
|
||||
6. mine 页任务状态/任务类型筛选与现有一致,且与「所有」Tab 共用结构。
|
||||
7. 查看弹窗按工单实际类型打开正确 dialog。
|
||||
8. 分类 Tab 行为与改动前一致(回归)。
|
||||
|
||||
---
|
||||
|
||||
## 8. 已确认决策
|
||||
|
||||
| 问题 | 决策 |
|
||||
|------|------|
|
||||
| 两页是否都加「所有」? | **是** — 筛选结构一致;mine 页多任务状态/任务类型 |
|
||||
| 列表是否分组? | **否** — 平铺 standalone |
|
||||
| 「所有」Tab 时间字段? | **创建时间**;出库输注/交付时间留在分类 Tab |
|
||||
| 类型 Tag 文案? | 细胞存储 / 科研捐赠 / 中试服务 / 基础实验 / 临时 |
|
||||
| 默认 Tab? | **所有** |
|
||||
@@ -0,0 +1,261 @@
|
||||
# 入库质检工单 · 协议单多样本 Tab 分组 — 设计文档
|
||||
|
||||
> 日期:2026-06-25
|
||||
> 状态:已实现
|
||||
> 范围:`web-admin` 【质检工单】【我的质检任务】入库类 Tab;后端列表关键词补协议号
|
||||
> 关联:`2026-06-16-qc-work-order-tab-split-design.md`、`2026-06-25-qc-work-order-all-tab-design.md`、`2026-06-25-qc-inspection-batch-design.md`
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
### 1.1 问题
|
||||
|
||||
细胞存储质检、科研捐赠质检的工单均来自**采集协议单 / 科赠协议单**。一份协议单可含**多个样本**,每个样本接收后各生成至少一条质检工单(生产过程可再追加)。
|
||||
|
||||
现网列表按 **`sampleCode`(样本编码)** 分组:同一协议下的多个样本各自占一张卡片,协议号等信息在组头副标题重复出现,用户难以「按协议一眼看全样本质检进度」。
|
||||
|
||||
### 1.2 目标
|
||||
|
||||
在 **细胞存储质检**、**科研捐赠质检** 两个 Tab 中,将同一协议单下的多个样本**合并为一张协议组卡片**,组内用 **Tab 切换样本**;样本内仍保留现网 **触发来源 Tab**(样本接收 / 生产过程)。
|
||||
|
||||
【质检工单】与【我的质检任务】**共用**同一套列表组件与分组逻辑。
|
||||
|
||||
### 1.3 非目标
|
||||
|
||||
- 不改变出库、临时 Tab 的列表布局。
|
||||
- 不在 **「所有」** Tab 做协议分组(沿用平铺 + 类型 Tag,见 `2026-06-25-qc-work-order-all-tab-design.md` §1.3)。
|
||||
- 不合并细胞存储与科研捐赠(仍分 Tab)。
|
||||
- 不把同协议多样本压成**单层扁平卡片**(去掉样本层级)。
|
||||
- 本期不做「按协议分页」后端改造(分页仍按工单条数;见 §5.3 边界说明)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 列表信息架构
|
||||
|
||||
### 2.1 三层结构
|
||||
|
||||
```
|
||||
协议组(新增外层)
|
||||
└── 样本 Tab(新增中层)
|
||||
└── 触发来源 Tab(现网 QcWorkOrderSampleGroup 内层)
|
||||
└── 工单卡片 + 检测批次 + 任务
|
||||
```
|
||||
|
||||
### 2.2 分组键
|
||||
|
||||
| 层级 | 分组字段 | 回退 |
|
||||
|------|----------|------|
|
||||
| 协议 | `collectionProtocolId` | `(protocolNo).trim()`,仍空则用首条工单 `id` |
|
||||
| 样本 | `sampleCode` | 工单 `id` |
|
||||
| 工单 | 同样本下按 `triggerSource` Tab 切换 | 现网逻辑 |
|
||||
|
||||
说明:科赠工单的 `collectionProtocolId` 存的是 `research_donation_id`(后端建单已如此),与细胞存储共用分组字段名。
|
||||
|
||||
### 2.3 Tab 配置
|
||||
|
||||
`listLayout` **保持** `inbound-grouped`(语义扩展为「入库分组列表」,实现改为协议优先分组,不再在 `QcWorkOrderCardList` 顶层直接使用 `QcWorkOrderSampleGroup`)。
|
||||
|
||||
受影响 Tab:
|
||||
|
||||
| Tab Key | 展示标签 | 列表布局(实现) |
|
||||
|---------|----------|------------------|
|
||||
| `inbound_cell_storage` | 细胞存储质检 | 协议分组 + 样本 Tab |
|
||||
| `inbound_research_donation` | 科研捐赠质检 | 协议分组 + 样本 Tab |
|
||||
|
||||
---
|
||||
|
||||
## 3. UI 设计
|
||||
|
||||
### 3.1 协议组头(`qc-protocol-row__ctx`)
|
||||
|
||||
视觉对齐现网 `qc-sample-row__ctx`(绿渐变顶栏 + 序号)。
|
||||
|
||||
| 元素 | 细胞存储 | 科研捐赠 |
|
||||
|------|----------|----------|
|
||||
| 主标题 | 协议号 `protocolNo` | 捐赠单号 `protocolNo` |
|
||||
| 副标题 | 协议状态 Tag + `N 个样本` + 可选进度摘要 | 捐赠状态 Tag + `N 个样本` + 可选进度摘要 |
|
||||
| Badge | 组内工单总数(如 `5 条质检`) | 同左 |
|
||||
|
||||
**进度摘要(可选展示):** 如 `2/3 已配置`,按样本维度统计:该样本下存在 `workOrderStatus !== 'dpz'` 的 gate 工单(优先 `triggerSource=reception`,否则取组内首条)即计为「已配置样本」。无数据时不展示。
|
||||
|
||||
**协议费用条:** 仅 **细胞存储** Tab、且组内存在 `paymentSummary` 的工单时,在协议组头下方展示 **一次** `QcWorkOrderProtocolPaymentPanel`(compact),**不要**在每个样本 Tab 内重复。
|
||||
|
||||
### 3.2 样本 Tab 行(`qc-protocol-sample-tabs`)
|
||||
|
||||
- 样式复用现网 `qc-wo-indep-tabs__btn` / pill Tab(与 `QcWorkOrderSampleGroup` 触发来源 Tab 一致)。
|
||||
- **仅当组内样本数 ≥ 2** 时展示 Tab 行;**单样本**时隐藏 Tab 行,直接展示该样本工单区。
|
||||
|
||||
每个 Tab pill 文案:
|
||||
|
||||
| 部分 | 内容 |
|
||||
|------|------|
|
||||
| 序号 | `1` `2` `3`(圆点序号,与现网一致) |
|
||||
| 主文案 | 样本编码(monospace) |
|
||||
| 辅助 | 样本类型 `sampleTypeName`(有值时) |
|
||||
| 状态 | 该样本 gate 工单 `workOrderStatus` 的 `el-tag` |
|
||||
|
||||
Tab 排序:按样本编码字典序;同编码按 gate 工单 `createTime` ASC。
|
||||
|
||||
### 3.3 样本工单区
|
||||
|
||||
选中样本后渲染 **`QcWorkOrderSampleGroup`**,传入该样本下的 `workOrders` 子集,并增加 prop:
|
||||
|
||||
| Prop | 值 | 说明 |
|
||||
|------|-----|------|
|
||||
| `hideContextBar` | `true` | 隐藏原样本组头(协议组头 + 样本 Tab 已表达上下文) |
|
||||
| 其余 | 与现网一致 | 内层触发来源 Tab、卡片、批次、任务 |
|
||||
|
||||
单样本且仅 1 条工单时:无样本 Tab、无触发来源 Tab,直接展示 `QcWorkOrderSingleCard`。
|
||||
|
||||
### 3.4 线框(ASCII)
|
||||
|
||||
```
|
||||
┌─ 1 XY2026001 [协议进行中] 3 个样本 · 2/3 已配置 [5 条质检] ─┐
|
||||
│ [协议费用 compact — 仅细胞存储] │
|
||||
├─ 样本 Tab ───────────────────────────────────────────────────────┤
|
||||
│ [1 A001·脐带血·待配置] [2 A002·胎盘·已配置] [3 B003·进行中] │
|
||||
├─ 触发来源 Tab(样本 A001 有 2 条工单时)───────────────────────────┤
|
||||
│ [样本接收 ZJ…] [生产过程 ZJ…] │
|
||||
├─ 工单 meta + 检测批次 + 任务 ─────────────────────────────────────┤
|
||||
└───────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 前端实现要点
|
||||
|
||||
### 4.1 新增工具(`web-admin/src/utils/qc-work-order-groups.ts`)
|
||||
|
||||
```typescript
|
||||
export type QcWorkOrderProtocolGroupModel = {
|
||||
groupKey: string
|
||||
protocolId: string
|
||||
protocolNo: string
|
||||
receptionSource: 'cell_storage' | 'research_donation'
|
||||
sampleGroups: QcWorkOrderSampleGroupModel[]
|
||||
workOrders: QcWorkOrder[] // 组内全部工单(扁平)
|
||||
}
|
||||
|
||||
export function groupInboundQcWorkOrdersByProtocol(
|
||||
rows: QcWorkOrder[]
|
||||
): QcWorkOrderProtocolGroupModel[]
|
||||
```
|
||||
|
||||
实现步骤:
|
||||
|
||||
1. 按 `collectionProtocolId`(及回退键)聚合工单。
|
||||
2. 每组内调用现有 `groupInboundQcWorkOrders` 得到 `sampleGroups`。
|
||||
3. 协议组排序:组内最新工单 `createTime DESC`(与列表默认排序一致)。
|
||||
|
||||
### 4.2 新增组件
|
||||
|
||||
**`QcWorkOrderProtocolGroup.vue`**
|
||||
|
||||
- Props / Emits 与 `QcWorkOrderSampleGroup` 对齐(`configure` / `view` / `command` / `tasks-changed`)。
|
||||
- 内含样本 Tab 状态 `activeSampleKey`(`sampleCode` 或回退 `id`)。
|
||||
- 渲染选中样本的 `QcWorkOrderSampleGroup`(`hideContextBar=true`)。
|
||||
|
||||
### 4.3 修改组件
|
||||
|
||||
| 文件 | 变更 |
|
||||
|------|------|
|
||||
| `QcWorkOrderSampleGroup.vue` | 新增 `hideContextBar?: boolean`,为 true 时不渲染 `qc-sample-row__ctx` |
|
||||
| `QcWorkOrderCardList.vue` | `cardMetaUsesInboundGroups` 时渲染 `QcWorkOrderProtocolGroup` 而非直接 `QcWorkOrderSampleGroup` |
|
||||
| `qc-work-order-card-meta.ts` | 新增 `buildProtocolGroupContextSubtitle(group)`;细胞存储/捐赠分别用协议/捐赠文案 |
|
||||
|
||||
### 4.4 「所有」Tab
|
||||
|
||||
**不变。** `buildAllTabListItems` 中 inbound 仍可按样本合并(或维持现状);本需求不修改 `all` Tab 布局。
|
||||
|
||||
### 4.5 我的质检任务
|
||||
|
||||
与 manage 共用 `QcWorkOrderCardList` + 协议分组;`pageMode='mine'` 时卡片仅查看、任务区 `taskListMode='mine'`。
|
||||
|
||||
前端 mine 关键词过滤补充 `protocolNo` 字段(`qc-mine-task-groups.ts` → `keywordMatchesWorkOrder`,inbound 组)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 后端变更
|
||||
|
||||
### 5.1 列表关键词 — 协议号(必须)
|
||||
|
||||
`list_work_orders` 在现有关键词 OR 条件中增加:
|
||||
|
||||
```python
|
||||
BizQcWorkOrder.protocol_no.like(like)
|
||||
```
|
||||
|
||||
适用于入库类及「所有」Tab 跨类型搜索。
|
||||
|
||||
### 5.2 筛选 placeholder
|
||||
|
||||
入库 Tab 关键词 placeholder 更新为:
|
||||
|
||||
`工单号/协议号/样本编码/入库编码`
|
||||
|
||||
(细胞存储写「协议号」,科研捐赠写「捐赠单号」——按 Tab 文案区分。)
|
||||
|
||||
### 5.3 分页边界
|
||||
|
||||
- 分页单位仍为 **工单条数**(`pageSize` 默认 100)。
|
||||
- 同一协议多样本可能**跨页**:当前页仅展示本页工单所属的样本 Tab;未出现在本页的样本不出 Tab。**可接受**,二期可选「按协议 ID 拉全量样本工单再分组」(非本期)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 与检测批次的关系
|
||||
|
||||
检测批次在 **工单卡片内部**(`QcWorkOrderBatchSubList`),与协议/样本分组**正交**:
|
||||
|
||||
```
|
||||
协议 → 样本 Tab → 触发来源 Tab → 工单 → 批次 → 任务
|
||||
```
|
||||
|
||||
本需求不修改批次配置 API 与 UI。
|
||||
|
||||
---
|
||||
|
||||
## 7. 验收标准
|
||||
|
||||
1. 【质检工单】细胞存储 / 科研捐赠 Tab:同一 `collectionProtocolId` 下多样本合并为 **一张协议组卡片**。
|
||||
2. 协议组内 **样本 Tab** 可切换;切换后展示对应样本工单与任务。
|
||||
3. 同样本多工单(接收 + 生产)仍显示 **触发来源 Tab**,行为与改动前一致。
|
||||
4. 单样本协议组 **不显示** 样本 Tab 行,直接展示工单区。
|
||||
5. 细胞存储协议组 **协议费用条** 组级展示一次;科研捐赠不展示费用条。
|
||||
6. 【我的质检任务】同上,且仅查看 + 任务操作。
|
||||
7. 关键词输入协议号 / 捐赠单号可筛出该协议下全部相关工单。
|
||||
8. 「所有」Tab、出库 Tab、临时 Tab 列表行为 **回归不变**。
|
||||
9. 配置检测 / 调整检测 / 查看弹窗 **回归不变**。
|
||||
|
||||
---
|
||||
|
||||
## 8. 已确认决策
|
||||
|
||||
| 问题 | 决策 |
|
||||
|------|------|
|
||||
| 是否按协议合并多样本? | **是** |
|
||||
| 样本切换交互? | **Tab(pill)**,复用现网触发来源 Tab 样式 |
|
||||
| 单样本是否仍显示 Tab? | **否**,隐藏样本 Tab 行 |
|
||||
| 两页是否一致? | **是** |
|
||||
| 「所有」Tab 是否协议分组? | **否** |
|
||||
| 分页是否改为按协议? | **否**(本期) |
|
||||
| 协议费用条位置? | **协议组头一次**(仅细胞存储) |
|
||||
|
||||
---
|
||||
|
||||
## 9. 实现阶段建议
|
||||
|
||||
| 阶段 | 内容 | 预估 |
|
||||
|------|------|------|
|
||||
| P1 | `groupInboundQcWorkOrdersByProtocol` + `QcWorkOrderProtocolGroup` + SampleGroup `hideContextBar` | 1~1.5 人天 |
|
||||
| P2 | CardList 接入 + card-meta 协议组头 + placeholder | 0.5 人天 |
|
||||
| P3 | 后端 `protocol_no` 关键词 + mine 前端关键词 | 0.5 人天 |
|
||||
| P4 | 两页联调、回归六 Tab + 所有 Tab | 0.5~1 人天 |
|
||||
| **合计** | | **2.5~3.5 人天** |
|
||||
|
||||
---
|
||||
|
||||
## 10. 下一步
|
||||
|
||||
1. 评审本文档 — 无遗漏后进入实现计划(`writing-plans` → `docs/superpowers/plans/`)。
|
||||
2. 可选:同步 OpenSpec capability `qc-work-order-protocol-group`(与 `ui-conventions` 卡片分组约定对齐)。
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-06-25
|
||||
@@ -0,0 +1,36 @@
|
||||
# 质检检测批次 — 技术设计
|
||||
|
||||
权威产品决策见 `docs/superpowers/specs/2026-06-25-qc-inspection-batch-design.md`。
|
||||
|
||||
## 架构
|
||||
|
||||
工单 → `biz_qc_work_order_inspection_batch` → lab/third 明细(`batch_id`)→ `biz_qc_task` → `biz_qc_task_assignee`(从 `biz_qc_batch_assignee` 同步)。
|
||||
|
||||
批次无状态字段;进度由任务聚合。
|
||||
|
||||
## 数据表
|
||||
|
||||
- `biz_qc_work_order_inspection_batch`
|
||||
- `biz_qc_batch_assignee`
|
||||
- `biz_qc_work_order_lab_item.batch_id`
|
||||
- `biz_qc_work_order_third_item.batch_id`
|
||||
- 可选 `biz_qc_task.batch_id` 冗余
|
||||
|
||||
## API
|
||||
|
||||
- `POST /qc-work-orders/{id}/configure` — body `batches[]`;扁平 `labItemIds` 兼容为单批次
|
||||
- `GET /qc-work-orders/{id}/inspection-batches` — 批次 + tasks 嵌套
|
||||
|
||||
## 同步策略
|
||||
|
||||
按批次 ID 比对:增删改 lab/third 行;任务 assignee 调用 `sync_assignees_for_task` 与批次负责人一致。
|
||||
|
||||
## 前端
|
||||
|
||||
- `index.vue` 配置弹窗:批次卡片
|
||||
- `QcWorkOrderBatchSubList.vue`:折叠批次 + 内嵌任务卡片
|
||||
- `qc-mine-task-groups.ts`:工单下按批次分组
|
||||
|
||||
## 迁移
|
||||
|
||||
SQL 脚本为每个已配置工单创建 `B01` 默认批次并回填 `batch_id`。
|
||||
@@ -0,0 +1,31 @@
|
||||
## Why
|
||||
|
||||
质检工单配置检测时,每个检测主数据项目在同一工单内只能选一次,负责人需按项目逐一指派,列表平铺展示任务,无法满足客户「多批次、跨批重复项目、批次级负责人」的质检组织方式。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 新增 **检测批次** 实体:工单下可配置多个批次,`ypz` 后可追加批次
|
||||
- 批次内可选 lab + 第三方项目(批次内不重复,跨批次可重复同一主数据项目)
|
||||
- **批次级多人负责人**,同步至批次内全部任务的 `biz_qc_task_assignee`
|
||||
- **BREAKING**:配置检测 API 请求体改为 `batches[]`(保留扁平字段短期兼容转单批次)
|
||||
- 新增 `GET /qc-work-orders/{id}/inspection-batches` 供列表展开
|
||||
- 配置/调整检测弹窗改为批次卡片 UI
|
||||
- 质检工单、我的质检任务:列表先展示批次,展开后展示检测项目/任务
|
||||
- DDL + 历史数据迁移(默认批次 1)
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `qc-inspection-batch`: 检测批次数据模型、配置/调整 API、批次列表 API、迁移与任务 assignee 同步
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
(无 `openspec/specs/` 基线;行为变更记录于本变更 spec)
|
||||
|
||||
## Impact
|
||||
|
||||
- **后端**:`models.py`、`qc_work_order.py`、`qc.py` API;新 `qc_inspection_batch.py` CRUD
|
||||
- **SQL**:`docs/sql/` 新表 + alter + 迁移脚本
|
||||
- **前端**:`qc-work-order/index.vue` 配置弹窗、`QcWorkOrderTaskSubList` / 新 `QcWorkOrderBatchSubList`、`qc-mine-task-groups.ts`、`qc-work-order.ts` API
|
||||
- **文档**:`docs/superpowers/specs/2026-06-25-qc-inspection-batch-design.md` 为实现权威
|
||||
@@ -0,0 +1,51 @@
|
||||
### Requirement: 检测批次数据模型
|
||||
|
||||
系统 SHALL 提供 `biz_qc_work_order_inspection_batch` 与 `biz_qc_batch_assignee` 表;lab/third 明细表 SHALL 包含 `batch_id` 外键。
|
||||
|
||||
#### Scenario: 新建批次
|
||||
|
||||
- **WHEN** 用户在 `dpz` 或 `ypz` 工单上提交配置且包含新批次
|
||||
- **THEN** 系统创建批次记录,`batch_no` 为 `{work_order_no}-Bnn`,`batch_name` 为 `YYYYMMDD检测`(同日多批递增 `-2` 后缀)
|
||||
|
||||
### Requirement: 批次内项目唯一与跨批重复
|
||||
|
||||
系统 SHALL 允许同一 `lab_test_item_id` / `third_party_item_id` 出现在同一工单的不同批次;同一批次内 SHALL NOT 重复同一主数据项目 ID。
|
||||
|
||||
#### Scenario: 批次内重复项目
|
||||
|
||||
- **WHEN** 提交的配置在同一批次 lab 列表含重复 ID
|
||||
- **THEN** 返回 400 校验错误
|
||||
|
||||
### Requirement: 批次负责人
|
||||
|
||||
每个批次 SHALL 配置至少一名负责人(多名允许);配置保存时 SHALL 将该负责人集合同步至批次内全部未删除任务的 `biz_qc_task_assignee`。
|
||||
|
||||
#### Scenario: 修改批次负责人
|
||||
|
||||
- **WHEN** 调整检测修改某批次负责人
|
||||
- **THEN** 该批次下所有任务 assignee 更新,「我的质检任务」对新负责人可见
|
||||
|
||||
### Requirement: 配置检测 API
|
||||
|
||||
`POST /web/admin/qc-work-orders/{id}/configure` SHALL 接受 `batches[]`;每批含 `assigneeUserIds`、`hasLab`、`hasThirdParty`、`labItemIds`、`thirdPartyItemIds`。`dpz` 首次配置后工单状态为 `ypz`;`ypz` 可追加批次。
|
||||
|
||||
### Requirement: 批次列表 API
|
||||
|
||||
`GET /web/admin/qc-work-orders/{id}/inspection-batches` SHALL 返回批次列表,每项含 `tasks` 嵌套(结构与任务列表项一致)及 `taskCount` / `completedTaskCount`。
|
||||
|
||||
### Requirement: 列表 UI 批次层级
|
||||
|
||||
质检工单与我的质检任务页面 SHALL 在工单展开区先展示检测批次,展开批次后展示检测项目任务卡片;任务级操作(开始、填写结果)不变。
|
||||
|
||||
### Requirement: 只读质检信息批次展示
|
||||
|
||||
协议单/捐赠单/入库放行/出库放行等查看弹窗中的质检信息、以及质检工单「查看」弹窗 SHALL 按检测批次分组展示任务;多批次时以 Tab 或分节展示批次名、批次编号、负责人与进度。
|
||||
|
||||
#### Scenario: 协议样本卡质检信息
|
||||
|
||||
- **WHEN** 用户在协议单查看弹窗打开含多批次质检工单的样本卡
|
||||
- **THEN** 质检信息区按批次 Tab 展示各批任务摘要,可跳转任务详情
|
||||
|
||||
### Requirement: 详情内嵌 inspectionBatches
|
||||
|
||||
工单详情、`qcInfo`(样本关联摘要)、出库质检详情 SHALL 可选内嵌 `inspectionBatches` 字段,结构与 `GET .../inspection-batches` 一致,以减少前端重复请求。
|
||||
@@ -0,0 +1,36 @@
|
||||
# Tasks: qc-inspection-batch
|
||||
|
||||
## 1. Database & Models
|
||||
|
||||
- [x] 1.1 `docs/sql/qc_inspection_batch.sql` — 新表 + alter `batch_id` + 数据迁移
|
||||
- [x] 1.2 `models.py` — `BizQcWorkOrderInspectionBatch`、`BizQcBatchAssignee`;明细/任务 `batch_id`
|
||||
- [x] 1.3 更新 `待同步到生产的sql脚本`;`migrate_qc_inspection_batch_data.sql` 历史迁移
|
||||
- [ ] 1.4 合并到 `docs/sql/zkxw.sql` 全量基线(待下次库导出)
|
||||
|
||||
## 2. Backend
|
||||
|
||||
- [x] 2.1 `crud/qc_inspection_batch.py` — 批次 CRUD、同步 lab/third、assignee、configure
|
||||
- [x] 2.2 `configure_work_order` 改为批次数组;扁平 body 兼容单批
|
||||
- [x] 2.3 `GET /qc-work-orders/{id}/inspection-batches`
|
||||
- [x] 2.4 工单详情 / qcInfo / outbound-detail 内嵌 `inspectionBatches`
|
||||
|
||||
## 3. Frontend — 配置弹窗
|
||||
|
||||
- [x] 3.1 `qc-work-order.ts` / `qc-inspection-batch.ts` — 类型与 API
|
||||
- [x] 3.2 `QcWorkOrderConfigureBatches.vue` + `index.vue` 批次卡片配置 UI
|
||||
- [x] 3.3 校验:批次负责人、批次内不重复、至少一项检测
|
||||
|
||||
## 4. Frontend — 列表与只读展示
|
||||
|
||||
- [x] 4.1 `QcWorkOrderBatchSubList.vue`
|
||||
- [x] 4.2 `QcWorkOrderSingleCard` 改用批次列表(SampleGroup 经 SingleCard 继承)
|
||||
- [x] 4.3 我的任务:`QcWorkOrderBatchSubList` 按 `batchId` 分组 preset 任务
|
||||
- [x] 4.4 `SampleQcBatchReadonly` + `SampleQcInfoCards` 批次 Tab(协议/捐赠/放行等查看弹窗)
|
||||
- [x] 4.5 工单查看弹窗六 Tab:`QcWorkOrderSystemViewDialog` 按批次分节
|
||||
- [x] 4.6 任务详情弹窗补充「检测批次」字段;`loadQcInspectionBatches` 优先内嵌数据
|
||||
|
||||
## 5. Verification
|
||||
|
||||
- [ ] 5.1 执行迁移 SQL(本地)
|
||||
- [ ] 5.2 手工验收:双批次、跨批重复项目、追加批次、我的任务可见性
|
||||
- [ ] 5.3 手工验收:协议单/放行查看弹窗质检信息按批次展示;工单查看弹窗批次分节
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,11 +1,11 @@
|
||||
# Graph Report - src (2026-06-25)
|
||||
# Graph Report - src (2026-06-26)
|
||||
|
||||
## Corpus Check
|
||||
- Large corpus: 792 files · ~529,390 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
|
||||
- Large corpus: 811 files · ~539,420 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
|
||||
|
||||
## Summary
|
||||
- 2624 nodes · 3636 edges · 53 communities detected
|
||||
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 785 edges (avg confidence: 0.8)
|
||||
- 2705 nodes · 3770 edges · 58 communities detected
|
||||
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 825 edges (avg confidence: 0.8)
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Community Hubs (Navigation)
|
||||
@@ -45,57 +45,62 @@
|
||||
- [[_COMMUNITY_Community 33|Community 33]]
|
||||
- [[_COMMUNITY_Community 34|Community 34]]
|
||||
- [[_COMMUNITY_Community 35|Community 35]]
|
||||
- [[_COMMUNITY_Community 36|Community 36]]
|
||||
- [[_COMMUNITY_Community 37|Community 37]]
|
||||
- [[_COMMUNITY_Community 38|Community 38]]
|
||||
- [[_COMMUNITY_Community 39|Community 39]]
|
||||
- [[_COMMUNITY_Community 40|Community 40]]
|
||||
- [[_COMMUNITY_Community 41|Community 41]]
|
||||
- [[_COMMUNITY_Community 42|Community 42]]
|
||||
- [[_COMMUNITY_Community 43|Community 43]]
|
||||
- [[_COMMUNITY_Community 44|Community 44]]
|
||||
- [[_COMMUNITY_Community 45|Community 45]]
|
||||
- [[_COMMUNITY_Community 48|Community 48]]
|
||||
- [[_COMMUNITY_Community 49|Community 49]]
|
||||
- [[_COMMUNITY_Community 50|Community 50]]
|
||||
- [[_COMMUNITY_Community 52|Community 52]]
|
||||
- [[_COMMUNITY_Community 53|Community 53]]
|
||||
- [[_COMMUNITY_Community 54|Community 54]]
|
||||
- [[_COMMUNITY_Community 55|Community 55]]
|
||||
- [[_COMMUNITY_Community 56|Community 56]]
|
||||
- [[_COMMUNITY_Community 57|Community 57]]
|
||||
- [[_COMMUNITY_Community 58|Community 58]]
|
||||
- [[_COMMUNITY_Community 63|Community 63]]
|
||||
- [[_COMMUNITY_Community 65|Community 65]]
|
||||
- [[_COMMUNITY_Community 60|Community 60]]
|
||||
- [[_COMMUNITY_Community 64|Community 64]]
|
||||
- [[_COMMUNITY_Community 66|Community 66]]
|
||||
- [[_COMMUNITY_Community 72|Community 72]]
|
||||
- [[_COMMUNITY_Community 73|Community 73]]
|
||||
|
||||
## God Nodes (most connected - your core abstractions)
|
||||
1. `get()` - 268 edges
|
||||
2. `push()` - 64 edges
|
||||
3. `emit()` - 27 edges
|
||||
1. `get()` - 275 edges
|
||||
2. `push()` - 70 edges
|
||||
3. `emit()` - 31 edges
|
||||
4. `WebSocketClient` - 26 edges
|
||||
5. `MenuProcessor` - 16 edges
|
||||
6. `handleDynamicRoutes()` - 16 edges
|
||||
7. `withFullscreenLoading()` - 15 edges
|
||||
8. `VersionManager` - 15 edges
|
||||
9. `scopeQuery()` - 15 edges
|
||||
10. `set()` - 15 edges
|
||||
5. `handleDynamicRoutes()` - 18 edges
|
||||
6. `set()` - 17 edges
|
||||
7. `MenuProcessor` - 16 edges
|
||||
8. `withFullscreenLoading()` - 15 edges
|
||||
9. `VersionManager` - 15 edges
|
||||
10. `scopeQuery()` - 15 edges
|
||||
|
||||
## Surprising Connections (you probably didn't know these)
|
||||
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
|
||||
views/basic-info/customer/index.vue → utils/fullscreen-loading.ts
|
||||
- `buildInboundMetaFields()` --calls--> `push()` [INFERRED]
|
||||
utils/production-work-order-card-meta.ts → views/operations/storage-facility/index.vue
|
||||
- `subscribeTokenRefresh()` --calls--> `push()` [INFERRED]
|
||||
utils/http/index.ts → views/operations/storage-facility/index.vue
|
||||
- `handleUnauthorizedResponse()` --calls--> `fetchRefreshToken()` [INFERRED]
|
||||
utils/http/index.ts → api/auth.ts
|
||||
- `fetchLeaveList()` --calls--> `get()` [INFERRED]
|
||||
api/leave.ts → views/production/process/ProcessRouteTab.vue
|
||||
- `fetchLeaveDetail()` --calls--> `get()` [INFERRED]
|
||||
api/leave.ts → views/production/process/ProcessRouteTab.vue
|
||||
- `fmtMoney()` --calls--> `formatMoneyDisplay()` [INFERRED]
|
||||
components/business/clinical-schedule-payment-detail/index.vue → utils/money-format.ts
|
||||
- `formatAmount()` --calls--> `formatMoneyDisplay()` [INFERRED]
|
||||
views/pilot-service/clinical-payment-confirm/RefundConfirmTab.vue → utils/money-format.ts
|
||||
- `defaultInstallmentRatios()` --calls--> `push()` [INFERRED]
|
||||
utils/protocol-payment-installment.ts → views/operations/storage-facility/index.vue
|
||||
|
||||
## Communities
|
||||
|
||||
### Community 0 - "Community 0"
|
||||
Cohesion: 0.01
|
||||
Nodes (134): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchChannelAccount(), fetchChannelAgreementPrices(), fetchChannelAgreements() (+126 more)
|
||||
Nodes (137): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchChannelAccount(), fetchChannelAgreementPrices(), fetchChannelAgreements() (+129 more)
|
||||
|
||||
### Community 1 - "Community 1"
|
||||
Cohesion: 0.03
|
||||
Nodes (70): fetchCellSampleTypeList(), fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionList(), fetchCheckupInstitutionProjects(), fetchCreateCellSampleType(), fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchCreateCheckupInstitutionProject() (+62 more)
|
||||
Cohesion: 0.02
|
||||
Nodes (86): fetchUploadAttachment(), fetchMyProductionTasks(), fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), handleReportUpload(), handleReportUpload(), walk() (+78 more)
|
||||
|
||||
### Community 2 - "Community 2"
|
||||
Cohesion: 0.02
|
||||
@@ -103,244 +108,266 @@ Nodes (42): fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllConsumable
|
||||
|
||||
### Community 3 - "Community 3"
|
||||
Cohesion: 0.03
|
||||
Nodes (33): fetchGetMenuList(), ComponentLoader, IframeRouteManager, MenuProcessor, RouteRegistry, RouteTransformer, useAppMode(), useAuth() (+25 more)
|
||||
Nodes (54): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), handleBatchDelete(), handleDelete(), handleDropdownCommand() (+46 more)
|
||||
|
||||
### Community 4 - "Community 4"
|
||||
Cohesion: 0.03
|
||||
Nodes (44): handleBlur(), handleFocus(), handleInput(), formatAmount(), formatAmount(), formatProtocolAmount(), fmtMoney(), buildBaseFields() (+36 more)
|
||||
Nodes (33): fetchGetMenuList(), ComponentLoader, IframeRouteManager, MenuProcessor, RouteRegistry, RouteTransformer, useAppMode(), useAuth() (+25 more)
|
||||
|
||||
### Community 5 - "Community 5"
|
||||
Cohesion: 0.03
|
||||
Nodes (56): handleBlur(), handleFocus(), handleInput(), fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList() (+48 more)
|
||||
|
||||
### Community 6 - "Community 6"
|
||||
Cohesion: 0.03
|
||||
Nodes (52): fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionList(), fetchCheckupInstitutionProjects(), fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchCreateCheckupInstitutionProject(), fetchUpdateCheckupInstitution(), fetchUpdateCheckupInstitutionInvoice() (+44 more)
|
||||
|
||||
### Community 7 - "Community 7"
|
||||
Cohesion: 0.04
|
||||
Nodes (72): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchPilotCheckupDetail(), markPilotCheckupChecked(), savePilotCheckup(), savePilotCheckupActualItems() (+64 more)
|
||||
|
||||
### Community 6 - "Community 6"
|
||||
Cohesion: 0.04
|
||||
Nodes (53): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), fetchProductionTaskList(), handleAdd(), handleDelete() (+45 more)
|
||||
|
||||
### Community 7 - "Community 7"
|
||||
Cohesion: 0.05
|
||||
Nodes (57): fetchUploadAttachment(), FireworkSystem, handleReportUpload(), handleReportUpload(), walk(), async(), handleAttachmentChange(), push() (+49 more)
|
||||
|
||||
### Community 8 - "Community 8"
|
||||
Cohesion: 0.04
|
||||
Nodes (42): fetchMyProductionTasks(), fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), for(), set(), annotateForkEdges(), chainApiToElements() (+34 more)
|
||||
Nodes (35): fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed(), fetchClinicalRefundPending(), fetchOrderAdjusts(), fetchOrderDetail() (+27 more)
|
||||
|
||||
### Community 9 - "Community 9"
|
||||
Cohesion: 0.04
|
||||
Nodes (44): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList(), fetchCreateProtocolInvoiceRequest(), fetchInvoiceEligiblePayments(), fetchPaymentDetailList() (+36 more)
|
||||
Cohesion: 0.05
|
||||
Nodes (33): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), if(), walk() (+25 more)
|
||||
|
||||
### Community 10 - "Community 10"
|
||||
Cohesion: 0.04
|
||||
Nodes (37): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchRoleOptions(), fetchUpdateMenu(), collectIds(), buildInboundBasicSection(), buildInboundCellStorageViewSections() (+29 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (38): buildBaseFields(), buildFeeSection(), buildInboundBasicSection(), buildInboundCellStorageProductionViewSections(), buildInboundResearchDonationProductionViewSections(), buildOutboundBasicExperimentProductionViewSections(), buildOutboundClinicalProductionViewSections(), buildOutboundDetail() (+30 more)
|
||||
|
||||
### Community 11 - "Community 11"
|
||||
Cohesion: 0.04
|
||||
Nodes (36): fetchAttachmentDownloadUrl(), qcAttachmentFullUrl(), qcDownloadAttachment(), qcPreviewAttachment(), handleDownloadAttachment(), attachmentFullUrl(), handleAttachmentDownload(), handleAttachmentPreview() (+28 more)
|
||||
|
||||
### Community 12 - "Community 12"
|
||||
Cohesion: 0.05
|
||||
Nodes (34): fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed(), fetchClinicalRefundPending(), fetchOrderAdjusts(), fetchOrderDetail() (+26 more)
|
||||
|
||||
### Community 13 - "Community 13"
|
||||
Cohesion: 0.05
|
||||
Nodes (31): fetchDeleteQcMaterialBatch(), fetchQcMaterialBatchList(), fetchQcMaterialBatchOptions(), fetchQcMaterialList(), fetchQcMaterialOptions(), fetchUpdateQcMaterialBatch(), fetchMarkQcMaterialUsageFullyUsed(), fetchMyQcMaterialUsageList() (+23 more)
|
||||
|
||||
### Community 14 - "Community 14"
|
||||
Cohesion: 0.06
|
||||
Nodes (11): fetchGetLatestUpgradeLog(), getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager (+3 more)
|
||||
|
||||
### Community 15 - "Community 15"
|
||||
### Community 12 - "Community 12"
|
||||
Cohesion: 0.05
|
||||
Nodes (30): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), collectAllPostBindDeptIds(), collectPostBindDeptSubtreeIds() (+22 more)
|
||||
Nodes (35): fetchAttachmentDownloadUrl(), qcAttachmentFullUrl(), qcDownloadAttachment(), qcPreviewAttachment(), handleDownloadAttachment(), attachmentFullUrl(), handleAttachmentDownload(), handleAttachmentPreview() (+27 more)
|
||||
|
||||
### Community 16 - "Community 16"
|
||||
### Community 13 - "Community 13"
|
||||
Cohesion: 0.06
|
||||
Nodes (36): fetchUserList(), fetchAddTaskStep(), fetchCopyTaskStep(), fetchDeleteTaskStep(), fetchDispatchProductionTaskSteps(), fetchForwardProductionTask(), fetchProductionTaskDetail(), fetchReassignProductionTask() (+28 more)
|
||||
Nodes (37): fetchUserList(), fetchAddTaskStep(), fetchCopyTaskStep(), fetchDeleteTaskStep(), fetchDispatchProductionTaskSteps(), fetchForwardProductionTask(), fetchProductionTaskDetail(), fetchProductionTaskList() (+29 more)
|
||||
|
||||
### Community 17 - "Community 17"
|
||||
### Community 14 - "Community 14"
|
||||
Cohesion: 0.05
|
||||
Nodes (13): fmtMoney(), auditorDisplay(), dash(), ensureUnitsInOptions(), expressName(), formatYm(), formatYmd(), sampleTypeName() (+5 more)
|
||||
|
||||
### Community 15 - "Community 15"
|
||||
Cohesion: 0.04
|
||||
Nodes (21): fetchAvailableMaterialBatches(), fetchMyProductionMaterialConsumptions(), fetchMyProductionMaterialUsageList(), fetchProductionMaterialBatchList(), fetchProductionMaterialBatchOptions(), fetchProductionMaterialConsumptions(), fetchProductionMaterialFormula(), fetchProductionMaterialLinkedStepUsages() (+13 more)
|
||||
|
||||
### Community 16 - "Community 16"
|
||||
Cohesion: 0.09
|
||||
Nodes (41): applyFqParamsChange(), buildFqAmounts(), countByStatus(), evaluateFqParamsChange(), formatMoneySummary(), generateInitialFqDetails(), getPaidInstallmentRows(), isSameFqParams() (+33 more)
|
||||
|
||||
### Community 17 - "Community 17"
|
||||
Cohesion: 0.06
|
||||
Nodes (25): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchRoleOptions(), fetchUpdateMenu(), collectIds(), postorder(), preorder() (+17 more)
|
||||
|
||||
### Community 18 - "Community 18"
|
||||
Cohesion: 0.06
|
||||
Nodes (20): fetchQcMaterialBatchList(), fetchQcMaterialBatchOptions(), fetchQcMaterialList(), fetchQcMaterialOptions(), fetchUpdateQcMaterialBatch(), fetchMarkQcMaterialUsageFullyUsed(), financeAttachmentsToUrlString(), ensureTabMounted() (+12 more)
|
||||
|
||||
### Community 19 - "Community 19"
|
||||
Cohesion: 0.1
|
||||
Nodes (2): WebSocketClient, TableCache
|
||||
|
||||
### Community 19 - "Community 19"
|
||||
Cohesion: 0.08
|
||||
Nodes (32): toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes() (+24 more)
|
||||
|
||||
### Community 20 - "Community 20"
|
||||
Cohesion: 0.07
|
||||
Nodes (18): buildInboundBasicSection(), buildInboundCellStorageViewSections(), buildInboundResearchDonationViewSections(), buildReceptionSection(), buildTransportSection(), formatCheckResults(), formatMetric(), appendTaskResultSections() (+10 more)
|
||||
|
||||
### Community 21 - "Community 21"
|
||||
Cohesion: 0.09
|
||||
Nodes (31): base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes(), sha256Hex() (+23 more)
|
||||
|
||||
### Community 22 - "Community 22"
|
||||
Cohesion: 0.08
|
||||
Nodes (27): fetchUserOptions(), fetchSampleReceptionCheckItemList(), fetchSampleReceptionCheckItemsActive(), fetchAllocateLabStorageCodes(), fetchSampleReceptionBySampleCode(), fetchSampleReceptionDetail(), fetchSampleReceptionPendingList(), fetchSampleReceptionReceivedList() (+19 more)
|
||||
|
||||
### Community 21 - "Community 21"
|
||||
Cohesion: 0.08
|
||||
Nodes (20): maskIdCard(), buildBasicExperimentApplicationFields(), buildDefaultApplicationFields(), buildOutboundPilotContextSections(), applicationStatusLabel(), applicationStatusTagType(), cellProductStatusLabel(), cellProductStatusTagType() (+12 more)
|
||||
|
||||
### Community 22 - "Community 22"
|
||||
### Community 23 - "Community 23"
|
||||
Cohesion: 0.07
|
||||
Nodes (17): fetchEthnicList(), applyDonationBundleToForm(), createEmptyTransport(), ensureEthnicOptionInList(), handleOpenForAdd(), loadEthnicOptions(), normalizeSampleRow(), resetForm() (+9 more)
|
||||
|
||||
### Community 23 - "Community 23"
|
||||
### Community 24 - "Community 24"
|
||||
Cohesion: 0.09
|
||||
Nodes (27): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), handleBatchComplete(), handleBatchStart(), handleBatchVoid() (+19 more)
|
||||
|
||||
### Community 24 - "Community 24"
|
||||
### Community 25 - "Community 25"
|
||||
Cohesion: 0.07
|
||||
Nodes (16): fetchDeleteMaterialBatch(), fetchMaterialBatchList(), fetchMaterialBatchOptions(), fetchMaterialList(), fetchMaterialOptions(), fetchUpdateMaterialBatch(), fetchMaterialUsageList(), fetchMyMaterialUsageList() (+8 more)
|
||||
|
||||
### Community 25 - "Community 25"
|
||||
Cohesion: 0.08
|
||||
Nodes (12): fetchCreateProductionWorkOrder(), fetchProductionWorkOrderCellProductOptions(), fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList(), fetchProductionWorkOrderQcDispatchOptions(), reload(), handleMenuJump(), openExternalLink() (+4 more)
|
||||
|
||||
### Community 26 - "Community 26"
|
||||
Cohesion: 0.1
|
||||
Nodes (28): fetchCellProductSpecList(), fetchCellProductTypeList(), fetchMaxPassageProductSeq(), handleAdd(), resetForm(), applyProductCodeToLines(), calcExpiryFromFreeze(), createEmptyProductLine() (+20 more)
|
||||
|
||||
### Community 27 - "Community 27"
|
||||
Cohesion: 0.11
|
||||
Nodes (21): fetchGetMenuCodes(), fetchGetUserInfo(), fetchLogin(), fetchRefreshToken(), fetchUpdateProfile(), fetchUploadProfileAvatar(), fetchUserInfo(), buildWebEncryptedLoginBody() (+13 more)
|
||||
|
||||
### Community 27 - "Community 27"
|
||||
Cohesion: 0.12
|
||||
Nodes (24): fetchCellProductSpecList(), fetchCellProductTypeList(), applyProductCodeToLines(), calcExpiryFromFreeze(), createEmptyProductLine(), createQuantityValue(), getLineStorageSlotOptions(), getOtherLineStorageSlotIds() (+16 more)
|
||||
|
||||
### Community 28 - "Community 28"
|
||||
Cohesion: 0.09
|
||||
Nodes (11): fetchMineQcWorkOrderTabUnfinishedCounts(), fetchOutboundQcDetail(), fetchQcWorkOrderDetail(), fetchQcWorkOrderList(), fetchQcWorkOrderTabUnfinishedCounts(), reload(), reloadTabCounts(), handleMenuJump() (+3 more)
|
||||
|
||||
### Community 29 - "Community 29"
|
||||
Cohesion: 0.12
|
||||
Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
|
||||
|
||||
### Community 29 - "Community 29"
|
||||
### Community 30 - "Community 30"
|
||||
Cohesion: 0.1
|
||||
Nodes (5): normalizeStepSubTables(), parseEquipmentIds(), syncEquipmentNamesFromOptions(), formatPlannedStartDate(), normalizePlannedStartDate()
|
||||
|
||||
### Community 31 - "Community 31"
|
||||
Cohesion: 0.13
|
||||
Nodes (18): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchDeleteCellSampleType(), fetchUpdateCellSampleType(), handleAdd(), handleDelete(), handleDropdownCommand(), handleEdit() (+10 more)
|
||||
|
||||
### Community 32 - "Community 32"
|
||||
Cohesion: 0.11
|
||||
Nodes (11): fetchOutboundReleaseMaterial(), fetchOutboundReleaseReviewDetail(), fetchOutboundReleaseReviewList(), fetchReleaseReviewList(), handleReset(), handleSearch(), handleToggleSelect(), loadData() (+3 more)
|
||||
|
||||
### Community 30 - "Community 30"
|
||||
### Community 33 - "Community 33"
|
||||
Cohesion: 0.12
|
||||
Nodes (8): fetchMineProductionWorkOrderTabStepCounts(), fetchProductionWorkOrderCellProductOptions(), fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList(), fetchProductionWorkOrderQcDispatchOptions(), fetchProductionWorkOrderTabStepCounts(), collectVisibleProductionMenuBadgeCodes(), refreshProductionMenuBadges()
|
||||
|
||||
### Community 34 - "Community 34"
|
||||
Cohesion: 0.16
|
||||
Nodes (13): handleChineseDatetimePaste(), parseChineseDatetimeText(), isMaternalBloodEmpty(), matchCellSampleType(), normalizeLine(), parseDatetime(), parseDeliveryMode(), parseDonationStandardImportText() (+5 more)
|
||||
|
||||
### Community 31 - "Community 31"
|
||||
### Community 35 - "Community 35"
|
||||
Cohesion: 0.16
|
||||
Nodes (14): fetchCreateEnvDetectItem(), fetchDeleteEnvDetectItem(), fetchEnvDetectItemDetail(), fetchEnvDetectItemList(), fetchEnvDetectItemsActive(), fetchUpdateEnvDetectItem(), handleAdd(), handleBatchDelete() (+6 more)
|
||||
|
||||
### Community 32 - "Community 32"
|
||||
### Community 36 - "Community 36"
|
||||
Cohesion: 0.16
|
||||
Nodes (10): useTable(), useTableImpl(), getColumnChecks(), useTableColumns(), createErrorHandler(), createSmartDebounce(), defaultResponseAdapter(), extractPagination() (+2 more)
|
||||
|
||||
### Community 33 - "Community 33"
|
||||
### Community 37 - "Community 37"
|
||||
Cohesion: 0.27
|
||||
Nodes (14): useChart(), useChartComponent(), useChartOps(), colourBlend(), getCssVar(), getDarkColor(), getLightColor(), handleElementThemeColor() (+6 more)
|
||||
|
||||
### Community 34 - "Community 34"
|
||||
### Community 38 - "Community 38"
|
||||
Cohesion: 0.33
|
||||
Nodes (13): buildProtocolPaymentFlowSteps(), dash(), financeReceiptTime(), formatAmount(), hasFinanceReceipt(), hasFinanceRefund(), hasReceiptSubmit(), hasRefundSubmit() (+5 more)
|
||||
|
||||
### Community 35 - "Community 35"
|
||||
### Community 39 - "Community 39"
|
||||
Cohesion: 0.19
|
||||
Nodes (6): fetchServiceOrderTxnList(), handleReset(), handleSearch(), handleTabChange(), loadData(), switchTab()
|
||||
|
||||
### Community 37 - "Community 37"
|
||||
### Community 41 - "Community 41"
|
||||
Cohesion: 0.15
|
||||
Nodes (4): fetchNextDonationSampleCode(), fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList()
|
||||
|
||||
### Community 38 - "Community 38"
|
||||
Cohesion: 0.18
|
||||
Nodes (3): normalizeStepSubTables(), parseEquipmentIds(), syncEquipmentNamesFromOptions()
|
||||
|
||||
### Community 39 - "Community 39"
|
||||
### Community 42 - "Community 42"
|
||||
Cohesion: 0.24
|
||||
Nodes (6): buildInboundMetaFields(), getCardMetaConfig(), getCardMetaConfigForLegacyTab(), parseReceptionTime(), receptionOver24HoursLabel(), receptionOver24HoursTagType()
|
||||
|
||||
### Community 40 - "Community 40"
|
||||
### Community 43 - "Community 43"
|
||||
Cohesion: 0.42
|
||||
Nodes (9): buildPaymentFlowSteps(), dash(), formatAmount(), hasFinanceReceipt(), hasFinanceRefund(), hasReceiptSubmit(), hasRefundSubmit(), receiptSubmitTime() (+1 more)
|
||||
|
||||
### Community 41 - "Community 41"
|
||||
### Community 44 - "Community 44"
|
||||
Cohesion: 0.25
|
||||
Nodes (2): handleTouchEnd(), setTransition()
|
||||
|
||||
### Community 44 - "Community 44"
|
||||
### Community 45 - "Community 45"
|
||||
Cohesion: 0.28
|
||||
Nodes (1): FireworkSystem
|
||||
|
||||
### Community 49 - "Community 49"
|
||||
Cohesion: 0.39
|
||||
Nodes (6): isIgnorableScriptError(), normalizeErrorMessage(), registerPromiseErrorHandler(), registerResourceErrorHandler(), scriptErrorHandler(), setupErrorHandle()
|
||||
|
||||
### Community 45 - "Community 45"
|
||||
### Community 50 - "Community 50"
|
||||
Cohesion: 0.36
|
||||
Nodes (1): TableHeightCalculator
|
||||
|
||||
### Community 48 - "Community 48"
|
||||
### Community 52 - "Community 52"
|
||||
Cohesion: 0.33
|
||||
Nodes (2): logApiCryptoBootInfo(), maskSecret()
|
||||
|
||||
### Community 49 - "Community 49"
|
||||
Cohesion: 0.29
|
||||
Nodes (2): fetchLeaveDetail(), fetchLeaveList()
|
||||
### Community 53 - "Community 53"
|
||||
Cohesion: 0.48
|
||||
Nodes (5): buildPrefilledLabStorageCode(), formatYear(), formatYm(), normalizeSampleTypeName(), normalizeSourceType()
|
||||
|
||||
### Community 50 - "Community 50"
|
||||
### Community 54 - "Community 54"
|
||||
Cohesion: 0.47
|
||||
Nodes (3): isPaymentDueWithinWarnWindow(), parsePaymentDueYmd(), startOfLocalDay()
|
||||
|
||||
### Community 52 - "Community 52"
|
||||
### Community 55 - "Community 55"
|
||||
Cohesion: 0.5
|
||||
Nodes (2): formatProtocolDocDeleteConfirm(), formatProtocolDocSubject()
|
||||
|
||||
### Community 53 - "Community 53"
|
||||
### Community 56 - "Community 56"
|
||||
Cohesion: 0.5
|
||||
Nodes (2): focusInput(), handleKeydown()
|
||||
|
||||
### Community 54 - "Community 54"
|
||||
### Community 57 - "Community 57"
|
||||
Cohesion: 0.67
|
||||
Nodes (2): if(), logSidebarMenu()
|
||||
|
||||
### Community 57 - "Community 57"
|
||||
### Community 60 - "Community 60"
|
||||
Cohesion: 0.5
|
||||
Nodes (1): fetchSampleSmsNotificationList()
|
||||
Nodes (1): fetchStorageEntrySmsList()
|
||||
|
||||
### Community 58 - "Community 58"
|
||||
Cohesion: 0.5
|
||||
Nodes (1): fetchQcSmsList()
|
||||
|
||||
### Community 63 - "Community 63"
|
||||
### Community 64 - "Community 64"
|
||||
Cohesion: 1.0
|
||||
Nodes (2): getSettingDefaults(), resetToDefaults()
|
||||
|
||||
### Community 65 - "Community 65"
|
||||
### Community 66 - "Community 66"
|
||||
Cohesion: 1.0
|
||||
Nodes (2): copyTextToClipboard(), copyTextWithFallback()
|
||||
|
||||
### Community 72 - "Community 72"
|
||||
Cohesion: 1.0
|
||||
Nodes (2): emptyTabCounts(), useProductionWorkOrderTabStepCounts()
|
||||
|
||||
### Community 73 - "Community 73"
|
||||
Cohesion: 1.0
|
||||
Nodes (2): emptyTabCounts(), useQcWorkOrderTabUnfinishedCounts()
|
||||
|
||||
## Knowledge Gaps
|
||||
- **Thin community `Community 18`** (42 nodes): `WebSocketClient`, `.calculateReconnectDelay()`, `.clearAllTimers()`, `.clearConnectionTimers()`, `.clearTimer()`, `.close()`, `.closeCurrentSocketForReconnect()`, `.connect()`, `.connectionStatusText()`, `.constructor()`, `.destroyInstance()`, `.flushMessageQueue()`, `.getInstance()`, `.getReadyStateText()`, `.handleClose()`, `.handleConnectionTimeout()`, `.handleError()`, `.handleMessage()`, `.handleOpen()`, `.init()`, `.isWebSocketConnected()`, `.reconnect()`, `.resetHeartbeat()`, `.send()`, `.startHeartbeat()`, `.startPing()`, `TableCache`, `.cleanupExpired()`, `.clear()`, `.clearByTags()`, `.clearCurrentSearch()`, `.clearPagination()`, `.constructor()`, `.evictLRU()`, `.generateKey()`, `.generateTags()`, `.get()`, `.getStats()`, `.log()`, `.set()`, `index.ts`, `tableCache.ts`
|
||||
- **Thin community `Community 19`** (42 nodes): `WebSocketClient`, `.calculateReconnectDelay()`, `.clearAllTimers()`, `.clearConnectionTimers()`, `.clearTimer()`, `.close()`, `.closeCurrentSocketForReconnect()`, `.connect()`, `.connectionStatusText()`, `.constructor()`, `.destroyInstance()`, `.flushMessageQueue()`, `.getInstance()`, `.getReadyStateText()`, `.handleClose()`, `.handleConnectionTimeout()`, `.handleError()`, `.handleMessage()`, `.handleOpen()`, `.init()`, `.isWebSocketConnected()`, `.reconnect()`, `.resetHeartbeat()`, `.send()`, `.startHeartbeat()`, `.startPing()`, `TableCache`, `.cleanupExpired()`, `.clear()`, `.clearByTags()`, `.clearCurrentSearch()`, `.clearPagination()`, `.constructor()`, `.evictLRU()`, `.generateKey()`, `.generateTags()`, `.get()`, `.getStats()`, `.log()`, `.set()`, `index.ts`, `tableCache.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 41`** (9 nodes): `cleanupEventListeners()`, `handleTouchEnd()`, `handleTouchMove()`, `handleTouchStart()`, `handleWheelScroll()`, `if()`, `setTransition()`, `setupEventListeners()`, `index.vue`
|
||||
- **Thin community `Community 44`** (9 nodes): `cleanupEventListeners()`, `handleTouchEnd()`, `handleTouchMove()`, `handleTouchStart()`, `handleWheelScroll()`, `if()`, `setTransition()`, `setupEventListeners()`, `index.vue`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 45`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
|
||||
- **Thin community `Community 45`** (9 nodes): `FireworkSystem`, `.constructor()`, `.createFirework()`, `.createParticle()`, `.getAvailableParticle()`, `.initializePool()`, `.preloadAllImages()`, `.preloadImage()`, `index.vue`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 48`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
|
||||
- **Thin community `Community 50`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 49`** (7 nodes): `fetchCreateLeave()`, `fetchDeleteLeave()`, `fetchLeaveDetail()`, `fetchLeaveList()`, `fetchSubmitLeave()`, `fetchUpdateLeave()`, `leave.ts`
|
||||
- **Thin community `Community 52`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 52`** (5 nodes): `formatProtocolDocBatchDeleteConfirm()`, `formatProtocolDocDeleteConfirm()`, `formatProtocolDocSubject()`, `getProtocolDocTypeLabel()`, `protocol-doc-label.ts`
|
||||
- **Thin community `Community 55`** (5 nodes): `formatProtocolDocBatchDeleteConfirm()`, `formatProtocolDocDeleteConfirm()`, `formatProtocolDocSubject()`, `getProtocolDocTypeLabel()`, `protocol-doc-label.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 53`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
|
||||
- **Thin community `Community 56`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 54`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
|
||||
- **Thin community `Community 57`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 57`** (4 nodes): `fetchGenerateSms()`, `fetchSampleSmsNotificationList()`, `fetchToggleSmsNotified()`, `sample-sms-notification.ts`
|
||||
- **Thin community `Community 60`** (4 nodes): `fetchGenerateStorageEntrySms()`, `fetchStorageEntrySmsList()`, `fetchToggleStorageEntrySmsNotified()`, `storage-entry-sms-notification.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 58`** (4 nodes): `fetchGenerateQcSms()`, `fetchQcSmsList()`, `fetchToggleQcSmsNotified()`, `qc-sms-notification.ts`
|
||||
- **Thin community `Community 64`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 63`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
|
||||
- **Thin community `Community 66`** (3 nodes): `copyTextToClipboard()`, `copyTextWithFallback()`, `copy-text.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 65`** (3 nodes): `copyTextToClipboard()`, `copyTextWithFallback()`, `copy-text.ts`
|
||||
- **Thin community `Community 72`** (3 nodes): `emptyTabCounts()`, `useProductionWorkOrderTabStepCounts()`, `useProductionWorkOrderTabStepCounts.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
- **Thin community `Community 73`** (3 nodes): `emptyTabCounts()`, `useQcWorkOrderTabUnfinishedCounts()`, `useQcWorkOrderTabUnfinishedCounts.ts`
|
||||
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
|
||||
|
||||
## Suggested Questions
|
||||
_Questions this graph is uniquely positioned to answer:_
|
||||
|
||||
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 20`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 29`, `Community 31`, `Community 35`, `Community 37`, `Community 49`, `Community 57`, `Community 58`?**
|
||||
_High betweenness centrality (0.322) - this node is a cross-community bridge._
|
||||
- **Why does `push()` connect `Community 7` to `Community 0`, `Community 1`, `Community 2`, `Community 4`, `Community 5`, `Community 6`, `Community 8`, `Community 9`, `Community 10`, `Community 14`, `Community 15`, `Community 16`, `Community 18`, `Community 19`, `Community 21`, `Community 22`, `Community 23`, `Community 25`, `Community 27`, `Community 39`?**
|
||||
_High betweenness centrality (0.154) - this node is a cross-community bridge._
|
||||
- **Why does `handleDynamicRoutes()` connect `Community 3` to `Community 26`, `Community 15`?**
|
||||
_High betweenness centrality (0.031) - this node is a cross-community bridge._
|
||||
- **Are the 267 inferred relationships involving `get()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
|
||||
_`get()` has 267 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 63 inferred relationships involving `push()` (e.g. with `collectLeafFacilityNodesInTreeOrder()` and `formatDetectMethods()`) actually correct?**
|
||||
_`push()` has 63 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 26 inferred relationships involving `emit()` (e.g. with `handleSubmit()` and `handleBlur()`) actually correct?**
|
||||
_`emit()` has 26 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 11`, `Community 13`, `Community 15`, `Community 16`, `Community 17`, `Community 18`, `Community 20`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 31`, `Community 32`, `Community 33`, `Community 35`, `Community 39`, `Community 41`, `Community 60`?**
|
||||
_High betweenness centrality (0.318) - this node is a cross-community bridge._
|
||||
- **Why does `push()` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 5`, `Community 6`, `Community 7`, `Community 9`, `Community 10`, `Community 11`, `Community 13`, `Community 14`, `Community 16`, `Community 17`, `Community 19`, `Community 20`, `Community 21`, `Community 23`, `Community 24`, `Community 26`, `Community 28`, `Community 33`, `Community 42`, `Community 45`?**
|
||||
_High betweenness centrality (0.185) - this node is a cross-community bridge._
|
||||
- **Are the 274 inferred relationships involving `get()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
|
||||
_`get()` has 274 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 69 inferred relationships involving `push()` (e.g. with `refreshQcMenuBadges()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
|
||||
_`push()` has 69 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 30 inferred relationships involving `emit()` (e.g. with `handleSubmit()` and `handleBlur()`) actually correct?**
|
||||
_`emit()` has 30 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Are the 11 inferred relationships involving `handleDynamicRoutes()` (e.g. with `.getMenuList()` and `.validateMenuList()`) actually correct?**
|
||||
_`handleDynamicRoutes()` has 11 INFERRED edges - model-reasoned connections that need verification._
|
||||
- **Should `Community 0` be split into smaller, more focused modules?**
|
||||
_Cohesion score 0.01 - nodes in this community are weakly interconnected._
|
||||
@@ -57,12 +57,12 @@
|
||||
</div>
|
||||
<div id="legend"></div>
|
||||
</div>
|
||||
<div id="stats">2624 nodes · 3636 edges · 318 communities</div>
|
||||
<div id="stats">2705 nodes · 3770 edges · 324 communities</div>
|
||||
</div>
|
||||
<script>
|
||||
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 48, "community_name": "Community 48", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 48, "community_name": "Community 48", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 48, "community_name": "Community 48", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 48, "community_name": "Community 48", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 48, "community_name": "Community 48", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 48, "community_name": "Community 48", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 103, "community_name": "Community 103", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 104, "community_name": "Community 104", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 28, "community_name": "Community 28", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 28, "community_name": "Community 28", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 28, "community_name": "Community 28", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 28, "community_name": "Community 28", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 28, "community_name": "Community 28", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_setuprolesdirective",Line truncated
|
||||
const RAW_EDGES = [{"from": "app_vue", "to": "src_app_refreshbuttonautoicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "src_app_refreshpaneltitleicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "main_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "utils_sys_console_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_masksecret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_logapicryptobootinfo", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_main_masksecret", "to": "src_main_logapicryptobootinfo", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_ts", "to": "directives_index_setupglobdirectives", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_setupglobdirectives", "to": "core_auth_setupauthdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "core_roles_setuprolesdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_highlight_setuphighlightdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_ripple_setuprippledirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_core_roles_ts", "to": "core_roles_checkrolepermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_setuprolesdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_roles_checkrolepermission", "to": "core_roles_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_checkauthpermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_setupauthdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_checkauthpermission", "to": "core_auth_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_ripple_ts", "to": "business_ripple_setuprippledirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_highlightcode", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_insertlinenumbers", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_addcopybutton", "label": "contains", "title": "contains [EXTRACTED]", "dLine truncated
|
||||
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 382}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 112}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 104}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 95}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 91}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 89}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 86}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 81}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 76}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 69}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 66}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 62}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 61}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 60}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 55}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 53}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 50}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 48}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 42}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 40}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 39}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 38}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 35}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 34}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 33}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 29}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 29}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 28}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 22}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 22}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 19}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 19}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 17}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 16}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 14}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 14}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 13}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 13}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 12}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 11}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 10}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 9}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 9}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 9}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 8}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 8}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 8}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 8}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 7}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 7}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 6}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 6}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 5}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 5}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 4}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 4}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 4}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 4}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 4}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 4}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 4}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 4}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 4}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 3}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 3}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 3}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 3}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 3}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 3}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 3}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "cLine truncated
|
||||
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 52, "community_name": "Community 52", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 52, "community_name": "Community 52", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 52, "community_name": "Community 52", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 52, "community_name": "Community 52", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 52, "community_name": "Community 52", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 52, "community_name": "Community 52", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 105, "community_name": "Community 105", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 106, "community_name": "Community 106", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 29, "community_name": "Community 29", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.5, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 29, "community_name": "Community 29", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 29, "community_name": "Community 29", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 29, "community_name": "Community 29", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 29, "community_name": "Community 29", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_setuprolesdirective",Line truncated
|
||||
const RAW_EDGES = [{"from": "app_vue", "to": "src_app_refreshbuttonautoicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "src_app_refreshpaneltitleicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "main_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "utils_sys_console_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_masksecret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_logapicryptobootinfo", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_main_masksecret", "to": "src_main_logapicryptobootinfo", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_ts", "to": "directives_index_setupglobdirectives", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_setupglobdirectives", "to": "core_auth_setupauthdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "core_roles_setuprolesdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_highlight_setuphighlightdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_ripple_setuprippledirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_core_roles_ts", "to": "core_roles_checkrolepermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_setuprolesdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_roles_checkrolepermission", "to": "core_roles_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_checkauthpermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_setupauthdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_checkauthpermission", "to": "core_auth_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_ripple_ts", "to": "business_ripple_setuprippledirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_highlightcode", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_insertlinenumbers", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_addcopybutton", "label": "contains", "title": "contains [EXTRACTED]", "dLine truncated
|
||||
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 389}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 147}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 104}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 96}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 95}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 91}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 90}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 89}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 62}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 58}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 58}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 55}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 51}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 51}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 50}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 48}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 47}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 44}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 42}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 42}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 39}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 39}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 39}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 35}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 34}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 33}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 32}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 29}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 24}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 22}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 22}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 22}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 22}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 20}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 19}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 19}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 17}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 16}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 14}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 14}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 13}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 13}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 11}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 10}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 9}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 9}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 9}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 9}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 9}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 8}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 8}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 8}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 7}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 7}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 6}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 5}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 5}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 4}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 4}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 4}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 4}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 4}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 4}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 4}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 3}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 3}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 3}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 3}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 3}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 3}, {"cid": 70, "color": "#4E79A7", "label": "Community 70",Line truncated
|
||||
|
||||
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
|
||||
function esc(s) {
|
||||
|
||||
+5831
-3530
File diff suppressed because it is too large.
Load diff
@@ -17,10 +17,10 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/common/index.ts": 1781272556.3597305,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/directive/directive.d.ts": 1781272556.3601494,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/api/api.d.ts": 1781272556.3606477,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1782361730.3874717,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1782361721.5556824,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1782406001.435002,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1782405955.9372323,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/store/index.ts": 1781272556.364766,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/router/index.ts": 1781272556.3652694,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/router/index.ts": 1782394569.8806834,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/locales/index.ts": 1781272556.3657222,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/config/pilot-biz-type.ts": 1781682539.4897008,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/config/setting.ts": 1781406298.257571,
|
||||
@@ -40,6 +40,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/mock/temp/commentDetail.ts": 1781272556.3772519,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/enums/formEnum.ts": 1781272556.3778555,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/enums/appEnum.ts": 1781272556.3784597,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-menu-badge.ts": 1782396392.0954244,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/patch-el-select-filterable.ts": 1781272556.3791182,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/storage-slot-options.ts": 1782289322.9593837,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-tabs.ts": 1781600464.3251936,
|
||||
@@ -47,25 +48,30 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/user-avatar.ts": 1781403605.517818,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/fullscreen-loading.ts": 1781272556.3849921,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-material-ui.ts": 1781525352.6976836,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-tabs.ts": 1781600462.9964879,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts": 1781698792.9167962,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-tabs.ts": 1782399957.5092957,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-card-meta.ts": 1782400129.6397395,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-category.ts": 1782393809.3917818,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router.ts": 1781272556.3875713,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-mine-task-groups.ts": 1781583493.924234,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-mine-task-groups.ts": 1781608059.9990764,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-mine-task-groups.ts": 1782399957.8029892,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-payment-labels.ts": 1781272556.3878465,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/status-tag-registry.ts": 1781765815.259271,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-card-meta.ts": 1782358030.9320872,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/fetch-paged-list.ts": 1781272556.3903377,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/sort-order.ts": 1781272556.3913012,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/sample-reception-lab-storage-code.ts": 1782378453.1031013,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/outbound-qc-pilot-view-sections.ts": 1781566346.7618802,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-groups.ts": 1781607964.911379,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-groups.ts": 1782400129.6394563,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-inspection-batch.ts": 1782398602.0427291,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/equipment-select.ts": 1781524048.96866,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-item-param-options.ts": 1782380049.7449021,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/clinical-payment-flow-steps.ts": 1781566916.7893076,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/donation-standard-import-parse.ts": 1782181911.7421873,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/copy-text.ts": 1781272556.4018052,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/tree-path.ts": 1781272556.402468,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/mask-sensitive.ts": 1781272556.4029639,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-labels.ts": 1781272556.4033675,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-labels.ts": 1782404305.713515,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-menu-badge.ts": 1782404667.995363,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/numeric-input-parse.ts": 1782179343.5953708,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/index.ts": 1781272556.410244,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts": 1781272556.4107764,
|
||||
@@ -167,10 +173,10 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-chat-window/index.vue": 1781272556.562926,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-page-content/index.vue": 1781272556.56442,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-horizontal-menu/index.vue": 1781272556.5652099,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-horizontal-menu/widget/HorizontalSubmenu.vue": 1781272556.5676432,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-horizontal-menu/widget/HorizontalSubmenu.vue": 1782404678.3207965,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-mixed-menu/index.vue": 1781401124.1983705,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/index.vue": 1781406299.7525744,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/widget/SidebarSubmenu.vue": 1781272556.5851753,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-menus/art-sidebar-menu/widget/SidebarSubmenu.vue": 1782404695.2500448,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-fireworks-effect/index.vue": 1781272556.5941117,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-global-search/index.vue": 1781272556.597667,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/layouts/art-notification/index.vue": 1781272556.6005983,
|
||||
@@ -197,12 +203,12 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-transport-form-section/index.vue": 1782206210.4586368,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/protocol-finance-confirm-fields/index.vue": 1781585388.6311953,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/protocol-finance-confirm-fields/finance-attachments.ts": 1781272556.6256514,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/qc-task-view-dialog/index.vue": 1781590356.7882614,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/qc-task-view-dialog/index.vue": 1782398594.1845114,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-payment-confirm-timeline/index.vue": 1781751829.1650536,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-readonly-panel/index.vue": 1781604188.1794512,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/dialog-form-body/index.vue": 1781272556.6276903,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-payment-submit-readonly/index.vue": 1781566692.993364,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-cards/index.vue": 1781596037.4093332,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-cards/index.vue": 1782398260.9411232,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/order-operate-local-dialog/index.vue": 1781272556.6297834,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/product-view-dialog/index.vue": 1781563767.2879,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-production-info-cards/index.vue": 1781585388.6388853,
|
||||
@@ -211,8 +217,10 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/work-order-remark-dialog/index.vue": 1781563767.2910764,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-info-grouped-panel/index.vue": 1781596014.9588113,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/clinical-schedule-payment-detail/index.vue": 1781585388.6415968,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/sample-qc-batch-readonly/index.vue": 1782398610.3519263,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/outbound-material-form-sections/index.vue": 1781598316.2599268,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/protocol-payment-detail-readonly/index.vue": 1781440987.1200492,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/qc-item-param-select-editor/index.vue": 1782380052.8264449,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/system-view-dialog/index.vue": 1781592191.1258788,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue": 1781272556.644192,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/order-operate-dialog-bridge/index.vue": 1781272556.644745,
|
||||
@@ -221,7 +229,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/core/useFastEnter.ts": 1781272556.6454022,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/core/useTableColumns.ts": 1781272556.6461287,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/core/useTable.ts": 1781272556.6477242,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/core/useMenuPerm.ts": 1782120928.5337958,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/core/useMenuPerm.ts": 1782405945.5294456,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/core/useHeaderBar.ts": 1781272556.6492157,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/core/useAuth.ts": 1781272556.6495874,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/core/useLayoutHeight.ts": 1781272556.6500459,
|
||||
@@ -235,14 +243,14 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception-check-item.ts": 1781272556.654672,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production.ts": 1781497438.3206656,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/infusion-schedule-handover.ts": 1781272556.6558568,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts": 1781603141.9232655,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts": 1782398621.3842177,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-third-party-item.ts": 1781272556.6567156,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/env-detect-record.ts": 1781272556.6569912,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts": 1781536765.5084789,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-material.ts": 1781510846.4290047,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/env-detect-record.ts": 1782375300.5909576,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts": 1782398606.4492025,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-material.ts": 1782404996.1897874,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/workflow.ts": 1781272556.6579714,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts": 1782350330.2414439,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-task-result.ts": 1781272556.6589992,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts": 1782404662.9687421,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-task-result.ts": 1782379634.2324347,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/protocol-sample-collection.ts": 1781272556.659353,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material-usage.ts": 1781517319.838243,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/pre-transit-sample.ts": 1782204427.8344586,
|
||||
@@ -259,8 +267,8 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-sms-notification.ts": 1781272556.666838,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material-stock-check.ts": 1781427280.4992144,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/research-donation.ts": 1782182859.3901165,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-task.ts": 1781581101.6134424,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-item-param.ts": 1781272556.6680455,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-task.ts": 1782398334.3162003,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-item-param.ts": 1782380054.2964334,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/env-detect-item.ts": 1781272556.668322,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts": 1782362264.303446,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-stock-check.ts": 1781424012.5471919,
|
||||
@@ -271,7 +279,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material.ts": 1781346022.817811,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts": 1781496419.5874305,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/auth.ts": 1782122651.4628098,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts": 1782350342.5611486,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts": 1782398601.5849254,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/auth/login/index.vue": 1781272556.6735966,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/refund-confirm/index.vue": 1781272556.6742516,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/my-material-usage/index.vue": 1781518736.690082,
|
||||
@@ -356,25 +364,27 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/sop/index.vue": 1781585388.69546,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-task/index.vue": 1781272556.812188,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/reagent/index.vue": 1781563767.359068,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue": 1782351718.6351538,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts": 1782362265.837388,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/StepDetailPanel.vue": 1782362266.614523,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue": 1782404705.735053,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts": 1782404253.840776,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/StepDetailPanel.vue": 1782404245.9286346,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/CompleteProductionTaskDialog.vue": 1781563767.3525257,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskInputEnhancedTable.vue": 1781585388.6972075,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchQcWorkOrderDialog.vue": 1782359900.6139107,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/SampleReceptionDialog.vue": 1781599793.4040868,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue": 1782351614.9751787,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/SampleReceptionDialog.vue": 1782377442.3260844,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskExecutionDialog.vue": 1782401948.7290232,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/EditTaskInfoDialog.vue": 1781577178.2471955,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskOutputList.vue": 1781585388.699347,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchTaskDialog.vue": 1782361064.4509723,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskPaperAttachmentsPanel.vue": 1781530960.805927,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/WorkOrderTaskSubList.vue": 1782351634.8770185,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/WorkOrderTaskSubList.vue": 1782401972.0912113,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/TaskOutputProductDialog.vue": 1781605192.0421948,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue": 1782358112.4315796,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderCardList.vue": 1782403069.155186,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ForwardTaskDialog.vue": 1781563767.3550124,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchStepDialog.vue": 1782351544.529724,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/WorkOrderTaskStepSubList.vue": 1782404256.625954,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/ProductionWorkOrderTabBar.vue": 1782403774.1374023,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/DispatchStepDialog.vue": 1782404217.6559534,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/tabs/OutboundPilotTab.vue": 1781583381.1088736,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/tabs/ProductionWorkOrderTabPanel.vue": 1781583376.390064,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/tabs/ProductionWorkOrderTabPanel.vue": 1782403798.0853126,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/tabs/InboundCellStorageTab.vue": 1781583380.9191706,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/tabs/OutboundBasicExperimentTab.vue": 1781583381.738445,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/tabs/InboundResearchDonationTab.vue": 1781583380.9646196,
|
||||
@@ -383,6 +393,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/tabs/OutboundClinicalTab.vue": 1781583382.4319067,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/production-view-sections.ts": 1781583319.8749113,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/useProductionViewDialog.ts": 1781587764.7598283,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/useProductionWorkOrderTabStepCounts.ts": 1782403760.178825,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/composables/useProductionWorkOrderTabPage.ts": 1781600314.4294987,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/InboundResearchDonationProductionViewDialog.vue": 1781583332.0303154,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/view-dialogs/OutboundClinicalProductionViewDialog.vue": 1781583335.85169,
|
||||
@@ -396,66 +407,72 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable/index.vue": 1781563767.346933,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/consumable/ConsumablePackTab.vue": 1781563767.3461943,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cleanroom-garment/index.vue": 1782265247.376364,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/index.vue": 1781519269.9141352,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/index.vue": 1782405078.1976075,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/MaterialConsumptionTab.vue": 1781502903.0563822,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/ProductionMaterialConfiguredCatalogDialog.vue": 1781498587.3288593,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/ProductionMaterialUsageTab.vue": 1781513793.4925437,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/ProductionMaterialStockCheckTab.vue": 1781508293.4167504,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-material/ProductionMaterialPrepTab.vue": 1781513807.0808678,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/sample-reception-completion/index.vue": 1781272556.844081,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/my-production-task/index.vue": 1781583391.5411932,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/my-production-task/index.vue": 1782404707.528094,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/equipment/index.vue": 1781563767.347355,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process/index.vue": 1781599788.6457248,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process/ProcessRouteTab.vue": 1781588546.7932389,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process-category/index.vue": 1781585388.7112913,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process-category/OutputTypeTab.vue": 1781563767.348404,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/index/index.vue": 1781272556.8548205,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue": 1781592807.1040754,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskResultPanel.vue": 1781589482.0890527,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSingleCard.vue": 1781699027.2649422,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue": 1782394624.8193831,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskResultPanel.vue": 1782398341.1529968,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderProtocolGroup.vue": 1782400499.8822792,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSingleCard.vue": 1782399918.5252447,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderConfigureBatches.vue": 1782386066.318798,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderFeeSummaryBar.vue": 1781585388.7152023,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSampleGroup.vue": 1781766463.2300944,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue": 1781590356.5447705,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderCardList.vue": 1781595924.5325,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderSampleGroup.vue": 1782399917.944618,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTaskSubList.vue": 1782392417.2151616,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderTabBar.vue": 1782394192.4055598,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderBatchSubList.vue": 1782401185.925739,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderCardList.vue": 1782400042.2199035,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/QcWorkOrderProtocolPaymentPanel.vue": 1781588255.9076052,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/OutboundPilotTab.vue": 1781582034.0446215,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/InboundCellStorageTab.vue": 1781582031.9110096,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/QcWorkOrderTabPanel.vue": 1781608023.8214188,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/QcWorkOrderTabPanel.vue": 1782394239.6593502,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/OutboundBasicExperimentTab.vue": 1781582033.9975233,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/InboundResearchDonationTab.vue": 1781582033.9975069,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/AllTab.vue": 1782393769.7060475,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/TemporaryTab.vue": 1781582036.0799434,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/tab-registry.ts": 1781582169.4766586,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/tab-registry.ts": 1782393772.4243252,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/tabs/OutboundClinicalTab.vue": 1781582035.6614258,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useOutboundQcViewDialog.ts": 1781589519.6184735,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTaskViewSections.ts": 1781589505.5582125,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useInboundQcViewDialog.ts": 1781589515.800703,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useOutboundQcViewDialog.ts": 1782398591.849214,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTaskViewSections.ts": 1782398280.5764718,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabUnfinishedCounts.ts": 1782394182.2860413,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useInboundQcViewDialog.ts": 1782398606.799624,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcViewAttachmentHelpers.ts": 1781581579.8782947,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/inbound-view-sections.ts": 1781608057.8810816,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts": 1781608043.655311,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/QcWorkOrderSystemViewDialog.vue": 1781589553.6371684,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/inbound-view-sections.ts": 1782398282.921316,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts": 1782397823.6269462,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/QcWorkOrderSystemViewDialog.vue": 1782398380.8308663,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundQcProductTable.vue": 1781604200.1464918,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundQcDiagnosisAttachments.vue": 1781581843.4276094,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/view-dialog-registry.ts": 1781582168.445552,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/InboundResearchDonationViewDialog.vue": 1781589531.009138,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundBasicExperimentViewDialog.vue": 1781604200.1465678,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundClinicalViewDialog.vue": 1781604200.291363,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/InboundCellStorageViewDialog.vue": 1781589526.0101316,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/TemporaryQcViewDialog.vue": 1781589531.7431345,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundPilotViewDialog.vue": 1781604200.1465576,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception-check-item/index.vue": 1781563767.3726647,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/index.vue": 1781585388.7276096,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/ThirdPartyCompanyTab.vue": 1781761242.3112986,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/view-dialog-registry.ts": 1782393780.8839016,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/InboundResearchDonationViewDialog.vue": 1782398319.51777,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundBasicExperimentViewDialog.vue": 1782398324.891622,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundClinicalViewDialog.vue": 1782398323.6604831,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/InboundCellStorageViewDialog.vue": 1782398316.2496862,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/TemporaryQcViewDialog.vue": 1782398320.0266304,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/view-dialogs/OutboundPilotViewDialog.vue": 1782398324.4457653,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception-check-item/index.vue": 1782405995.2313125,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/index.vue": 1782379670.980952,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/ThirdPartyCompanyTab.vue": 1782379714.340431,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/my-qc-material-usage/index.vue": 1781518516.1543977,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue": 1781690353.3115087,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialStockCheckTab.vue": 1781563767.3635929,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue": 1782120970.241405,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue": 1782405945.9069998,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialStockCheckTab.vue": 1782405946.1329827,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue": 1782405945.6418679,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/QcMaterialBatchAttachmentDialog.vue": 1781690342.0885053,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/index.vue": 1782206029.583706,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue": 1782263777.2928922,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue": 1782198775.9162123,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue": 1782378331.5120492,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/SampleReceptionCardList.vue": 1781585388.7346976,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/my-qc-task/index.vue": 1781582341.1215634,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/env-detect-record/index.vue": 1781585388.736309,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/my-qc-task/index.vue": 1782394624.819391,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/env-detect-record/index.vue": 1782377015.4291072,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/env-detect-item/index.vue": 1781563767.360739,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue": 1781272556.8975937,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/storage-release-review/index.vue": 1781272556.8987281,
|
||||
@@ -522,11 +539,13 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/CollectionProtocolNoTab.vue": 1781563767.3099859,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/assets/svg/loading.ts": 1781272558.486104,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/index.ts": 1781272559.227605,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/qc-menu-badge.ts": 1782394567.2213001,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/worktab.ts": 1781351182.1456184,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/table.ts": 1781272559.2465377,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/menu.ts": 1781272559.2476027,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/setting.ts": 1781661173.9923356,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts": 1782190001.5644245,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/production-menu-badge.ts": 1782404664.0879827,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/user.ts": 1782404740.3322744,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/routesAlias.ts": 1781272559.2590332,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/index.ts": 1781272559.4304278,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/core/RouteTransformer.ts": 1781272559.268035,
|
||||
@@ -542,7 +561,7 @@
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/exception.ts": 1781272559.549901,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/routes/staticRoutes.ts": 1781272559.596198,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/routes/asyncRoutes.ts": 1781272559.619745,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts": 1782190002.5828512,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/beforeEach.ts": 1782404681.821045,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/guards/afterEach.ts": 1781272559.7019026,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/assets/svg/my-copy.svg": 1778582067.9349968,
|
||||
"/Users/wuzilong/work/00code/zkxw/web-admin/src/assets/svg/search.svg": 1778582067.9393654,
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"highlight.js": "^11.10.0",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"jszip": "^3.10.1",
|
||||
"mitt": "^3.0.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"ohash": "^2.0.11",
|
||||
|
||||
Generated
+3
@@ -62,6 +62,9 @@ importers:
|
||||
jsencrypt:
|
||||
specifier: ^3.3.2
|
||||
version: 3.5.4
|
||||
jszip:
|
||||
specifier: ^3.10.1
|
||||
version: 3.10.1
|
||||
mitt:
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.1
|
||||
|
||||
@@ -12,6 +12,7 @@ export type EnvDetectRecord = {
|
||||
id: string
|
||||
recordNo: string
|
||||
detectTime: string
|
||||
resultTime?: string
|
||||
inspectorIds: string[]
|
||||
inspectorNames: string[]
|
||||
inspectorDisplay: string
|
||||
@@ -48,6 +49,7 @@ export function fetchEnvDetectRecordDetail(id: string) {
|
||||
|
||||
export function fetchCreateEnvDetectRecord(data: {
|
||||
detectTime: string
|
||||
resultTime?: string
|
||||
inspectorIds: string[]
|
||||
envDetectItemId: string
|
||||
resultDesc: string
|
||||
@@ -64,6 +66,7 @@ export function fetchUpdateEnvDetectRecord(
|
||||
id: string,
|
||||
data: {
|
||||
detectTime?: string
|
||||
resultTime?: string
|
||||
inspectorIds?: string[]
|
||||
envDetectItemId?: string
|
||||
resultDesc?: string
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {
|
||||
OutboundQcDetailInfusionSchedule,
|
||||
OutboundQcDetailProduct
|
||||
} from '@/api/qc-work-order'
|
||||
import type { QcInspectionBatch } from '@/utils/qc-inspection-batch'
|
||||
|
||||
type PageList<T> = {
|
||||
list: T[]
|
||||
@@ -82,19 +83,24 @@ export type OutboundProductionInfo = {
|
||||
|
||||
export type OutboundQcTask = {
|
||||
id?: string
|
||||
taskNo?: string
|
||||
itemName?: string
|
||||
taskType?: string
|
||||
taskTypeLabel?: string
|
||||
taskStatus?: string
|
||||
taskStatusLabel?: string
|
||||
conclusion?: string
|
||||
conclusionLabel?: string
|
||||
batchId?: string
|
||||
}
|
||||
|
||||
export type OutboundQcInfo = {
|
||||
id?: string
|
||||
workOrderNo?: string
|
||||
workOrderStatus?: string
|
||||
workOrderStatusLabel?: string
|
||||
tasks?: OutboundQcTask[]
|
||||
inspectionBatches?: QcInspectionBatch[]
|
||||
}
|
||||
|
||||
export type OutboundReleaseReviewDetail = {
|
||||
|
||||
@@ -39,6 +39,7 @@ export type ProductionMaterialBatch = {
|
||||
stockInNo: string
|
||||
stockInDate: string
|
||||
expireDate: string
|
||||
productionDate?: string
|
||||
catalogNo: string
|
||||
batchNo: string
|
||||
manufacturer: string
|
||||
@@ -72,6 +73,7 @@ export type ProductionMaterialBatchOption = {
|
||||
stockInNo: string
|
||||
stockInDate?: string
|
||||
expireDate?: string
|
||||
productionDate?: string
|
||||
materialId: string
|
||||
materialCode: string
|
||||
materialName: string
|
||||
@@ -92,6 +94,7 @@ export type StockInPayload = {
|
||||
stockInNo: string
|
||||
stockInDate: string
|
||||
expireDate: string
|
||||
productionDate?: string
|
||||
catalogNo: string
|
||||
batchNo: string
|
||||
manufacturer: string
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import request from '@/utils/http'
|
||||
import type { ProductionWorkOrderTabKey } from '@/utils/production-work-order-tabs'
|
||||
import type {
|
||||
QcWorkOrderReceptionDetail,
|
||||
OutboundQcDetailApplication,
|
||||
@@ -188,3 +189,50 @@ export function fetchCreateQcFromProduction(
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export type ProductionWorkOrderTabStepCount = {
|
||||
overdueIncomplete: number
|
||||
unassigned: number
|
||||
}
|
||||
|
||||
export type ProductionWorkOrderTabStepCounts = Record<
|
||||
ProductionWorkOrderTabKey,
|
||||
ProductionWorkOrderTabStepCount
|
||||
>
|
||||
|
||||
export function formatProductionWorkOrderTabStepBadge(count: ProductionWorkOrderTabStepCount): string {
|
||||
const fmt = (n: number) => (n > 99 ? '99+' : String(n))
|
||||
return `${fmt(count.overdueIncomplete)}+${fmt(count.unassigned)}`
|
||||
}
|
||||
|
||||
export function isProductionWorkOrderTabStepBadgeZero(count: ProductionWorkOrderTabStepCount): boolean {
|
||||
return (count.overdueIncomplete || 0) === 0 && (count.unassigned || 0) === 0
|
||||
}
|
||||
|
||||
/** 汇总可见 Tab 的步骤角标(左侧菜单展示各 Tab 数值之和) */
|
||||
export function sumProductionWorkOrderTabStepCounts(
|
||||
counts: Partial<ProductionWorkOrderTabStepCounts> | null | undefined,
|
||||
tabKeys: ProductionWorkOrderTabKey[]
|
||||
): ProductionWorkOrderTabStepCount {
|
||||
return tabKeys.reduce(
|
||||
(acc, key) => {
|
||||
const c = counts?.[key]
|
||||
acc.overdueIncomplete += c?.overdueIncomplete || 0
|
||||
acc.unassigned += c?.unassigned || 0
|
||||
return acc
|
||||
},
|
||||
{ overdueIncomplete: 0, unassigned: 0 }
|
||||
)
|
||||
}
|
||||
|
||||
export function fetchProductionWorkOrderTabStepCounts() {
|
||||
return request.get<ProductionWorkOrderTabStepCounts>({
|
||||
url: '/web/admin/production-work-orders/tab-step-counts'
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchMineProductionWorkOrderTabStepCounts() {
|
||||
return request.get<ProductionWorkOrderTabStepCounts>({
|
||||
url: '/web/admin/production-work-orders/mine-tab-step-counts'
|
||||
})
|
||||
}
|
||||
@@ -6,8 +6,12 @@ export type QcItemParam = {
|
||||
paramCode: string
|
||||
paramUnit?: string
|
||||
paramType: string
|
||||
options?: string
|
||||
defaultValue?: string
|
||||
requiredFlag: string
|
||||
orderNum?: number
|
||||
/** 表单编辑单选选项文本,逗号分隔(仅前端) */
|
||||
_optionText?: string
|
||||
}
|
||||
|
||||
export function fetchQcItemParams(itemSource: string, itemId: string) {
|
||||
|
||||
@@ -7,6 +7,9 @@ export type QcTaskResultItem = {
|
||||
paramCode?: string
|
||||
paramUnit?: string
|
||||
paramType: string
|
||||
options?: string
|
||||
defaultValue?: string
|
||||
requiredFlag?: string
|
||||
paramValue: string
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,9 @@ export type QcTask = {
|
||||
assigneeUserIds?: string[]
|
||||
assigneeUserNames?: string
|
||||
sourceLineId?: string
|
||||
batchId?: string
|
||||
batchName?: string
|
||||
batchNo?: string
|
||||
remark?: string
|
||||
createTime?: string
|
||||
updateTime?: string
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import request from '@/utils/http'
|
||||
import type { QcInspectionBatch } from '@/utils/qc-inspection-batch'
|
||||
import type { QcWorkOrderTabKey } from '@/utils/qc-work-order-tabs'
|
||||
|
||||
type PageList<T> = {
|
||||
list: T[]
|
||||
@@ -176,6 +178,25 @@ export type QcWorkOrderDetail = QcWorkOrder & {
|
||||
assigneeUserNames?: string
|
||||
attachmentFiles?: Array<{ id?: string; fileUrl?: string; fileName?: string }>
|
||||
}>
|
||||
inspectionBatches?: QcInspectionBatch[]
|
||||
}
|
||||
|
||||
export type QcWorkOrderTabUnfinishedCounts = Record<QcWorkOrderTabKey, number>
|
||||
|
||||
export function formatQcWorkOrderTabBadgeCount(count: number): string {
|
||||
return count > 99 ? '99+' : String(count)
|
||||
}
|
||||
|
||||
export function fetchQcWorkOrderTabUnfinishedCounts() {
|
||||
return request.get<QcWorkOrderTabUnfinishedCounts>({
|
||||
url: '/web/admin/qc-work-orders/tab-unfinished-counts'
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchMineQcWorkOrderTabUnfinishedCounts() {
|
||||
return request.get<QcWorkOrderTabUnfinishedCounts>({
|
||||
url: '/web/admin/qc-work-orders/mine-tab-unfinished-counts'
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchQcWorkOrderList(params?: {
|
||||
@@ -207,10 +228,19 @@ export function fetchQcWorkOrderDetail(id: string) {
|
||||
export function fetchConfigureQcWorkOrder(
|
||||
id: string,
|
||||
data: {
|
||||
hasLab: boolean
|
||||
hasThirdParty: boolean
|
||||
labItemIds: string[]
|
||||
thirdPartyItemIds: string[]
|
||||
batches?: Array<{
|
||||
id?: string
|
||||
batchName?: string
|
||||
assigneeUserIds: string[]
|
||||
hasLab: boolean
|
||||
hasThirdParty: boolean
|
||||
labItemIds: string[]
|
||||
thirdPartyItemIds: string[]
|
||||
}>
|
||||
hasLab?: boolean
|
||||
hasThirdParty?: boolean
|
||||
labItemIds?: string[]
|
||||
thirdPartyItemIds?: string[]
|
||||
labItemAssignees?: Record<string, string[]>
|
||||
thirdPartyItemAssignees?: Record<string, string[]>
|
||||
}
|
||||
@@ -317,6 +347,7 @@ export type OutboundQcDetail = {
|
||||
infusionSchedule?: OutboundQcDetailInfusionSchedule
|
||||
products?: OutboundQcDetailProduct[]
|
||||
tasks?: QcWorkOrderDetail['tasks']
|
||||
inspectionBatches?: QcInspectionBatch[]
|
||||
}
|
||||
|
||||
export function fetchOutboundQcDetail(id: string) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import request from '@/utils/http'
|
||||
import type { QcInspectionBatch } from '@/utils/qc-inspection-batch'
|
||||
import type { QcWorkOrderReceptionDetail } from '@/api/qc-work-order'
|
||||
|
||||
type PageList<T> = {
|
||||
@@ -74,15 +75,19 @@ export type ReceptionInfo = {
|
||||
|
||||
export type QcInfoTask = {
|
||||
id?: string
|
||||
taskNo?: string
|
||||
itemName?: string
|
||||
taskType?: string
|
||||
taskTypeLabel?: string
|
||||
taskStatus?: string
|
||||
taskStatusLabel?: string
|
||||
conclusion?: string
|
||||
conclusionLabel?: string
|
||||
batchId?: string
|
||||
}
|
||||
|
||||
export type QcInfo = {
|
||||
id?: string
|
||||
workOrderNo?: string
|
||||
workOrderStatus?: string
|
||||
workOrderStatusLabel?: string
|
||||
@@ -98,6 +103,7 @@ export type QcInfo = {
|
||||
productionWorkOrderId?: string
|
||||
productionWorkOrderNo?: string
|
||||
tasks?: QcInfoTask[]
|
||||
inspectionBatches?: QcInspectionBatch[]
|
||||
}
|
||||
|
||||
export type ProductionInfoTask = {
|
||||
|
||||
@@ -276,6 +276,16 @@ body {
|
||||
text-align: center;
|
||||
background: #fd4e4e;
|
||||
border-radius: 4px;
|
||||
|
||||
&--zero {
|
||||
background: #94a3b8;
|
||||
}
|
||||
|
||||
&--dual {
|
||||
min-width: 34px;
|
||||
padding: 0 6px;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes breathe {
|
||||
@@ -520,6 +530,23 @@ body {
|
||||
border-color: var(--primary, #10b981);
|
||||
}
|
||||
|
||||
&__badge--zero {
|
||||
background: #94a3b8;
|
||||
}
|
||||
|
||||
&__badge--dual {
|
||||
min-width: 34px;
|
||||
padding: 0 6px;
|
||||
font-size: 10px;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
&__btn.is-active &__badge--zero {
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
color: var(--primary-dark, #059669);
|
||||
border-color: var(--primary, #10b981);
|
||||
}
|
||||
|
||||
// el-tabs 结构
|
||||
&.el-tabs {
|
||||
> .el-tabs__header {
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="qc-param-select-editor">
|
||||
<div class="qc-param-select-editor__head">
|
||||
单选选项
|
||||
<span class="form-label-tip">多个选项用逗号分隔,第一个为默认选项</span>
|
||||
</div>
|
||||
<el-input
|
||||
v-model="param._optionText"
|
||||
placeholder="例如:阴性,阳性,待复核"
|
||||
@input="syncOptions"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { watch } from 'vue'
|
||||
import type { QcItemParam } from '@/api/qc-item-param'
|
||||
import {
|
||||
formatQcParamOptionText,
|
||||
parseQcParamOptionText
|
||||
} from '@/utils/qc-item-param-options'
|
||||
|
||||
const param = defineModel<QcItemParam>('param', { required: true })
|
||||
|
||||
function ensureOptionText() {
|
||||
if (param.value._optionText === undefined) {
|
||||
param.value._optionText = formatQcParamOptionText(
|
||||
param.value.options,
|
||||
param.value.defaultValue
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function syncOptions() {
|
||||
const list = parseQcParamOptionText(param.value._optionText)
|
||||
param.value.options = list.length ? JSON.stringify(list) : undefined
|
||||
param.value.defaultValue = list[0] || undefined
|
||||
}
|
||||
|
||||
watch(
|
||||
() => param.value.paramType,
|
||||
() => {
|
||||
if (param.value.paramType === 'select') {
|
||||
ensureOptionText()
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.qc-param-select-editor {
|
||||
padding: 8px 0 4px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.qc-param-select-editor__head {
|
||||
font-size: 12px;
|
||||
color: var(--mint-text-muted, #64748b);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
}
|
||||
</style>
|
||||
@@ -110,6 +110,7 @@
|
||||
qcTaskConclusionLabel
|
||||
} from '@/utils/qc-labels'
|
||||
import { downloadAttachmentFile } from '@/utils/download-attachment'
|
||||
import { fetchQcInspectionBatches, loadQcInspectionBatches } from '@/utils/qc-inspection-batch'
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean
|
||||
@@ -140,6 +141,8 @@
|
||||
const loading = ref(false)
|
||||
const viewDetail = ref<QcTaskDetail | null>(null)
|
||||
const viewMaterialUsages = ref<ViewMaterialUsageRow[]>([])
|
||||
const viewBatchName = ref('')
|
||||
const viewBatchNo = ref('')
|
||||
const minioBaseUrl = (import.meta.env.VITE_MINIO_BASE_URL || '').replace(/\/$/, '')
|
||||
|
||||
function materialRowsFromApi(items: QcTaskMaterialUsageItem[]): ViewMaterialUsageRow[] {
|
||||
@@ -162,11 +165,28 @@
|
||||
if (!vis || !id) {
|
||||
viewDetail.value = null
|
||||
viewMaterialUsages.value = []
|
||||
viewBatchName.value = ''
|
||||
viewBatchNo.value = ''
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
try {
|
||||
const detail = await fetchQcTaskDetail(id)
|
||||
viewBatchName.value = ''
|
||||
viewBatchNo.value = ''
|
||||
const batchId = (detail.batchId || '').trim()
|
||||
const workOrderId = (detail.workOrderId || '').trim()
|
||||
if (batchId && workOrderId) {
|
||||
try {
|
||||
const batches = await loadQcInspectionBatches(workOrderId)
|
||||
const batch = batches.find((b) => b.id === batchId)
|
||||
viewBatchName.value = batch?.batchName || ''
|
||||
viewBatchNo.value = batch?.batchNo || ''
|
||||
} catch {
|
||||
viewBatchName.value = ''
|
||||
viewBatchNo.value = ''
|
||||
}
|
||||
}
|
||||
try {
|
||||
const results = await fetchQcTaskResults(id)
|
||||
;(detail as QcTaskDetail).results = results || []
|
||||
@@ -188,6 +208,8 @@
|
||||
} catch {
|
||||
viewDetail.value = null
|
||||
viewMaterialUsages.value = []
|
||||
viewBatchName.value = ''
|
||||
viewBatchNo.value = ''
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -360,6 +382,14 @@
|
||||
tagType: qcBizTypeTagType(d.qcBizType || '')
|
||||
},
|
||||
{ label: '工单号', value: d.workOrderNo || '—' },
|
||||
...(viewBatchName.value || viewBatchNo.value
|
||||
? [
|
||||
{
|
||||
label: '检测批次',
|
||||
value: [viewBatchName.value, viewBatchNo.value].filter(Boolean).join(' · ')
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{
|
||||
label: '工单状态',
|
||||
value: d.workOrderStatus ? workOrderStatusLabel(d.workOrderStatus) : '—',
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
<!-- 样本查看 — 质检信息按检测批次只读展示 -->
|
||||
<template>
|
||||
<div class="sample-qc-batch-readonly" v-loading="loading">
|
||||
<template v-if="batchSections.length">
|
||||
<el-tabs
|
||||
v-model="activeBatchKey"
|
||||
class="panel-pill-tabs panel-pill-tabs--start sample-qc-batch-readonly__tabs"
|
||||
>
|
||||
<el-tab-pane
|
||||
v-for="section in batchSections"
|
||||
:key="section.key"
|
||||
:name="section.key"
|
||||
>
|
||||
<template #label>
|
||||
<span class="sample-qc-batch-readonly__tab-label">{{ section.batchName }}</span>
|
||||
<span class="sample-qc-batch-readonly__tab-count">
|
||||
{{ section.completedTaskCount }}/{{ section.taskCount }}
|
||||
</span>
|
||||
</template>
|
||||
<div
|
||||
v-if="section.batchNo || section.assigneeUserNames"
|
||||
class="sample-qc-batch-readonly__meta"
|
||||
>
|
||||
<span v-if="section.batchNo" class="sample-qc-batch-readonly__meta-item">{{
|
||||
section.batchNo
|
||||
}}</span>
|
||||
<span v-if="section.assigneeUserNames" class="sample-qc-batch-readonly__meta-item">
|
||||
负责人:{{ section.assigneeUserNames }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="qc-detail-cards qc-detail-cards--tasks">
|
||||
<div
|
||||
v-for="task in section.tasks"
|
||||
:key="task.id || `${section.key}-${task.taskNo}`"
|
||||
class="qc-detail-card qc-detail-card--task"
|
||||
>
|
||||
<div class="qc-detail-card__header">
|
||||
<span class="qc-detail-card__name">{{ task.itemName || '—' }}</span>
|
||||
<el-tag :type="taskTypeTagType(task.taskType || '')" size="small">{{
|
||||
task.taskTypeLabel || taskTypeLabel(task.taskType || '')
|
||||
}}</el-tag>
|
||||
</div>
|
||||
<div class="qc-detail-card__body">
|
||||
<div class="qc-kv">
|
||||
<span class="qc-kv__label">任务号</span>
|
||||
<span class="qc-kv__value">{{ task.taskNo || '—' }}</span>
|
||||
</div>
|
||||
<div class="qc-kv">
|
||||
<span class="qc-kv__label">任务状态</span>
|
||||
<span class="qc-kv__value">
|
||||
<el-tag :type="taskStatusTagType(task.taskStatus)" size="small">
|
||||
{{ task.taskStatusLabel || taskStatusLabel(task.taskStatus || '') }}
|
||||
</el-tag>
|
||||
</span>
|
||||
</div>
|
||||
<div class="qc-kv">
|
||||
<span class="qc-kv__label">检测结论</span>
|
||||
<span class="qc-kv__value">
|
||||
<el-tag
|
||||
v-if="task.conclusion"
|
||||
:type="qcTaskConclusionTagType(task.conclusion)"
|
||||
size="small"
|
||||
>
|
||||
{{ task.conclusionLabel || qcTaskConclusionLabel(task.conclusion) }}
|
||||
</el-tag>
|
||||
<span v-else class="qc-kv__muted">—</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="task.id" class="qc-detail-card__foot">
|
||||
<button type="button" class="qc-detail-card__link" @click.stop="emit('view-task', task)">
|
||||
点击查看详情
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
<div v-else-if="!loading" class="sample-qc-batch-readonly__empty hint-muted">
|
||||
暂无检测批次或任务
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import {
|
||||
taskTypeLabel,
|
||||
taskTypeTagType,
|
||||
taskStatusLabel,
|
||||
qcTaskConclusionLabel,
|
||||
qcTaskConclusionTagType
|
||||
} from '@/utils/qc-labels'
|
||||
import { taskStatusTagType } from '@/utils/status-tag-registry'
|
||||
import { loadQcInspectionBatches, resolveBatchSections,
|
||||
type QcBatchTaskSection,
|
||||
type QcInspectionBatch
|
||||
} from '@/utils/qc-inspection-batch'
|
||||
|
||||
export type SampleQcBatchTask = {
|
||||
id?: string
|
||||
taskNo?: string
|
||||
taskType?: string
|
||||
taskTypeLabel?: string
|
||||
itemName?: string
|
||||
taskStatus?: string
|
||||
taskStatusLabel?: string
|
||||
conclusion?: string
|
||||
conclusionLabel?: string
|
||||
batchId?: string
|
||||
}
|
||||
|
||||
defineOptions({ name: 'SampleQcBatchReadonly' })
|
||||
|
||||
const props = defineProps<{
|
||||
workOrderId?: string
|
||||
tasks?: SampleQcBatchTask[]
|
||||
inspectionBatches?: QcInspectionBatch[]
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'view-task': [task: SampleQcBatchTask]
|
||||
}>()
|
||||
|
||||
const loading = ref(false)
|
||||
const batches = ref<QcInspectionBatch[]>([])
|
||||
const batchSections = ref<QcBatchTaskSection<SampleQcBatchTask>[]>([])
|
||||
const activeBatchKey = ref('')
|
||||
|
||||
function ensureActiveBatchKey(sections: QcBatchTaskSection<SampleQcBatchTask>[]) {
|
||||
if (!sections.length) {
|
||||
activeBatchKey.value = ''
|
||||
return
|
||||
}
|
||||
const keys = new Set(sections.map((s) => s.key))
|
||||
if (!keys.has(activeBatchKey.value)) {
|
||||
activeBatchKey.value = sections[0].key
|
||||
}
|
||||
}
|
||||
|
||||
function syncSections() {
|
||||
batchSections.value = resolveBatchSections(props.inspectionBatches || batches.value, props.tasks)
|
||||
ensureActiveBatchKey(batchSections.value)
|
||||
}
|
||||
|
||||
async function loadBatches() {
|
||||
const woId = (props.workOrderId || '').trim()
|
||||
if (props.inspectionBatches?.length) {
|
||||
batches.value = []
|
||||
syncSections()
|
||||
return
|
||||
}
|
||||
if (!woId) {
|
||||
batches.value = []
|
||||
syncSections()
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
try {
|
||||
batches.value = await loadQcInspectionBatches(woId)
|
||||
} catch {
|
||||
batches.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
syncSections()
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [props.workOrderId, props.tasks, props.inspectionBatches] as const,
|
||||
() => {
|
||||
if (props.inspectionBatches?.length) {
|
||||
batches.value = []
|
||||
syncSections()
|
||||
return
|
||||
}
|
||||
if (props.workOrderId) {
|
||||
loadBatches()
|
||||
return
|
||||
}
|
||||
syncSections()
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.sample-qc-batch-readonly__tabs {
|
||||
&.panel-pill-tabs.el-tabs > :deep(.el-tabs__header) {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
&.panel-pill-tabs.el-tabs :deep(.el-tabs__nav-scroll) {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
&.panel-pill-tabs.el-tabs :deep(.el-tabs__item) {
|
||||
min-width: 96px;
|
||||
padding: 6px 14px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.sample-qc-batch-readonly__tab-label {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.sample-qc-batch-readonly__tab-count {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.sample-qc-batch-readonly__meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px 16px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 12px;
|
||||
color: var(--mint-text-muted, #64748b);
|
||||
}
|
||||
|
||||
.sample-qc-batch-readonly__empty {
|
||||
padding: 8px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.qc-detail-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
||||
gap: 10px;
|
||||
|
||||
&--tasks {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.qc-detail-card {
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.qc-detail-card__header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
}
|
||||
|
||||
.qc-detail-card__name {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
text-align: left;
|
||||
flex: 1;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.qc-detail-card__body {
|
||||
padding: 10px 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.qc-detail-card__foot {
|
||||
padding: 2px 12px 8px;
|
||||
text-align: right;
|
||||
border-top: 1px dashed #f1f5f9;
|
||||
}
|
||||
|
||||
.qc-detail-card__link {
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
font-size: 11px;
|
||||
line-height: 1.4;
|
||||
color: #047857;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #065f46;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.qc-kv__muted {
|
||||
color: var(--mint-text-muted, #334155);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.qc-kv {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.qc-kv__label {
|
||||
color: var(--mint-text-muted, #334155);
|
||||
flex-shrink: 0;
|
||||
min-width: 56px;
|
||||
}
|
||||
|
||||
.qc-kv__value {
|
||||
color: #1e293b;
|
||||
font-weight: 500;
|
||||
word-break: break-word;
|
||||
}
|
||||
</style>
|
||||
@@ -32,56 +32,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="qcInfo.workOrderStatus === 'dpz' && !qcInfo.tasks?.length" class="sample-qc-hint">
|
||||
<div
|
||||
v-if="qcInfo.workOrderStatus === 'dpz' && !hasTaskContent"
|
||||
class="sample-qc-hint"
|
||||
>
|
||||
工单待配置检测项目
|
||||
</div>
|
||||
|
||||
<div v-if="qcInfo.tasks?.length" class="qc-detail-cards qc-detail-cards--tasks">
|
||||
<div
|
||||
v-for="task in qcInfo.tasks"
|
||||
:key="task.id"
|
||||
class="qc-detail-card qc-detail-card--task"
|
||||
>
|
||||
<div class="qc-detail-card__header">
|
||||
<span class="qc-detail-card__name">{{ task.itemName || '—' }}</span>
|
||||
<el-tag :type="taskTypeTagType(task.taskType || '')" size="small">{{
|
||||
task.taskTypeLabel || taskTypeLabel(task.taskType || '')
|
||||
}}</el-tag>
|
||||
</div>
|
||||
<div class="qc-detail-card__body">
|
||||
<div class="qc-kv">
|
||||
<span class="qc-kv__label">任务号</span>
|
||||
<span class="qc-kv__value">{{ task.taskNo || '—' }}</span>
|
||||
</div>
|
||||
<div class="qc-kv">
|
||||
<span class="qc-kv__label">任务状态</span>
|
||||
<span class="qc-kv__value">
|
||||
<el-tag :type="taskStatusTagType(task.taskStatus)" size="small">
|
||||
{{ task.taskStatusLabel || taskStatusLabel(task.taskStatus || '') }}
|
||||
</el-tag>
|
||||
</span>
|
||||
</div>
|
||||
<div class="qc-kv">
|
||||
<span class="qc-kv__label">检测结论</span>
|
||||
<span class="qc-kv__value">
|
||||
<el-tag
|
||||
v-if="task.conclusion"
|
||||
:type="qcTaskConclusionTagType(task.conclusion)"
|
||||
size="small"
|
||||
>
|
||||
{{ task.conclusionLabel || qcTaskConclusionLabel(task.conclusion) }}
|
||||
</el-tag>
|
||||
<span v-else class="qc-kv__muted">—</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="qc-detail-card__foot">
|
||||
<button type="button" class="qc-detail-card__link" @click.stop="openTaskView(task)">
|
||||
点击查看详情
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<SampleQcBatchReadonly
|
||||
v-if="hasTaskContent"
|
||||
:work-order-id="qcInfo.id"
|
||||
:tasks="qcInfo.tasks"
|
||||
:inspection-batches="qcInfo.inspectionBatches"
|
||||
@view-task="openTaskView"
|
||||
/>
|
||||
|
||||
<div v-else-if="qcInfo.workOrderStatus !== 'dpz'" class="sample-qc-hint"> 暂无检测任务 </div>
|
||||
</template>
|
||||
@@ -98,17 +62,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import {
|
||||
qcBizTypeLabel,
|
||||
workOrderStatusLabel,
|
||||
taskTypeLabel,
|
||||
taskTypeTagType,
|
||||
taskStatusLabel,
|
||||
qcTaskConclusionLabel,
|
||||
qcTaskConclusionTagType
|
||||
} from '@/utils/qc-labels'
|
||||
import { workOrderStatusTagType, taskStatusTagType } from '@/utils/status-tag-registry'
|
||||
import { qcBizTypeLabel, workOrderStatusLabel } from '@/utils/qc-labels'
|
||||
import { workOrderStatusTagType } from '@/utils/status-tag-registry'
|
||||
import type { QcInspectionBatch } from '@/utils/qc-inspection-batch'
|
||||
import QcTaskViewDialog from '@/components/business/qc-task-view-dialog/index.vue'
|
||||
import SampleQcBatchReadonly from '@/components/business/sample-qc-batch-readonly/index.vue'
|
||||
|
||||
export type SampleQcTask = {
|
||||
id?: string
|
||||
@@ -124,9 +82,11 @@
|
||||
conclusionLabel?: string
|
||||
completedTime?: string
|
||||
remark?: string
|
||||
batchId?: string
|
||||
}
|
||||
|
||||
export type SampleQcInfo = {
|
||||
id?: string
|
||||
workOrderNo?: string
|
||||
workOrderStatus?: string
|
||||
workOrderStatusLabel?: string
|
||||
@@ -147,6 +107,7 @@
|
||||
itemName?: string
|
||||
companyName?: string
|
||||
}>
|
||||
inspectionBatches?: QcInspectionBatch[]
|
||||
tasks?: SampleQcTask[]
|
||||
}
|
||||
|
||||
@@ -172,6 +133,11 @@
|
||||
const taskViewVisible = ref(false)
|
||||
const taskViewId = ref('')
|
||||
|
||||
const hasTaskContent = computed(
|
||||
() =>
|
||||
!!(props.qcInfo?.inspectionBatches?.length || props.qcInfo?.tasks?.length)
|
||||
)
|
||||
|
||||
const emptyHint = computed(() => {
|
||||
const rec = props.sampleReception
|
||||
if (!rec) {
|
||||
@@ -236,74 +202,6 @@
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
.qc-detail-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
||||
gap: 10px;
|
||||
|
||||
&--tasks {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.qc-detail-card {
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.qc-detail-card__header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
}
|
||||
|
||||
.qc-detail-card__name {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
text-align: left;
|
||||
flex: 1;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.qc-detail-card__body {
|
||||
padding: 10px 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.qc-detail-card__foot {
|
||||
padding: 2px 12px 8px;
|
||||
text-align: right;
|
||||
border-top: 1px dashed #f1f5f9;
|
||||
}
|
||||
|
||||
.qc-detail-card__link {
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
font-size: 11px;
|
||||
line-height: 1.4;
|
||||
color: #047857;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #065f46;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.qc-kv__muted {
|
||||
color: var(--mint-text-muted, #334155);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.qc-kv {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
|
||||
+49
-4
@@ -4,8 +4,12 @@
|
||||
<ArtSvgIcon :icon="item.meta.icon" :color="theme?.iconColor" class="mr-1 text-lg" />
|
||||
<span class="text-md">{{ formatMenuTitle(item.meta.title) }}</span>
|
||||
<div v-if="item.meta.showBadge" class="art-badge art-badge-horizontal" />
|
||||
<div v-if="item.meta.showTextBadge" class="art-text-badge">
|
||||
{{ item.meta.showTextBadge }}
|
||||
<div
|
||||
v-if="resolveMenuTextBadge(item)"
|
||||
class="art-text-badge"
|
||||
:class="menuTextBadgeClass(item)"
|
||||
>
|
||||
{{ resolveMenuTextBadge(item) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -38,8 +42,8 @@
|
||||
class="art-badge"
|
||||
:style="{ right: level === 0 ? '10px' : '20px' }"
|
||||
/>
|
||||
<div v-if="item.meta.showTextBadge && level !== 0" class="art-text-badge">
|
||||
{{ item.meta.showTextBadge }}
|
||||
<div v-if="resolveMenuTextBadge(item)" class="art-text-badge" :class="menuTextBadgeClass(item)">
|
||||
{{ resolveMenuTextBadge(item) }}
|
||||
</div>
|
||||
</ElMenuItem>
|
||||
</template>
|
||||
@@ -49,6 +53,12 @@
|
||||
import { AppRouteRecord } from '@/types/router'
|
||||
import { handleMenuJump } from '@/utils/navigation'
|
||||
import { formatMenuTitle } from '@/utils/router'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useQcMenuBadgeStore } from '@/store/modules/qc-menu-badge'
|
||||
import { useProductionMenuBadgeStore } from '@/store/modules/production-menu-badge'
|
||||
import { resolveQcMenuBadgeCode } from '@/utils/qc-menu-badge'
|
||||
import { resolveProductionMenuBadgeCode } from '@/utils/production-menu-badge'
|
||||
import { formatQcWorkOrderTabBadgeCount } from '@/api/qc-work-order'
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
@@ -67,6 +77,41 @@
|
||||
})
|
||||
|
||||
const emit = defineEmits(['close'])
|
||||
const qcMenuBadgeStore = useQcMenuBadgeStore()
|
||||
const productionMenuBadgeStore = useProductionMenuBadgeStore()
|
||||
const { loadedMenuCodes, badgeByMenuCode } = storeToRefs(qcMenuBadgeStore)
|
||||
const { loadedMenuCodes: productionLoadedMenuCodes } = storeToRefs(productionMenuBadgeStore)
|
||||
|
||||
function resolveMenuTextBadge(item: AppRouteRecord): string {
|
||||
const productionMenuCode = resolveProductionMenuBadgeCode(item)
|
||||
if (productionMenuCode && productionLoadedMenuCodes.value.includes(productionMenuCode)) {
|
||||
return productionMenuBadgeStore.getBadgeText(productionMenuCode)
|
||||
}
|
||||
const menuCode = resolveQcMenuBadgeCode(item)
|
||||
if (menuCode && loadedMenuCodes.value.includes(menuCode)) {
|
||||
const count = badgeByMenuCode.value[menuCode] ?? 0
|
||||
return formatQcWorkOrderTabBadgeCount(count)
|
||||
}
|
||||
if (item.meta.showTextBadge && props.level !== 0) {
|
||||
return item.meta.showTextBadge
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function menuTextBadgeClass(item: AppRouteRecord): Record<string, boolean> {
|
||||
const productionMenuCode = resolveProductionMenuBadgeCode(item)
|
||||
if (productionMenuCode && productionLoadedMenuCodes.value.includes(productionMenuCode)) {
|
||||
return {
|
||||
'art-text-badge--zero': productionMenuBadgeStore.isBadgeZero(productionMenuCode),
|
||||
'art-text-badge--dual': true
|
||||
}
|
||||
}
|
||||
const menuCode = resolveQcMenuBadgeCode(item)
|
||||
if (menuCode && loadedMenuCodes.value.includes(menuCode)) {
|
||||
return { 'art-text-badge--zero': (badgeByMenuCode.value[menuCode] ?? 0) === 0 }
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
// 过滤后的子菜单项(不包含隐藏的)
|
||||
const filteredChildren = computed(() => {
|
||||
|
||||
@@ -157,6 +157,7 @@ $popup-menu-radius: 6px;
|
||||
// 菜单高度
|
||||
.el-sub-menu__title,
|
||||
.el-menu-item {
|
||||
position: relative;
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
@@ -165,6 +166,15 @@ $popup-menu-radius: 6px;
|
||||
line-height: $menu-height !important;
|
||||
overflow: hidden !important;
|
||||
|
||||
.menu-title-wrap {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
padding-right: 28px;
|
||||
}
|
||||
|
||||
.menu-name {
|
||||
flex-shrink: 1;
|
||||
min-width: 0;
|
||||
|
||||
+53
-6
@@ -54,12 +54,18 @@
|
||||
/>
|
||||
|
||||
<template #title>
|
||||
<span class="menu-name">
|
||||
{{ formatMenuTitle(item.meta.title) }}
|
||||
</span>
|
||||
<div v-if="item.meta.showBadge" class="art-badge" />
|
||||
<div v-if="item.meta.showTextBadge && (level > 0 || menuOpen)" class="art-text-badge">
|
||||
{{ item.meta.showTextBadge }}
|
||||
<div class="menu-title-wrap">
|
||||
<span class="menu-name">
|
||||
{{ formatMenuTitle(item.meta.title) }}
|
||||
</span>
|
||||
<div v-if="item.meta.showBadge" class="art-badge" />
|
||||
<div
|
||||
v-if="resolveMenuTextBadge(item)"
|
||||
class="art-text-badge"
|
||||
:class="menuTextBadgeClass(item)"
|
||||
>
|
||||
{{ resolveMenuTextBadge(item) }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</ElMenuItem>
|
||||
@@ -73,6 +79,11 @@
|
||||
import { filterSidebarRoutes } from '@/utils/router/sidebar-menu-filter'
|
||||
import { handleMenuJump } from '@/utils/navigation'
|
||||
import { useSettingStore } from '@/store/modules/setting'
|
||||
import { useQcMenuBadgeStore } from '@/store/modules/qc-menu-badge'
|
||||
import { useProductionMenuBadgeStore } from '@/store/modules/production-menu-badge'
|
||||
import { resolveQcMenuBadgeCode } from '@/utils/qc-menu-badge'
|
||||
import { resolveProductionMenuBadgeCode } from '@/utils/production-menu-badge'
|
||||
import { formatQcWorkOrderTabBadgeCount } from '@/api/qc-work-order'
|
||||
|
||||
interface MenuTheme {
|
||||
iconColor?: string
|
||||
@@ -107,8 +118,12 @@
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
const qcMenuBadgeStore = useQcMenuBadgeStore()
|
||||
const productionMenuBadgeStore = useProductionMenuBadgeStore()
|
||||
|
||||
const { menuOpen } = storeToRefs(settingStore)
|
||||
const { loadedMenuCodes, badgeByMenuCode } = storeToRefs(qcMenuBadgeStore)
|
||||
const { loadedMenuCodes: productionLoadedMenuCodes } = storeToRefs(productionMenuBadgeStore)
|
||||
|
||||
/**
|
||||
* 过滤后的菜单项列表
|
||||
@@ -116,6 +131,38 @@
|
||||
*/
|
||||
const filteredMenuItems = computed(() => filterSidebarRoutes(props.list || []))
|
||||
|
||||
function resolveMenuTextBadge(item: AppRouteRecord): string {
|
||||
const productionMenuCode = resolveProductionMenuBadgeCode(item)
|
||||
if (productionMenuCode && productionLoadedMenuCodes.value.includes(productionMenuCode)) {
|
||||
return productionMenuBadgeStore.getBadgeText(productionMenuCode)
|
||||
}
|
||||
const menuCode = resolveQcMenuBadgeCode(item)
|
||||
if (menuCode && loadedMenuCodes.value.includes(menuCode)) {
|
||||
const count = badgeByMenuCode.value[menuCode] ?? 0
|
||||
return formatQcWorkOrderTabBadgeCount(count)
|
||||
}
|
||||
const staticBadge = item.meta.showTextBadge
|
||||
if (staticBadge && (props.level > 0 || menuOpen.value)) {
|
||||
return staticBadge
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function menuTextBadgeClass(item: AppRouteRecord): Record<string, boolean> {
|
||||
const productionMenuCode = resolveProductionMenuBadgeCode(item)
|
||||
if (productionMenuCode && productionLoadedMenuCodes.value.includes(productionMenuCode)) {
|
||||
return {
|
||||
'art-text-badge--zero': productionMenuBadgeStore.isBadgeZero(productionMenuCode),
|
||||
'art-text-badge--dual': true
|
||||
}
|
||||
}
|
||||
const menuCode = resolveQcMenuBadgeCode(item)
|
||||
if (menuCode && loadedMenuCodes.value.includes(menuCode)) {
|
||||
return { 'art-text-badge--zero': (badgeByMenuCode.value[menuCode] ?? 0) === 0 }
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到指定页面
|
||||
* @param item 菜单项数据
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_composables_useqcworkordertabpage_ts", "label": "useQcWorkOrderTabPage.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L1"}, {"id": "composables_useqcworkordertabpage_shouldapplytriggersourcefilter", "label": "shouldApplyTriggerSourceFilter()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L26"}, {"id": "composables_useqcworkordertabpage_useqcworkordertabpage", "label": "useQcWorkOrderTabPage()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L33"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_composables_useqcworkordertabpage_ts", "target": "vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_composables_useqcworkordertabpage_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_composables_useqcworkordertabpage_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_task", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L3", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_composables_useqcworkordertabpage_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_mine_task_groups", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_composables_useqcworkordertabpage_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_work_order_tabs", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L12", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_composables_useqcworkordertabpage_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_work_order_category", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L23", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_composables_useqcworkordertabpage_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_work_order_card_meta", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L24", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_composables_useqcworkordertabpage_ts", "target": "composables_useqcworkordertabpage_shouldapplytriggersourcefilter", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L26", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_composables_useqcworkordertabpage_ts", "target": "composables_useqcworkordertabpage_useqcworkordertabpage", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/composables/useQcWorkOrderTabPage.ts", "source_location": "L33", "weight": 1.0}], "raw_caLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_storage_release_review_ts", "label": "storage-release-review.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L1"}, {"id": "api_storage_release_review_fetchstoragereleasereviewlist", "label": "fetchStorageReleaseReviewList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L137"}, {"id": "api_storage_release_review_fetchstoragereleasereviewdetail", "label": "fetchStorageReleaseReviewDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L151"}, {"id": "api_storage_release_review_submitstoragereleasereview", "label": "submitStorageReleaseReview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L157"}, {"id": "api_storage_release_review_batchreviewstoragerelease", "label": "batchReviewStorageRelease()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L171"}, {"id": "api_storage_release_review_storesample", "label": "storeSample()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L183"}, {"id": "api_storage_release_review_batchstoresample", "label": "batchStoreSample()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L189"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_storage_release_review_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_http", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_storage_release_review_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_storage_release_review_ts", "target": "api_storage_release_review_fetchstoragereleasereviewlist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L137", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_storage_release_review_ts", "target": "api_storage_release_review_fetchstoragereleasereviewdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L151", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_storage_release_review_ts", "target": "api_storage_release_review_submitstoragereleasereview", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L157", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_storage_release_review_ts", "target": "api_storage_release_review_batchreviewstoragerelease", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L171", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_storage_release_review_ts", "target": "api_storage_release_review_storesample", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L183", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_storage_release_review_ts", "target": "api_storage_release_review_batchstoresample", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L189", "weight": 1.0}], "raw_calls": [{"caller_nid": "api_storage_release_review_fetchstoragereleasereviewlist", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L145"}, {"caller_nid": "api_storage_release_review_fetchstoragereleasereviewdetail", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts", "source_location": "L152"}, {"caller_nid": "api_storage_release_revLine truncated
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "label": "outbound-release-review.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L1"}, {"id": "api_outbound_release_review_fetchoutboundreleasereviewlist", "label": "fetchOutboundReleaseReviewList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L164"}, {"id": "api_outbound_release_review_fetchoutboundreleasereviewdetail", "label": "fetchOutboundReleaseReviewDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L182"}, {"id": "api_outbound_release_review_submitoutboundreleasereview", "label": "submitOutboundReleaseReview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L188"}, {"id": "api_outbound_release_review_batchreviewoutboundrelease", "label": "batchReviewOutboundRelease()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L202"}, {"id": "api_outbound_release_review_fetchoutboundreleasematerial", "label": "fetchOutboundReleaseMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L214"}, {"id": "api_outbound_release_review_fetchreleasereviewlist", "label": "fetchReleaseReviewList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L220"}, {"id": "api_outbound_release_review_updatereleasereview", "label": "updateReleaseReview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L226"}, {"id": "api_outbound_release_review_deletereleasereview", "label": "deleteReleaseReview()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L233"}, {"id": "api_outbound_release_review_saveoutboundreleasematerial", "label": "saveOutboundReleaseMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L239"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_http", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_qc_inspection_batch", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L9", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_fetchoutboundreleasereviewlist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L164", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_fetchoutboundreleasereviewdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L182", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_submitoutboundreleasereview", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_location": "L188", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_outbound_release_review_ts", "target": "api_outbound_release_review_batchreviewoutboundrelease", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/outbound-release-review.ts", "source_locaLine truncated
|
||||
Loaded 100 of 323 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user