This commit is contained in:
zlwu committed 2026-05-20 21:12:16 +08:00
1 parent e6b4b9a8d7
commit 6272d107dc
29 files changed
+5840 -4504

No files matched your search

+1 -1
View File
@@ -1 +1 @@
51733 82445
+29 -4
View File
@@ -6,6 +6,7 @@ from typing import Any, List, Optional
from fastapi import APIRouter, Depends, Query from fastapi import APIRouter, Depends, Query
from pydantic import BaseModel, ConfigDict, Field from pydantic import BaseModel, ConfigDict, Field
from sqlalchemy import or_
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app.core.database import get_db from app.core.database import get_db
@@ -121,14 +122,31 @@ def _row_to_dict_project_price(row: BizInsuranceProjectPrice) -> dict:
def _list_insurance_companies( def _list_insurance_companies(
db: Session, *, page: int, page_size: int, keyword: Optional[str], tenant_no: str, user_info=None db: Session,
*,
page: int,
page_size: int,
keyword: Optional[str],
status: Optional[str],
tenant_no: str,
user_info=None,
): ):
q = db.query(BizInsuranceCompany).filter( q = db.query(BizInsuranceCompany).filter(
BizInsuranceCompany.tenant_no == tenant_no, BizInsuranceCompany.tenant_no == tenant_no,
BizInsuranceCompany.del_flag == 0, BizInsuranceCompany.del_flag == 0,
) )
if keyword: kw = (keyword or "").strip()
q = q.filter(BizInsuranceCompany.company_name.like(f"%{keyword}%")) if kw:
like = f"%{kw}%"
q = q.filter(
or_(
BizInsuranceCompany.company_name.like(like),
BizInsuranceCompany.contact_name.like(like),
)
)
st = (status or "").strip()
if st in ("0", "1"):
q = q.filter(BizInsuranceCompany.status == st)
if user_info: if user_info:
from app.core.data_scope import apply_data_scope from app.core.data_scope import apply_data_scope
q = apply_data_scope(q, BizInsuranceCompany, user_info, db, tenant_no) q = apply_data_scope(q, BizInsuranceCompany, user_info, db, tenant_no)
@@ -532,12 +550,19 @@ async def list_insurance_companies(
page: int = Query(1, ge=1), page: int = Query(1, ge=1),
pageSize: int = Query(10, ge=1, le=100, alias="pageSize"), pageSize: int = Query(10, ge=1, le=100, alias="pageSize"),
keyword: Optional[str] = None, keyword: Optional[str] = None,
status: Optional[str] = None,
user: dict = Depends(require_admin_or_super_admin), user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db), db: Session = Depends(get_db),
): ):
tenant_no = _get_tenant_no(db, user) tenant_no = _get_tenant_no(db, user)
items, total = _list_insurance_companies( items, total = _list_insurance_companies(
db, page=page, page_size=pageSize, keyword=keyword, tenant_no=tenant_no, user_info=user db,
page=page,
page_size=pageSize,
keyword=keyword,
status=status,
tenant_no=tenant_no,
user_info=user,
) )
tp = _total_pages(total, pageSize) tp = _total_pages(total, pageSize)
return success_response( return success_response(
+119 -3
View File
@@ -1,5 +1,6 @@
"""市场物料库 API""" """市场物料库 API"""
from typing import Optional from datetime import datetime
from typing import List, Optional
from fastapi import APIRouter, Depends, Query from fastapi import APIRouter, Depends, Query
from pydantic import BaseModel, ConfigDict, Field from pydantic import BaseModel, ConfigDict, Field
@@ -7,6 +8,7 @@ from sqlalchemy.orm import Session
from app.api.sample_reception import _get_current_user_id, _get_tenant_no, _page_payload from app.api.sample_reception import _get_current_user_id, _get_tenant_no, _page_payload
from app.core.database import get_db from app.core.database import get_db
from app.core.utils import parse_datetime
from app.core.menu_guard import require_admin_or_super_admin, require_menu_code from app.core.menu_guard import require_admin_or_super_admin, require_menu_code
from app.core.response import error_response, success_response from app.core.response import error_response, success_response
from app.crud import material as mat_svc from app.crud import material as mat_svc
@@ -48,6 +50,7 @@ class StockInBody(BaseModel):
model_config = ConfigDict(populate_by_name=True) model_config = ConfigDict(populate_by_name=True)
qty: float = Field(..., gt=0) qty: float = Field(..., gt=0)
remark: Optional[str] = None remark: Optional[str] = None
stock_in_time: Optional[str] = Field(None, alias="stockInTime")
class StockOutBody(BaseModel): class StockOutBody(BaseModel):
@@ -56,6 +59,37 @@ class StockOutBody(BaseModel):
receiver: Optional[str] = None receiver: Optional[str] = None
purpose: Optional[str] = None purpose: Optional[str] = None
remark: Optional[str] = None remark: Optional[str] = None
stock_out_time: Optional[str] = Field(None, alias="stockOutTime")
class BatchStockInItem(BaseModel):
model_config = ConfigDict(populate_by_name=True)
material_id: str = Field(..., alias="materialId")
qty: float = Field(..., gt=0)
remark: Optional[str] = None
class BatchStockInBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
items: List[BatchStockInItem] = Field(..., min_length=1)
remark: Optional[str] = None
stock_in_time: Optional[str] = Field(None, alias="stockInTime")
class BatchStockOutItem(BaseModel):
model_config = ConfigDict(populate_by_name=True)
material_id: str = Field(..., alias="materialId")
qty: float = Field(..., gt=0)
remark: Optional[str] = None
class BatchStockOutBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
items: List[BatchStockOutItem] = Field(..., min_length=1)
receiver: Optional[str] = None
purpose: Optional[str] = None
remark: Optional[str] = None
stock_out_time: Optional[str] = Field(None, alias="stockOutTime")
# ---------- 物料 CRUD ---------- # ---------- 物料 CRUD ----------
@@ -154,6 +188,76 @@ async def delete_material(
return error_response(str(e)) return error_response(str(e))
@router.post("/materials/batch-stock-in")
async def batch_stock_in_material(
body: BatchStockInBody,
db: Session = Depends(get_db),
user: dict = Depends(require_menu_code("biz:material:list")),
):
try:
tenant_no = _get_tenant_no(db, user)
user_id = _get_current_user_id(user)
operate_time = datetime.now()
if body.stock_in_time:
rt = parse_datetime(body.stock_in_time)
if not rt:
return error_response("入库时间格式无效")
operate_time = rt
items = [
{"material_id": x.material_id, "qty": x.qty, "remark": x.remark}
for x in body.items
]
count = mat_svc.batch_stock_in(
db,
items=items,
remark=body.remark,
tenant_no=tenant_no,
user_id=user_id,
operate_time=operate_time,
)
return success_response({"count": count}, message=f"批量入库成功,共 {count} 项")
except ValueError as e:
return error_response(str(e))
except Exception as e:
return error_response(str(e))
@router.post("/materials/batch-stock-out")
async def batch_stock_out_material(
body: BatchStockOutBody,
db: Session = Depends(get_db),
user: dict = Depends(require_menu_code("biz:material:list")),
):
try:
tenant_no = _get_tenant_no(db, user)
user_id = _get_current_user_id(user)
operate_time = datetime.now()
if body.stock_out_time:
rt = parse_datetime(body.stock_out_time)
if not rt:
return error_response("出库时间格式无效")
operate_time = rt
items = [
{"material_id": x.material_id, "qty": x.qty, "remark": x.remark}
for x in body.items
]
count = mat_svc.batch_stock_out(
db,
items=items,
receiver=body.receiver,
purpose=body.purpose,
remark=body.remark,
tenant_no=tenant_no,
user_id=user_id,
operate_time=operate_time,
)
return success_response({"count": count}, message=f"批量出库成功,共 {count} 项")
except ValueError as e:
return error_response(str(e))
except Exception as e:
return error_response(str(e))
@router.post("/materials/{material_id}/stock-in") @router.post("/materials/{material_id}/stock-in")
async def stock_in_material( async def stock_in_material(
material_id: str, material_id: str,
@@ -164,9 +268,15 @@ async def stock_in_material(
try: try:
tenant_no = _get_tenant_no(db, user) tenant_no = _get_tenant_no(db, user)
user_id = _get_current_user_id(user) user_id = _get_current_user_id(user)
operate_time = datetime.now()
if body.stock_in_time:
rt = parse_datetime(body.stock_in_time)
if not rt:
return error_response("入库时间格式无效")
operate_time = rt
obj = mat_svc.stock_in( obj = mat_svc.stock_in(
db, material_id, qty=body.qty, remark=body.remark, db, material_id, qty=body.qty, remark=body.remark,
tenant_no=tenant_no, user_id=user_id, tenant_no=tenant_no, user_id=user_id, operate_time=operate_time,
) )
return success_response(obj, message="入库成功") return success_response(obj, message="入库成功")
except ValueError as e: except ValueError as e:
@@ -185,10 +295,16 @@ async def stock_out_material(
try: try:
tenant_no = _get_tenant_no(db, user) tenant_no = _get_tenant_no(db, user)
user_id = _get_current_user_id(user) user_id = _get_current_user_id(user)
operate_time = datetime.now()
if body.stock_out_time:
rt = parse_datetime(body.stock_out_time)
if not rt:
return error_response("出库时间格式无效")
operate_time = rt
obj = mat_svc.stock_out( obj = mat_svc.stock_out(
db, material_id, qty=body.qty, receiver=body.receiver, db, material_id, qty=body.qty, receiver=body.receiver,
purpose=body.purpose, remark=body.remark, purpose=body.purpose, remark=body.remark,
tenant_no=tenant_no, user_id=user_id, tenant_no=tenant_no, user_id=user_id, operate_time=operate_time,
) )
return success_response(obj, message="出库成功") return success_response(obj, message="出库成功")
except ValueError as e: except ValueError as e:
+171 -4
View File
@@ -260,6 +260,7 @@ def stock_in(
tenant_no: str, tenant_no: str,
user_id: Optional[str] = None, user_id: Optional[str] = None,
dept_id: str = "", dept_id: str = "",
operate_time: Optional[datetime] = None,
) -> Dict[str, Any]: ) -> Dict[str, Any]:
if qty is None or qty <= 0: if qty is None or qty <= 0:
raise ValueError("入库数量必须大于0") raise ValueError("入库数量必须大于0")
@@ -278,6 +279,7 @@ def stock_in(
if not obj: if not obj:
raise ValueError("物料不存在") raise ValueError("物料不存在")
op_time = operate_time or datetime.now()
stock_before = obj.stock_qty if obj.stock_qty is not None else Decimal("0") stock_before = obj.stock_qty if obj.stock_qty is not None else Decimal("0")
stock_after = stock_before + qty_dec stock_after = stock_before + qty_dec
obj.stock_qty = stock_after obj.stock_qty = stock_after
@@ -298,9 +300,9 @@ def stock_in(
remark=(remark or "").strip() or None, remark=(remark or "").strip() or None,
create_by=user_id, create_by=user_id,
create_dept_id=dept_id or "", create_dept_id=dept_id or "",
create_time=datetime.now(), create_time=op_time,
update_by=user_id, update_by=user_id,
update_time=datetime.now(), update_time=op_time,
del_flag=0, del_flag=0,
) )
db.add(log) db.add(log)
@@ -309,6 +311,82 @@ def stock_in(
return _row_to_dict(obj) return _row_to_dict(obj)
def batch_stock_in(
db: Session,
*,
items: List[Dict[str, Any]],
remark: Optional[str] = None,
tenant_no: str,
user_id: Optional[str] = None,
dept_id: str = "",
operate_time: Optional[datetime] = None,
) -> int:
"""批量入库,同一事务;任一条失败则全部回滚。"""
if not items:
raise ValueError("请至少选择一条物料")
op_time = operate_time or datetime.now()
shared_remark = (remark or "").strip() or None
try:
for it in items:
material_id = (it.get("material_id") or it.get("materialId") or "").strip()
qty = it.get("qty")
if not material_id:
raise ValueError("物料ID不能为空")
if qty is None or qty <= 0:
raise ValueError("入库数量必须大于0")
qty_dec = Decimal(str(qty))
line_remark = (it.get("remark") or "").strip()
log_remark = line_remark or shared_remark or None
obj = (
db.query(BizMaterial)
.filter(
BizMaterial.id == material_id,
BizMaterial.tenant_no == tenant_no,
BizMaterial.del_flag == 0,
)
.with_for_update()
.first()
)
if not obj:
raise ValueError("物料不存在")
if obj.status != "1":
raise ValueError(f"物料「{obj.material_name}」已停用,无法入库")
stock_before = obj.stock_qty if obj.stock_qty is not None else Decimal("0")
stock_after = stock_before + qty_dec
obj.stock_qty = stock_after
obj.update_by = user_id
obj.update_time = datetime.now()
db.add(obj)
log = BizMaterialStockLog(
id=generate_uuid(),
material_id=obj.id,
material_code=obj.material_code,
material_name=obj.material_name,
change_type="rk",
change_qty=qty_dec,
stock_before=stock_before,
stock_after=stock_after,
tenant_no=tenant_no,
remark=log_remark,
create_by=user_id,
create_dept_id=dept_id or "",
create_time=op_time,
update_by=user_id,
update_time=op_time,
del_flag=0,
)
db.add(log)
db.commit()
return len(items)
except Exception:
db.rollback()
raise
def stock_out( def stock_out(
db: Session, db: Session,
material_id: str, material_id: str,
@@ -320,6 +398,7 @@ def stock_out(
tenant_no: str, tenant_no: str,
user_id: Optional[str] = None, user_id: Optional[str] = None,
dept_id: str = "", dept_id: str = "",
operate_time: Optional[datetime] = None,
) -> Dict[str, Any]: ) -> Dict[str, Any]:
if qty is None or qty <= 0: if qty is None or qty <= 0:
raise ValueError("出库数量必须大于0") raise ValueError("出库数量必须大于0")
@@ -344,6 +423,7 @@ def stock_out(
f"物料「{obj.material_name}」库存不足,当前库存 {stock_before},需出库 {qty_dec}" f"物料「{obj.material_name}」库存不足,当前库存 {stock_before},需出库 {qty_dec}"
) )
op_time = operate_time or datetime.now()
stock_after = stock_before - qty_dec stock_after = stock_before - qty_dec
obj.stock_qty = stock_after obj.stock_qty = stock_after
obj.update_by = user_id obj.update_by = user_id
@@ -365,9 +445,9 @@ def stock_out(
remark=(remark or "").strip() or None, remark=(remark or "").strip() or None,
create_by=user_id, create_by=user_id,
create_dept_id=dept_id or "", create_dept_id=dept_id or "",
create_time=datetime.now(), create_time=op_time,
update_by=user_id, update_by=user_id,
update_time=datetime.now(), update_time=op_time,
del_flag=0, del_flag=0,
) )
db.add(log) db.add(log)
@@ -376,6 +456,93 @@ def stock_out(
return _row_to_dict(obj) return _row_to_dict(obj)
def batch_stock_out(
db: Session,
*,
items: List[Dict[str, Any]],
receiver: Optional[str] = None,
purpose: Optional[str] = None,
remark: Optional[str] = None,
tenant_no: str,
user_id: Optional[str] = None,
dept_id: str = "",
operate_time: Optional[datetime] = None,
) -> int:
"""批量出库,同一事务;任一条失败则全部回滚。"""
if not items:
raise ValueError("请至少选择一条物料")
op_time = operate_time or datetime.now()
shared_receiver = (receiver or "").strip() or None
shared_purpose = (purpose or "").strip() or None
shared_remark = (remark or "").strip() or None
try:
for it in items:
material_id = (it.get("material_id") or it.get("materialId") or "").strip()
qty = it.get("qty")
if not material_id:
raise ValueError("物料ID不能为空")
if qty is None or qty <= 0:
raise ValueError("出库数量必须大于0")
qty_dec = Decimal(str(qty))
line_remark = (it.get("remark") or "").strip()
log_remark = line_remark or shared_remark or None
obj = (
db.query(BizMaterial)
.filter(
BizMaterial.id == material_id,
BizMaterial.tenant_no == tenant_no,
BizMaterial.del_flag == 0,
)
.with_for_update()
.first()
)
if not obj:
raise ValueError("物料不存在")
if obj.status != "1":
raise ValueError(f"物料「{obj.material_name}」已停用,无法出库")
stock_before = obj.stock_qty if obj.stock_qty is not None else Decimal("0")
if stock_before < qty_dec:
raise ValueError(
f"物料「{obj.material_name}」库存不足,当前库存 {stock_before},需出库 {qty_dec}"
)
stock_after = stock_before - qty_dec
obj.stock_qty = stock_after
obj.update_by = user_id
obj.update_time = datetime.now()
db.add(obj)
log = BizMaterialStockLog(
id=generate_uuid(),
material_id=obj.id,
material_code=obj.material_code,
material_name=obj.material_name,
change_type="ck",
change_qty=qty_dec,
stock_before=stock_before,
stock_after=stock_after,
receiver=shared_receiver,
purpose=shared_purpose,
tenant_no=tenant_no,
remark=log_remark,
create_by=user_id,
create_dept_id=dept_id or "",
create_time=op_time,
update_by=user_id,
update_time=op_time,
del_flag=0,
)
db.add(log)
db.commit()
return len(items)
except Exception:
db.rollback()
raise
def options_list(db: Session, tenant_no: str) -> List[Dict[str, Any]]: def options_list(db: Session, tenant_no: str) -> List[Dict[str, Any]]:
rows = ( rows = (
db.query(BizMaterial) db.query(BizMaterial)
+18 -3
View File
@@ -8,6 +8,15 @@ from sqlalchemy import func, or_
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app.models.material import BizMaterialStockLog from app.models.material import BizMaterialStockLog
from app.models.models import SysUser
def _user_nick_name_map(db: Session, user_ids: List[str]) -> Dict[str, str]:
ids = list({x for x in user_ids if x})
if not ids:
return {}
rows = db.query(SysUser.id, SysUser.nick_name).filter(SysUser.id.in_(ids)).all()
return {u.id: (u.nick_name or "").strip() for u in rows}
def _dec(v: Any) -> float: def _dec(v: Any) -> float:
@@ -20,7 +29,8 @@ def _fmt_dt(t: Optional[datetime]) -> str:
return t.strftime("%Y-%m-%d %H:%M:%S") if t else "" return t.strftime("%Y-%m-%d %H:%M:%S") if t else ""
def _row_to_dict(r: BizMaterialStockLog) -> Dict[str, Any]: def _row_to_dict(r: BizMaterialStockLog, *, create_by_name: str = "") -> Dict[str, Any]:
create_by = r.create_by or ""
return { return {
"id": r.id, "id": r.id,
"materialId": r.material_id, "materialId": r.material_id,
@@ -33,7 +43,8 @@ def _row_to_dict(r: BizMaterialStockLog) -> Dict[str, Any]:
"receiver": r.receiver or "", "receiver": r.receiver or "",
"purpose": r.purpose or "", "purpose": r.purpose or "",
"remark": r.remark or "", "remark": r.remark or "",
"createBy": r.create_by or "", "createBy": create_by,
"createByName": create_by_name or create_by,
"createTime": _fmt_dt(r.create_time), "createTime": _fmt_dt(r.create_time),
"updateTime": _fmt_dt(r.update_time), "updateTime": _fmt_dt(r.update_time),
} }
@@ -89,4 +100,8 @@ def list_stock_logs(
.limit(page_size) .limit(page_size)
.all() .all()
) )
return [_row_to_dict(x) for x in rows], int(total) name_map = _user_nick_name_map(db, [x.create_by for x in rows if x.create_by])
return [
_row_to_dict(x, create_by_name=name_map.get(x.create_by or "", ""))
for x in rows
], int(total)
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_basic_info_py", "label": "basic_info.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L1"}, {"id": "api_basic_info_get_tenant_no", "label": "_get_tenant_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L31"}, {"id": "api_basic_info_customercreatebody", "label": "CustomerCreateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L46"}, {"id": "basemodel", "label": "BaseModel", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "api_basic_info_customerupdatebody", "label": "CustomerUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L59"}, {"id": "api_basic_info_list_customers", "label": "list_customers()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L73"}, {"id": "api_basic_info_create_customer", "label": "create_customer()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L106"}, {"id": "api_basic_info_update_customer", "label": "update_customer()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L132"}, {"id": "api_basic_info_delete_customer", "label": "delete_customer()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L161"}, {"id": "api_basic_info_cellsampletypecreatebody", "label": "CellSampleTypeCreateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L179"}, {"id": "api_basic_info_cellsampletypeupdatebody", "label": "CellSampleTypeUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L190"}, {"id": "api_basic_info_list_cell_sample_types", "label": "list_cell_sample_types()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L202"}, {"id": "api_basic_info_create_cell_sample_type", "label": "create_cell_sample_type()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L233"}, {"id": "api_basic_info_update_cell_sample_type", "label": "update_cell_sample_type()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L257"}, {"id": "api_basic_info_delete_cell_sample_type", "label": "delete_cell_sample_type()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L284"}, {"id": "api_basic_info_collectionregioncreatebody", "label": "CollectionRegionCreateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L302"}, {"id": "api_basic_info_collectionregionupdatebody", "label": "CollectionRegionUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L310"}, {"id": "api_basic_info_list_collection_regions", "label": "list_collection_regions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L319"}, {"id": "api_basic_info_create_collection_region", "label": "create_collection_region()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L346"}, {"id": "api_basic_info_update_collection_region", "label": "update_collection_region()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L367"}, {"id": "api_basic_info_delete_collection_region", "label": "delete_collection_region()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L391"}, {"id": "api_basic_info_hospitalcreatebody", "label": "HospitalCreateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L409"}, {"id": "api_basic_info_hospitalupdatebody", "label": "HospitalUpdateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L417"}, {"id": "api_basic_info_list_hospitals", "label": "list_hospitals()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py", "source_location": "L426"}, {"id": "api_basic_info_crLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_code_py", "label": "sample_code.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L1"}, {"id": "crud_sample_code_resolve_issued_user_display_name", "label": "_resolve_issued_user_display_name()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L15"}, {"id": "crud_sample_code_parse_issued_time", "label": "_parse_issued_time()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L32"}, {"id": "crud_sample_code_row_to_dict", "label": "_row_to_dict()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L44"}, {"id": "crud_sample_code_sample_code_exists", "label": "sample_code_exists()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L61"}, {"id": "crud_sample_code_list_sample_codes", "label": "list_sample_codes()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L73"}, {"id": "crud_sample_code_get_sample_code", "label": "get_sample_code()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L104"}, {"id": "crud_sample_code_create_sample_code", "label": "create_sample_code()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L111"}, {"id": "crud_sample_code_update_sample_code", "label": "update_sample_code()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L167"}, {"id": "crud_sample_code_soft_delete_sample_code", "label": "soft_delete_sample_code()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L219"}, {"id": "crud_sample_code_batch_generate_sample_codes", "label": "batch_generate_sample_codes()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L229"}, {"id": "crud_sample_code_batch_issue_sample_codes", "label": "batch_issue_sample_codes()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L312"}, {"id": "crud_sample_code_batch_revoke_sample_codes", "label": "batch_revoke_sample_codes()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L357"}, {"id": "crud_sample_code_total_pages", "label": "total_pages()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L396"}, {"id": "crud_sample_code_rationale_1", "label": "\u6837\u672c\u7f16\u7801\u6c60 CRUD\uff08biz_sample_code\uff09", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L1"}, {"id": "crud_sample_code_rationale_240", "label": "\u6279\u91cf\u751f\u6210\u6837\u672c\u7f16\u7801: \u7c7b\u578b\u524d\u7f00 + \u4e2d\u95f4\u6bb5 + \u8865\u96f6\u5e8f\u53f7", "file_type": "rationale", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L240"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_code_py", "target": "math", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L4", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_code_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L5", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_code_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L6", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_code_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L8", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_backend_app_crud_sample_code_py", "target": "sqlalchemy_orm", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py", "source_location": "L9", "weight": 1.0}, {"sourcLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_backend_app_api_insurance_company_py", "label": "insurance_company.py", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L1"}, {"id": "api_insurance_company_get_tenant_no", "label": "_get_tenant_no()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L30"}, {"id": "api_insurance_company_generate_uuid", "label": "_generate_uuid()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L40"}, {"id": "api_insurance_company_fmt_dt", "label": "_fmt_dt()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L44"}, {"id": "api_insurance_company_total_pages", "label": "_total_pages()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L52"}, {"id": "api_insurance_company_row_to_dict_company", "label": "_row_to_dict_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L61"}, {"id": "api_insurance_company_row_to_dict_invoice", "label": "_row_to_dict_invoice()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L80"}, {"id": "api_insurance_company_row_to_dict_project_price", "label": "_row_to_dict_project_price()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L101"}, {"id": "api_insurance_company_list_insurance_companies", "label": "_list_insurance_companies()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L124"}, {"id": "api_insurance_company_create_insurance_company", "label": "_create_insurance_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L163"}, {"id": "api_insurance_company_update_insurance_company", "label": "_update_insurance_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L199"}, {"id": "api_insurance_company_soft_delete_insurance_company", "label": "_soft_delete_insurance_company()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L245"}, {"id": "api_insurance_company_list_insurance_company_invoices", "label": "_list_insurance_company_invoices()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L266"}, {"id": "api_insurance_company_create_insurance_company_invoice", "label": "_create_insurance_company_invoice()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L293"}, {"id": "api_insurance_company_update_insurance_company_invoice", "label": "_update_insurance_company_invoice()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L333"}, {"id": "api_insurance_company_soft_delete_insurance_company_invoice", "label": "_soft_delete_insurance_company_invoice()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L382"}, {"id": "api_insurance_company_list_insurance_project_prices", "label": "_list_insurance_project_prices()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L403"}, {"id": "api_insurance_company_create_insurance_project_price", "label": "_create_insurance_project_price()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L429"}, {"id": "api_insurance_company_update_insurance_project_price", "label": "_update_insurance_project_price()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L463"}, {"id": "api_insurance_company_soft_delete_insurance_project_price", "label": "_soft_delete_insurance_project_price()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L503"}, {"id": "api_insurance_company_insurancecompanycreatebody", "label": "InsuranceCompanyCreateBody", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py", "source_location": "L524"}, {"id": "basemodel", "label": "BaseModel", "file_typeLine truncated
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+113 -128
View File
@@ -1,12 +1,12 @@
# Graph Report - app (2026-05-20) # Graph Report - app (2026-05-20)
## Corpus Check ## Corpus Check
- 135 files · ~114,728 words - 135 files · ~115,043 words
- Verdict: corpus is large enough that graph structure adds value. - Verdict: corpus is large enough that graph structure adds value.
## Summary ## Summary
- 2329 nodes · 9061 edges · 56 communities detected - 2331 nodes · 9069 edges · 53 communities detected
- Extraction: 42% EXTRACTED · 58% INFERRED · 0% AMBIGUOUS · INFERRED: 5245 edges (avg confidence: 0.63) - Extraction: 42% EXTRACTED · 58% INFERRED · 0% AMBIGUOUS · INFERRED: 5247 edges (avg confidence: 0.63)
- Token cost: 0 input · 0 output - Token cost: 0 input · 0 output
## Community Hubs (Navigation) ## Community Hubs (Navigation)
@@ -57,20 +57,17 @@
- [[_COMMUNITY_Community 44|Community 44]] - [[_COMMUNITY_Community 44|Community 44]]
- [[_COMMUNITY_Community 45|Community 45]] - [[_COMMUNITY_Community 45|Community 45]]
- [[_COMMUNITY_Community 46|Community 46]] - [[_COMMUNITY_Community 46|Community 46]]
- [[_COMMUNITY_Community 47|Community 47]]
- [[_COMMUNITY_Community 48|Community 48]]
- [[_COMMUNITY_Community 49|Community 49]] - [[_COMMUNITY_Community 49|Community 49]]
- [[_COMMUNITY_Community 50|Community 50]]
- [[_COMMUNITY_Community 51|Community 51]]
- [[_COMMUNITY_Community 52|Community 52]] - [[_COMMUNITY_Community 52|Community 52]]
- [[_COMMUNITY_Community 53|Community 53]] - [[_COMMUNITY_Community 53|Community 53]]
- [[_COMMUNITY_Community 54|Community 54]] - [[_COMMUNITY_Community 54|Community 54]]
- [[_COMMUNITY_Community 55|Community 55]]
- [[_COMMUNITY_Community 56|Community 56]]
- [[_COMMUNITY_Community 57|Community 57]]
## God Nodes (most connected - your core abstractions) ## God Nodes (most connected - your core abstractions)
1. `success_response()` - 370 edges 1. `success_response()` - 370 edges
2. `error_response()` - 296 edges 2. `error_response()` - 296 edges
3. `SysUser` - 209 edges 3. `SysUser` - 211 edges
4. `BizQcTaskResult` - 193 edges 4. `BizQcTaskResult` - 193 edges
5. `BizQcMaterialUsage` - 190 edges 5. `BizQcMaterialUsage` - 190 edges
6. `BizMaterialStockLog` - 189 edges 6. `BizMaterialStockLog` - 189 edges
@@ -95,76 +92,76 @@
### Community 0 - "Community 0" ### Community 0 - "Community 0"
Cohesion: 0.02 Cohesion: 0.02
Nodes (386): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+378 more) Nodes (371): attachment_download_url(), create_dept(), create_dict_data(), create_dict_type(), create_express_company(), create_item_unit(), create_menu(), create_post() (+363 more)
### Community 1 - "Community 1" ### Community 1 - "Community 1"
Cohesion: 0.01 Cohesion: 0.01
Nodes (371): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+363 more) Nodes (352): AttachmentDownloadUrlBody, DeptCreateBody, DeptUpdateBody, DictDataCreateBody, DictDataUpdateBody, DictTypeCreateBody, DictTypeUpdateBody, ExpressCompanyCreateBody (+344 more)
### Community 2 - "Community 2" ### Community 2 - "Community 2"
Cohesion: 0.06 Cohesion: 0.04
Nodes (212): AccessLogCreateBody, AccessLogUpdateBody, CleanRoomCreateBody, CleanRoomUpdateBody, ExhibitionAppointmentCreateBody, ExhibitionAppointmentUpdateBody, 运营支撑 API(洁净室、进出记录、仓储设施、储位、展厅预约), StorageFacilityCreateBody (+204 more) Nodes (219): CellSampleTypeCreateBody, CellSampleTypeUpdateBody, CollectionRegionCreateBody, CollectionRegionUpdateBody, CustomerCreateBody, CustomerUpdateBody, HospitalCreateBody, HospitalUpdateBody (+211 more)
### Community 3 - "Community 3" ### Community 3 - "Community 3"
Cohesion: 0.03 Cohesion: 0.06
Nodes (121): generate_uuid(), _code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), list_materials(), options_list() (+113 more) Nodes (217): AccessLogCreateBody, AccessLogUpdateBody, CleanRoomCreateBody, CleanRoomUpdateBody, ExhibitionAppointmentCreateBody, ExhibitionAppointmentUpdateBody, 运营支撑 API(洁净室、进出记录、仓储设施、储位、展厅预约), StorageFacilityCreateBody (+209 more)
### Community 4 - "Community 4" ### Community 4 - "Community 4"
Cohesion: 0.09 Cohesion: 0.02
Nodes (126): CellSampleTypeCreateBody, CellSampleTypeUpdateBody, CollectionRegionCreateBody, CollectionRegionUpdateBody, CustomerCreateBody, CustomerUpdateBody, HospitalCreateBody, HospitalUpdateBody (+118 more) Nodes (148): list_ethnics_for_select(), get_designer_data(), apply_data_scope(), _get_child_dept_ids(), get_user_dept_id(), _resolve_user_role_scopes(), delete(), get_multi_with_filters() (+140 more)
### Community 5 - "Community 5" ### Community 5 - "Community 5"
Cohesion: 0.03 Cohesion: 0.03
Nodes (96): list_ethnics_for_select(), apply_data_scope(), _get_child_dept_ids(), get_user_dept_id(), _resolve_user_role_scopes(), list_ethnics(), 民族码表 CRUD(全局 sys_ethnic), _row_to_dict() (+88 more) Nodes (141): generate_uuid(), create_consumable_pack(), get_consumable_pack(), get_pack_detail(), _item_row_to_dict(), list_all_packs(), list_consumable_packs(), pack_code_exists() (+133 more)
### Community 6 - "Community 6" ### Community 6 - "Community 6"
Cohesion: 0.04
Nodes (98): list_collection_regions(), _persist_protocol_sub_resources(), delete(), get_multi_with_filters(), _add_months_yyyymmdd(), align_fq_payment_details_payload(), _apply_submit_receipt_finance(), _apply_submit_refund_finance() (+90 more)
### Community 7 - "Community 7"
Cohesion: 0.03
Nodes (58): get_designer_data(), BaseStorage, convert_heic_to_jpeg(), get_storage(), LocalStorage, MinIOStorage, OSSStorage, process_image_content() (+50 more)
### Community 8 - "Community 8"
Cohesion: 0.05 Cohesion: 0.05
Nodes (83): _format_attachment_file_size(), get_protocol_nos_used_in_protocols(), urls_to_attachment_list(), complete_production_work_order(), create_production_work_order_from_reception(), _fmt_dt(), _generate_work_order_no(), get_production_work_order() (+75 more) Nodes (83): _format_attachment_file_size(), get_protocol_nos_used_in_protocols(), urls_to_attachment_list(), complete_production_work_order(), create_production_work_order_from_reception(), _fmt_dt(), _generate_work_order_no(), get_production_work_order() (+75 more)
### Community 9 - "Community 9" ### Community 7 - "Community 7"
Cohesion: 0.04 Cohesion: 0.04
Nodes (61): list_roles_for_select(), _avatar_url_field(), _build_user_info_payload(), get_web_auth_menu_codes(), _jwt_user_payload(), logout(), 公共接口(Web 登录、刷新 Token、登出;用户模型对齐 docs/sql/zkxw.sql 基线), 登出:吊销 Redis 会话(若已配置 REDIS_HOST)。 (+53 more) Nodes (65): list_roles_for_select(), _avatar_url_field(), _build_user_info_payload(), get_web_auth_menu_codes(), _jwt_user_payload(), logout(), 公共接口(Web 登录、刷新 Token、登出;用户模型对齐 docs/sql/zkxw.sql 基线), 登出:吊销 Redis 会话(若已配置 REDIS_HOST)。 (+57 more)
### Community 10 - "Community 10" ### Community 8 - "Community 8"
Cohesion: 0.09 Cohesion: 0.05
Nodes (40): _parse_datetime_fields(), generate_id(), parse_datetime(), camel_to_snake(), get_model_attr(), HistoryCRUD, _audit_to_dict(), batch_delete_donations() (+32 more) Nodes (26): BusinessException, InvalidStatusTransitionException, log_delivery_operation(), log_operation(), log_order_operation(), log_settlement_operation(), log_user_operation(), OrderLockedException (+18 more)
### Community 11 - "Community 11" ### Community 9 - "Community 9"
Cohesion: 0.43 Cohesion: 0.43
Nodes (45): ConsumableCreateBody, ConsumablePackCreateBody, ConsumablePackUpdateBody, ConsumableUpdateBody, OutputTypeCreateBody, OutputTypeUpdateBody, PackItemInput, ProcessCategoryCreateBody (+37 more) Nodes (45): ConsumableCreateBody, ConsumablePackCreateBody, ConsumablePackUpdateBody, ConsumableUpdateBody, OutputTypeCreateBody, OutputTypeUpdateBody, PackItemInput, ProcessCategoryCreateBody (+37 more)
### Community 12 - "Community 12" ### Community 10 - "Community 10"
Cohesion: 0.1
Nodes (47): AuditSubmitBody, batch_delete_research_donations(), BatchDeleteBody, change_donation_status(), convert_from_storage(), convert_to_storage(), ConvertFromStorageBody, create_research_donation() (+39 more)
### Community 11 - "Community 11"
Cohesion: 0.08 Cohesion: 0.08
Nodes (36): BaseHTTPMiddleware, parse_admin_request_json(), 运营 Web(/web/admin)JSON 请求体解析。 与 ApiCryptoMiddleware 配合:中间件未改写 body 时,在路由内解密 `, 读取 JSON body;dict 时走 resolve_request_payload(明文 / 密文 / data 包装)。 Returns:, ApiCryptoError, _b64url_decode(), _b64url_encode(), decrypt_json() (+28 more) Nodes (36): BaseHTTPMiddleware, parse_admin_request_json(), 运营 Web(/web/admin)JSON 请求体解析。 与 ApiCryptoMiddleware 配合:中间件未改写 body 时,在路由内解密 `, 读取 JSON body;dict 时走 resolve_request_payload(明文 / 密文 / data 包装)。 Returns:, ApiCryptoError, _b64url_decode(), _b64url_encode(), decrypt_json() (+28 more)
### Community 13 - "Community 13" ### Community 12 - "Community 12"
Cohesion: 0.16 Cohesion: 0.16
Nodes (32): _create_insurance_company(), _create_insurance_company_invoice(), _create_insurance_project_price(), delete_insurance_company(), delete_insurance_company_invoice(), delete_insurance_project_price(), _fmt_dt(), _generate_uuid() (+24 more) Nodes (32): _create_insurance_company(), _create_insurance_company_invoice(), _create_insurance_project_price(), delete_insurance_company(), delete_insurance_company_invoice(), delete_insurance_project_price(), _fmt_dt(), _generate_uuid() (+24 more)
### Community 13 - "Community 13"
Cohesion: 0.13
Nodes (9): 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, 生成签名 V3 (SHA256 with RSA), wechat_pay(), WechatPayClient (+1 more)
### Community 14 - "Community 14" ### Community 14 - "Community 14"
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 15 - "Community 15"
Cohesion: 0.17
Nodes (12): BusinessException, InvalidStatusTransitionException, log_delivery_operation(), log_operation(), log_order_operation(), log_settlement_operation(), log_user_operation(), OrderLockedException (+4 more)
### Community 16 - "Community 16"
Cohesion: 0.18 Cohesion: 0.18
Nodes (18): company_code_exists(), create_company(), get_company(), list_companies(), list_company_options(), _row_to_dict(), soft_delete_company(), update_company() (+10 more) Nodes (18): company_code_exists(), create_company(), get_company(), list_companies(), list_company_options(), _row_to_dict(), soft_delete_company(), update_company() (+10 more)
### Community 17 - "Community 17" ### Community 15 - "Community 15"
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 16 - "Community 16"
Cohesion: 0.21 Cohesion: 0.21
Nodes (13): _access_log_to_dict(), create_access_log(), create_clean_room(), get_access_log(), get_clean_room(), list_access_logs(), list_clean_rooms(), room_code_exists() (+5 more) Nodes (13): _access_log_to_dict(), create_access_log(), create_clean_room(), get_access_log(), get_clean_room(), list_access_logs(), list_clean_rooms(), room_code_exists() (+5 more)
### Community 17 - "Community 17"
Cohesion: 0.21
Nodes (13): create_collection_region(), create_hospital(), get_collection_region(), get_hospital(), _hospital_names_by_region_ids(), _hospital_to_dict(), list_collection_regions(), list_hospitals() (+5 more)
### Community 18 - "Community 18" ### Community 18 - "Community 18"
Cohesion: 0.25 Cohesion: 0.25
Nodes (13): batch_issue_protocol_nos(), batch_revoke_protocol_nos(), create_protocol_no(), get_protocol_no(), list_protocol_nos(), _parse_issued_time(), protocol_no_exists(), 采集协议号池 CRUD(biz_collection_protocol_no) (+5 more) Nodes (13): batch_issue_protocol_nos(), batch_revoke_protocol_nos(), create_protocol_no(), get_protocol_no(), list_protocol_nos(), _parse_issued_time(), protocol_no_exists(), 采集协议号池 CRUD(biz_collection_protocol_no) (+5 more)
@@ -174,189 +171,177 @@ 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) Nodes (9): 微信消息通知服务 支持微信小程序模板消息推送 使用方式: from app.core.wechat_message import Wech, 发送模板消息 Args: openid: 用户openid templ, send_delivery_notice(), send_delivery_warning(), send_order_status(), send_payment_success(), send_refund_result(), send_urge_notification() (+1 more)
### Community 20 - "Community 20" ### Community 20 - "Community 20"
Cohesion: 0.27 Cohesion: 0.23
Nodes (12): code_exists(), create_material(), _dec(), _fmt_dt(), get_material(), list_materials(), options_list(), _row_to_dict() (+4 more) Nodes (12): Config, ProductBase, ProductCategoryBase, ProductCategoryCreate, ProductCategoryResponse, ProductCreate, ProductResponse, ProductUnitBase (+4 more)
### Community 21 - "Community 21" ### Community 21 - "Community 21"
Cohesion: 0.27 Cohesion: 0.27
Nodes (10): batch_issue_sample_codes(), batch_revoke_sample_codes(), create_sample_code(), get_sample_code(), list_sample_codes(), 样本编码池 CRUD(biz_sample_code), _row_to_dict(), sample_code_exists() (+2 more)
### Community 22 - "Community 22"
Cohesion: 0.3
Nodes (10): create_consumable_pack(), get_consumable_pack(), get_pack_detail(), _item_row_to_dict(), list_all_packs(), list_consumable_packs(), pack_code_exists(), _row_to_dict() (+2 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) Nodes (11): _build_tree(), _cascade_soft_delete(), _collect_with_ancestors(), create_dept(), get_dept(), list_depts(), list_depts_tree(), 保留匹配节点及其全部上级,供关键词检索后仍能正确组树。 (+3 more)
### Community 24 - "Community 24" ### Community 22 - "Community 22"
Cohesion: 0.29 Cohesion: 0.29
Nodes (9): _build_tree(), _cascade_soft_delete(), create_menu(), get_menu(), list_menus(), list_menus_tree(), _row_to_dict(), soft_delete_menu() (+1 more) 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 25 - "Community 25" ### Community 23 - "Community 23"
Cohesion: 0.31 Cohesion: 0.31
Nodes (8): consumable_code_exists(), create_consumable(), get_consumable(), list_consumables(), 耗材 CRUD(biz_consumable), _row_to_dict(), soft_delete_consumable(), update_consumable() Nodes (8): consumable_code_exists(), create_consumable(), get_consumable(), list_consumables(), 耗材 CRUD(biz_consumable), _row_to_dict(), soft_delete_consumable(), update_consumable()
### Community 26 - "Community 26" ### Community 24 - "Community 24"
Cohesion: 0.31
Nodes (9): appointment_no_exists(), create_exhibition_appointment(), _generate_appointment_no(), get_exhibition_appointment(), list_exhibition_appointments(), 展览预约 CRUD(biz_exhibition_appointment), 生成预约编号:YYYYMMDD + 6位序号(如 20260515000001), soft_delete_exhibition_appointment() (+1 more)
### Community 27 - "Community 27"
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 28 - "Community 28"
Cohesion: 0.38
Nodes (9): create_check_item(), get_check_item(), item_code_exists(), list_active_check_items(), list_check_items(), _order_query(), _row_to_dict(), soft_delete_check_item() (+1 more)
### Community 29 - "Community 29"
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 30 - "Community 30"
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 31 - "Community 31"
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 32 - "Community 32"
Cohesion: 0.31 Cohesion: 0.31
Nodes (8): create_sop_document(), get_sop_document(), list_sop_documents(), SOP文档 CRUD(biz_sop_document), _row_to_dict(), soft_delete_sop_document(), sop_code_exists(), update_sop_document() 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 33 - "Community 33" ### Community 25 - "Community 25"
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 26 - "Community 26"
Cohesion: 0.38
Nodes (9): create_check_item(), get_check_item(), item_code_exists(), list_active_check_items(), list_check_items(), _order_query(), _row_to_dict(), soft_delete_check_item() (+1 more)
### Community 27 - "Community 27"
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 28 - "Community 28"
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 29 - "Community 29"
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 30 - "Community 30"
Cohesion: 0.31 Cohesion: 0.31
Nodes (8): create_customer(), get_customer(), id_card_taken(), list_customers(), 客户 CRUD(biz_customer), _row_to_dict(), soft_delete_customer(), update_customer() Nodes (8): create_customer(), get_customer(), id_card_taken(), list_customers(), 客户 CRUD(biz_customer), _row_to_dict(), soft_delete_customer(), update_customer()
### Community 34 - "Community 34" ### Community 31 - "Community 31"
Cohesion: 0.31
Nodes (9): appointment_no_exists(), create_exhibition_appointment(), _generate_appointment_no(), get_exhibition_appointment(), list_exhibition_appointments(), 展览预约 CRUD(biz_exhibition_appointment), 生成预约编号:YYYYMMDD + 6位序号(如 20260515000001), soft_delete_exhibition_appointment() (+1 more)
### Community 32 - "Community 32"
Cohesion: 0.31 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() 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 35 - "Community 35" ### Community 33 - "Community 33"
Cohesion: 0.31 Cohesion: 0.31
Nodes (8): create_output_type(), get_output_type(), list_output_types(), 工艺产出物类型 CRUD(biz_output_type), _row_to_dict(), soft_delete_output_type(), type_code_exists(), update_output_type() 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 36 - "Community 36" ### Community 34 - "Community 34"
Cohesion: 0.36 Cohesion: 0.36
Nodes (7): create_post(), get_post(), list_posts(), post_code_exists(), _row_to_dict(), soft_delete_post(), update_post() Nodes (7): create_post(), get_post(), list_posts(), post_code_exists(), _row_to_dict(), soft_delete_post(), update_post()
### Community 37 - "Community 37" ### Community 35 - "Community 35"
Cohesion: 0.36 Cohesion: 0.36
Nodes (7): create_dict_type(), dict_type_code_exists(), get_dict_type(), list_dict_types(), _row_to_dict(), soft_delete_dict_type(), update_dict_type() Nodes (7): create_dict_type(), dict_type_code_exists(), get_dict_type(), list_dict_types(), _row_to_dict(), soft_delete_dict_type(), update_dict_type()
### Community 38 - "Community 38" ### Community 36 - "Community 36"
Cohesion: 0.36 Cohesion: 0.36
Nodes (7): create_tenant(), get_tenant(), list_tenants(), _row_to_dict(), soft_delete_tenant(), tenant_no_exists(), update_tenant() Nodes (7): create_tenant(), get_tenant(), list_tenants(), _row_to_dict(), soft_delete_tenant(), tenant_no_exists(), update_tenant()
### Community 39 - "Community 39" ### Community 37 - "Community 37"
Cohesion: 0.36 Cohesion: 0.36
Nodes (7): create_reagent(), get_reagent(), list_reagents(), reagent_code_exists(), _row_to_dict(), soft_delete_reagent(), update_reagent() Nodes (7): create_reagent(), get_reagent(), list_reagents(), reagent_code_exists(), _row_to_dict(), soft_delete_reagent(), update_reagent()
### Community 40 - "Community 40" ### Community 38 - "Community 38"
Cohesion: 0.31
Nodes (7): create_cell_product(), delete_cell_product(), get_cell_product(), list_cell_products(), 细胞产品 CRUD(biz_cell_product), _row_to_dict(), update_cell_product()
### Community 41 - "Community 41"
Cohesion: 0.39
Nodes (8): create_lab_item(), get_lab_item(), item_code_exists(), list_active_lab_items(), list_lab_items(), _row_to_dict(), soft_delete_lab_item(), update_lab_item()
### Community 42 - "Community 42"
Cohesion: 0.36 Cohesion: 0.36
Nodes (7): create_site(), get_site(), list_sites(), _row_to_dict(), site_code_exists(), soft_delete_site(), update_site() Nodes (7): create_site(), get_site(), list_sites(), _row_to_dict(), site_code_exists(), soft_delete_site(), update_site()
### Community 43 - "Community 43" ### Community 39 - "Community 39"
Cohesion: 0.31
Nodes (7): create_cell_product(), delete_cell_product(), get_cell_product(), list_cell_products(), 细胞产品 CRUD(biz_cell_product), _row_to_dict(), update_cell_product()
### Community 40 - "Community 40"
Cohesion: 0.29 Cohesion: 0.29
Nodes (2): BaseModel, SoftDeleteModel Nodes (2): BaseModel, SoftDeleteModel
### Community 44 - "Community 44" ### Community 41 - "Community 41"
Cohesion: 0.38 Cohesion: 0.38
Nodes (6): derive_legacy_status_from_three(), derive_three_status_from_legacy(), 阶段A兼容:从旧 status 推导三字段。 约束:旧 status 本身混合了支付/配送/订单生命周期,因此只能尽力推断; 若业务侧已有更精确, 阶段A兼容:从三字段反推旧 status(用于旧前端/旧筛选参数兼容)。, ThreeStatus, _to_decimal() Nodes (6): derive_legacy_status_from_three(), derive_three_status_from_legacy(), 阶段A兼容:从旧 status 推导三字段。 约束:旧 status 本身混合了支付/配送/订单生命周期,因此只能尽力推断; 若业务侧已有更精确, 阶段A兼容:从三字段反推旧 status(用于旧前端/旧筛选参数兼容)。, ThreeStatus, _to_decimal()
### Community 45 - "Community 45" ### Community 42 - "Community 42"
Cohesion: 0.5 Cohesion: 0.5
Nodes (3): BaseSettings, Config, Settings Nodes (3): BaseSettings, Config, Settings
### Community 46 - "Community 46" ### Community 43 - "Community 43"
Cohesion: 0.5 Cohesion: 0.5
Nodes (2): _auto_fill_create_dept_id(), ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID Nodes (2): _auto_fill_create_dept_id(), ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID
### Community 47 - "Community 47" ### Community 44 - "Community 44"
Cohesion: 0.67 Cohesion: 0.67
Nodes (2): get_menu_list(), 运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,供后端菜单模式联调) Nodes (2): get_menu_list(), 运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,供后端菜单模式联调)
### Community 48 - "Community 48" ### Community 45 - "Community 45"
Cohesion: 1.0 Cohesion: 1.0
Nodes (1): 请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传 Nodes (1): 请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传
### Community 49 - "Community 49" ### Community 46 - "Community 46"
Cohesion: 1.0 Cohesion: 1.0
Nodes (1): API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位) Nodes (1): API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)
### Community 52 - "Community 52" ### Community 49 - "Community 49"
Cohesion: 1.0 Cohesion: 1.0
Nodes (1): 发送订单状态通知 Args: openid: 用户openid ord Nodes (1): 发送订单状态通知 Args: openid: 用户openid ord
### Community 53 - "Community 53" ### Community 50 - "Community 50"
Cohesion: 1.0 Cohesion: 1.0
Nodes (1): 发送支付成功通知 Args: openid: 用户openid ord Nodes (1): 发送支付成功通知 Args: openid: 用户openid ord
### Community 54 - "Community 54" ### Community 51 - "Community 51"
Cohesion: 1.0 Cohesion: 1.0
Nodes (1): 发送配送通知 Args: openid: 配送员openid task Nodes (1): 发送配送通知 Args: openid: 配送员openid task
### Community 55 - "Community 55" ### Community 52 - "Community 52"
Cohesion: 1.0 Cohesion: 1.0
Nodes (1): 发送配送时效预警 Args: openid: 配送员openid ta Nodes (1): 发送配送时效预警 Args: openid: 配送员openid ta
### Community 56 - "Community 56" ### Community 53 - "Community 53"
Cohesion: 1.0 Cohesion: 1.0
Nodes (1): 发送退款结果通知 Args: openid: 用户openid ord Nodes (1): 发送退款结果通知 Args: openid: 用户openid ord
### Community 57 - "Community 57" ### Community 54 - "Community 54"
Cohesion: 1.0 Cohesion: 1.0
Nodes (1): 发送催单通知给配送员 Args: deliver_openid: 配送员openid Nodes (1): 发送催单通知给配送员 Args: deliver_openid: 配送员openid
## Knowledge Gaps ## Knowledge Gaps
- **86 isolated node(s):** `刷新会话 TTL(refreshToken 续期;已登录用户每次 API 校验通过后滑动续期)`, `写入 refreshToken(用于 one-time 使用/吊销)`, `根据 token 获取当前用户(包含 Redis 会话校验;会话滑动续期)`, `登录凭据 RSA 解密(与前端 JSEncrypt PKCS#1 v1.5 兼容)。`, `Base64 密文 -> JSON 对象(须含 username、password、ts 毫秒时间戳)。` (+81 more) - **86 isolated node(s):** `刷新会话 TTL(refreshToken 续期;已登录用户每次 API 校验通过后滑动续期)`, `写入 refreshToken(用于 one-time 使用/吊销)`, `根据 token 获取当前用户(包含 Redis 会话校验;会话滑动续期)`, `登录凭据 RSA 解密(与前端 JSEncrypt PKCS#1 v1.5 兼容)。`, `Base64 密文 -> JSON 对象(须含 username、password、ts 毫秒时间戳)。` (+81 more)
These have ≤1 connection - possible missing edges or undocumented components. These have ≤1 connection - possible missing edges or undocumented components.
- **Thin community `Community 43`** (8 nodes): `BaseModel`, `.to_dict()`, `get_active()`, `base.py`, `SoftDeleteModel`, `.restore()`, `.soft_delete()`, `__tablename__()` - **Thin community `Community 40`** (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. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 46`** (4 nodes): `_auto_fill_create_dept_id()`, `get_db()`, `database.py`, `ORM before_insert 钩子:当 create_dept_id 为空时,自动从请求上下文填充当前用户部门 ID` - **Thin community `Community 43`** (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. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 47`** (3 nodes): `get_menu_list()`, `menu.py`, `运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,供后端菜单模式联调)` - **Thin community `Community 44`** (3 nodes): `get_menu_list()`, `menu.py`, `运营端菜单接口(与 web-admin 前端静态路由 sqxp.ts 对齐,供后端菜单模式联调)`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 48`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传` - **Thin community `Community 45`** (2 nodes): `context.py`, `请求级别的用户上下文变量 通过 contextvars 在请求处理链路中传递当前用户信息, 供 SQLAlchemy 事件监听器等底层机制使用,避免逐层手动传`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 49`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)` - **Thin community `Community 46`** (2 nodes): `__init__.py`, `API 路由包(骨架:公共鉴权 + 静态菜单 + 运营端占位)`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 52`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord` - **Thin community `Community 49`** (1 nodes): `发送订单状态通知 Args: openid: 用户openid ord`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 53`** (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. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 54`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task` - **Thin community `Community 51`** (1 nodes): `发送配送通知 Args: openid: 配送员openid task`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 55`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta` - **Thin community `Community 52`** (1 nodes): `发送配送时效预警 Args: openid: 配送员openid ta`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 56`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord` - **Thin community `Community 53`** (1 nodes): `发送退款结果通知 Args: openid: 用户openid ord`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 57`** (1 nodes): `发送催单通知给配送员 Args: deliver_openid: 配送员openid` - **Thin community `Community 54`** (1 nodes): `发送催单通知给配送员 Args: deliver_openid: 配送员openid`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
## Suggested Questions ## Suggested Questions
_Questions this graph is uniquely positioned to answer:_ _Questions this graph is uniquely positioned to answer:_
- **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 12`, `Community 16`, `Community 17`, `Community 18`, `Community 20`, `Community 21`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 33`, `Community 34`, `Community 35`, `Community 36`, `Community 37`, `Community 38`, `Community 39`, `Community 40`, `Community 41`, `Community 42`?** - **Why does `generate_uuid()` connect `Community 5` to `Community 0`, `Community 2`, `Community 3`, `Community 4`, `Community 6`, `Community 7`, `Community 10`, `Community 11`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 18`, `Community 21`, `Community 22`, `Community 23`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 31`, `Community 32`, `Community 33`, `Community 34`, `Community 35`, `Community 36`, `Community 37`, `Community 38`, `Community 39`?**
_High betweenness centrality (0.109) - this node is a cross-community bridge._ _High betweenness centrality (0.115) - this node is a cross-community bridge._
- **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 5`, `Community 6`, `Community 7`, `Community 9`, `Community 13`, `Community 47`?** - **Why does `SysUser` connect `Community 1` to `Community 2`, `Community 3`, `Community 5`, `Community 7`, `Community 9`, `Community 10`, `Community 12`, `Community 15`, `Community 18`?**
_High betweenness centrality (0.075) - this node is a cross-community bridge._ _High betweenness centrality (0.092) - this node is a cross-community bridge._
- **Why does `SysUser` connect `Community 1` to `Community 2`, `Community 3`, `Community 4`, `Community 9`, `Community 11`, `Community 13`, `Community 18`?** - **Why does `success_response()` connect `Community 0` to `Community 1`, `Community 2`, `Community 4`, `Community 7`, `Community 10`, `Community 44`, `Community 12`?**
_High betweenness centrality (0.074) - this node is a cross-community bridge._ _High betweenness centrality (0.056) - this node is a cross-community bridge._
- **Are the 369 inferred relationships involving `success_response()` (e.g. with `web_login_rsa_public_key()` and `web_login()`) actually correct?** - **Are the 369 inferred relationships involving `success_response()` (e.g. with `web_login_rsa_public_key()` and `web_login()`) actually correct?**
_`success_response()` has 369 INFERRED edges - model-reasoned connections that need verification._ _`success_response()` has 369 INFERRED edges - model-reasoned connections that need verification._
- **Are the 334 inferred relationships involving `str` (e.g. with `extract_login_credentials()` and `._make_request()`) actually correct?** - **Are the 334 inferred relationships involving `str` (e.g. with `extract_login_credentials()` and `._make_request()`) actually correct?**
_`str` has 334 INFERRED edges - model-reasoned connections that need verification._ _`str` has 334 INFERRED edges - model-reasoned connections that need verification._
- **Are the 295 inferred relationships involving `error_response()` (e.g. with `_json_error_response()` and `web_login()`) actually correct?** - **Are the 295 inferred relationships involving `error_response()` (e.g. with `_json_error_response()` and `web_login()`) actually correct?**
_`error_response()` has 295 INFERRED edges - model-reasoned connections that need verification._ _`error_response()` has 295 INFERRED edges - model-reasoned connections that need verification._
- **Are the 207 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤) data_scope 值: 1 = 全部数据 2 = 本部门数据 3` and `从 SysUser 读取用户的 dept_id。`) actually correct?** - **Are the 209 inferred relationships involving `SysUser` (e.g. with `数据权限过滤(V0.3:基于角色 data_scope 的查询级行级过滤) data_scope 值: 1 = 全部数据 2 = 本部门数据 3` and `从 SysUser 读取用户的 dept_id。`) actually correct?**
_`SysUser` has 207 INFERRED edges - model-reasoned connections that need verification._ _`SysUser` has 209 INFERRED edges - model-reasoned connections that need verification._
+4 -4
View File
@@ -57,12 +57,12 @@
</div> </div>
<div id="legend"></div> <div id="legend"></div>
</div> </div>
<div id="stats">2329 nodes &middot; 9061 edges &middot; 62 communities</div> <div id="stats">2331 nodes &middot; 9069 edges &middot; 59 communities</div>
</div> </div>
<script> <script>
const RAW_NODES = [{"id": "init_py", "label": "__init__.py", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 50, "community_name": "Community 50", "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": 4}, {"id": "app_main_lifespan", "label": "lifespan()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_mask_secret", "label": "_mask_secret()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.1, "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.1, "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.1, "font": {"size": 0, "color": "#ffffff"}, "title": "health_check()", "community": 9, "community_name": "Community 9", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "tasks_init_py", "label": "__init__.py", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 9, "community_name": "Community 9", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "tasks_init_init_scheduled_tasks", "label": "init_scheduled_tasks()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "init_scheduled_tasks()", "community": 9, "community_name": "Community 9", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "tasks_init_shutdown_scheduler", "label": "shutdown_scheduler()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "shutdown_scheduler()", "community": 9, "community_name": "Community 9", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "core_auth_py", "label": "auth.py", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 11.5, "font": {"size": 0, "color": "#ffffff"}, "title": "auth.py", "community": 9, "community_name": "Community 9", "source_file": "core/auth.py", "file_type": "code", "degree": 18}, {"id": "core_auth_redis_session_enabled", "label": "_redis_session_enabled()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "_redis_session_enabled()", "community": 9, "community_name": "Community 9", "source_file": "core/auth.py", "file_type": "code", "degree": 2}, {"id": "core_auth_get_redis_client", "label": "_get_redis_client()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.7, "font": {"size": 0, "color": "#ffffff"}, "title": "_get_redis_client()", "community": 9, "community_name": "Community 9", "source_file": "core/auth.py", "file_type": "code", "degree": 9}, {"id": "core_auth_session_key", "label": "_session_key()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "_session_key()", "community": 9, "community_name": "Community 9", "source_file": "core/auth.py", "file_type": "code", "degree": 5}, {"id": "core_auth_refresh_key", "label": "_refresh_key()", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "boLine truncated 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": 47, "community_name": "Community 47", "source_file": "__init__.py", "file_type": "code", "degree": 0}, {"id": "main_py", "label": "main.py", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "main.py", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_lifespan", "label": "lifespan()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "lifespan()", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 4}, {"id": "app_main_mask_secret", "label": "_mask_secret()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "_mask_secret()", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_root", "label": "root()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "root()", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "app_main_health_check", "label": "health_check()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "health_check()", "community": 7, "community_name": "Community 7", "source_file": "main.py", "file_type": "code", "degree": 1}, {"id": "tasks_init_py", "label": "__init__.py", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "__init__.py", "community": 7, "community_name": "Community 7", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "tasks_init_init_scheduled_tasks", "label": "init_scheduled_tasks()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "init_scheduled_tasks()", "community": 7, "community_name": "Community 7", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "tasks_init_shutdown_scheduler", "label": "shutdown_scheduler()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "shutdown_scheduler()", "community": 7, "community_name": "Community 7", "source_file": "tasks/__init__.py", "file_type": "code", "degree": 2}, {"id": "core_auth_py", "label": "auth.py", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 11.5, "font": {"size": 0, "color": "#ffffff"}, "title": "auth.py", "community": 7, "community_name": "Community 7", "source_file": "core/auth.py", "file_type": "code", "degree": 18}, {"id": "core_auth_redis_session_enabled", "label": "_redis_session_enabled()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "_redis_session_enabled()", "community": 7, "community_name": "Community 7", "source_file": "core/auth.py", "file_type": "code", "degree": 2}, {"id": "core_auth_get_redis_client", "label": "_get_redis_client()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.7, "font": {"size": 0, "color": "#ffffff"}, "title": "_get_redis_client()", "community": 7, "community_name": "Community 7", "source_file": "core/auth.py", "file_type": "code", "degree": 9}, {"id": "core_auth_session_key", "label": "_session_key()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "_session_key()", "community": 7, "community_name": "Community 7", "source_file": "core/auth.py", "file_type": "code", "degree": 5}, {"id": "core_auth_refresh_key", "label": "_refresh_key()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "boLine 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_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": "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", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_session_key", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_refresh_key", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_store_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_revoke_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_extend_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_is_session_valid", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_store_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_is_refresh_token_valid", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_revoke_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_create_access_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_create_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_decode_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_current_user_by_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_current_user", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "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_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": "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", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_session_key", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_refresh_key", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_store_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_revoke_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_extend_session", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_is_session_valid", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_store_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_is_refresh_token_valid", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_revoke_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_create_access_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_create_refresh_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_decode_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_current_user_by_token", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "to": "core_auth_get_current_user", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_py", "Line truncated
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 399}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 395}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 217}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 131}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 129}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 110}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 107}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 105}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 92}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 80}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 49}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 49}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 43}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 33}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 31}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 21}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 20}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 15}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 15}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 13}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 13}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 12}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 12}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 12}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 11}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 10}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 10}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 10}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 10}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 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": 9}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 9}, {"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": 9}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 9}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 8}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 7}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 4}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 4}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 3}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 2}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 2}, {"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}]; const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 385}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 375}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 224}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 222}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 181}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 154}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 92}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 92}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 69}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 49}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 49}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 43}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 33}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 27}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 20}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 16}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 15}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 15}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 15}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 13}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 13}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 12}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 11}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 10}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 10}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 10}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 10}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 10}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 10}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 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": 9}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 9}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 9}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 9}, {"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": 8}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 7}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 4}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 4}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 3}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 2}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 2}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 1}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 1}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 1}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 1}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 1}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 1}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 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 // HTML-escape helper — prevents XSS when injecting graph data into innerHTML
function esc(s) { function esc(s) {
File diff suppressed because it is too large. Load diff
+3 -3
View File
@@ -61,7 +61,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/schemas/leave.py": 1778666088.7680702, "/Users/wuzilong/work/00code/zkxw/backend/app/schemas/leave.py": 1778666088.7680702,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py": 1779265700.504972, "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task.py": 1779265700.504972,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/process_route.py": 1779265696.2771301, "/Users/wuzilong/work/00code/zkxw/backend/app/crud/process_route.py": 1779265696.2771301,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py": 1778739713.1609266, "/Users/wuzilong/work/00code/zkxw/backend/app/crud/sample_code.py": 1779279460.690872,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py": 1779265777.8667352, "/Users/wuzilong/work/00code/zkxw/backend/app/crud/qc_task_result.py": 1779265777.8667352,
"/Users/wuzilong/work/00code/zkxw/backend/app/crud/post.py": 1779265648.38155, "/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/sample_reception_check_result.py": 1779255909.8554008,
@@ -117,7 +117,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/api/material.py": 1779266127.8435113, "/Users/wuzilong/work/00code/zkxw/backend/app/api/material.py": 1779266127.8435113,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py": 1779265802.2248735, "/Users/wuzilong/work/00code/zkxw/backend/app/api/qc.py": 1779265802.2248735,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/collection_protocol.py": 1779265813.1605325, "/Users/wuzilong/work/00code/zkxw/backend/app/api/collection_protocol.py": 1779265813.1605325,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py": 1779279035.4324942, "/Users/wuzilong/work/00code/zkxw/backend/app/api/basic_info.py": 1779280842.8447173,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/__init__.py": 1779230551.0712175, "/Users/wuzilong/work/00code/zkxw/backend/app/api/__init__.py": 1779230551.0712175,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/operations.py": 1779271459.2836037, "/Users/wuzilong/work/00code/zkxw/backend/app/api/operations.py": 1779271459.2836037,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/menu.py": 1779263225.4964793, "/Users/wuzilong/work/00code/zkxw/backend/app/api/menu.py": 1779263225.4964793,
@@ -127,7 +127,7 @@
"/Users/wuzilong/work/00code/zkxw/backend/app/api/pilot_service.py": 1779265798.3244395, "/Users/wuzilong/work/00code/zkxw/backend/app/api/pilot_service.py": 1779265798.3244395,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/workflow.py": 1779266232.4568832, "/Users/wuzilong/work/00code/zkxw/backend/app/api/workflow.py": 1779266232.4568832,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/sample_reception.py": 1779265829.262964, "/Users/wuzilong/work/00code/zkxw/backend/app/api/sample_reception.py": 1779265829.262964,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py": 1779266106.5009758, "/Users/wuzilong/work/00code/zkxw/backend/app/api/insurance_company.py": 1779281097.279193,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py": 1779265782.5075505, "/Users/wuzilong/work/00code/zkxw/backend/app/api/production.py": 1779265782.5075505,
"/Users/wuzilong/work/00code/zkxw/backend/app/api/leave.py": 1779266168.8693042, "/Users/wuzilong/work/00code/zkxw/backend/app/api/leave.py": 1779266168.8693042,
"/Users/wuzilong/work/00code/zkxw/backend/app/services/workflow_callback.py": 1778727966.7277644, "/Users/wuzilong/work/00code/zkxw/backend/app/services/workflow_callback.py": 1778727966.7277644,
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+59 -118
View File
@@ -1,11 +1,11 @@
# Graph Report - src (2026-05-20) # Graph Report - src (2026-05-20)
## Corpus Check ## Corpus Check
- Large corpus: 575 files · ~286,028 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only. - Large corpus: 575 files · ~286,452 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
## Summary ## Summary
- 1441 nodes · 1845 edges · 45 communities detected - 1444 nodes · 1853 edges · 36 communities detected
- Extraction: 77% EXTRACTED · 23% INFERRED · 0% AMBIGUOUS · INFERRED: 418 edges (avg confidence: 0.8) - Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 416 edges (avg confidence: 0.8)
- Token cost: 0 input · 0 output - Token cost: 0 input · 0 output
## Community Hubs (Navigation) ## Community Hubs (Navigation)
@@ -36,24 +36,15 @@
- [[_COMMUNITY_Community 24|Community 24]] - [[_COMMUNITY_Community 24|Community 24]]
- [[_COMMUNITY_Community 25|Community 25]] - [[_COMMUNITY_Community 25|Community 25]]
- [[_COMMUNITY_Community 26|Community 26]] - [[_COMMUNITY_Community 26|Community 26]]
- [[_COMMUNITY_Community 27|Community 27]] - [[_COMMUNITY_Community 29|Community 29]]
- [[_COMMUNITY_Community 28|Community 28]]
- [[_COMMUNITY_Community 30|Community 30]] - [[_COMMUNITY_Community 30|Community 30]]
- [[_COMMUNITY_Community 31|Community 31]]
- [[_COMMUNITY_Community 32|Community 32]] - [[_COMMUNITY_Community 32|Community 32]]
- [[_COMMUNITY_Community 33|Community 33]] - [[_COMMUNITY_Community 33|Community 33]]
- [[_COMMUNITY_Community 34|Community 34]] - [[_COMMUNITY_Community 34|Community 34]]
- [[_COMMUNITY_Community 35|Community 35]] - [[_COMMUNITY_Community 35|Community 35]]
- [[_COMMUNITY_Community 36|Community 36]] - [[_COMMUNITY_Community 36|Community 36]]
- [[_COMMUNITY_Community 37|Community 37]]
- [[_COMMUNITY_Community 38|Community 38]] - [[_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 47|Community 47]]
## God Nodes (most connected - your core abstractions) ## God Nodes (most connected - your core abstractions)
1. `get()` - 151 edges 1. `get()` - 151 edges
@@ -70,12 +61,12 @@
## Surprising Connections (you probably didn't know these) ## Surprising Connections (you probably didn't know these)
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED] - `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
views/operations/clean-room/index.vue → utils/fullscreen-loading.ts views/operations/clean-room/index.vue → utils/fullscreen-loading.ts
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
views/system/site/index.vue → utils/fullscreen-loading.ts
- `handleDelete()` --calls--> `withFullscreenLoading()` [INFERRED] - `handleDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
views/pilot-service/project-price-system/index.vue → utils/fullscreen-loading.ts views/pilot-service/project-price-system/index.vue → utils/fullscreen-loading.ts
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED] - `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
views/pilot-service/project-price-system/index.vue → utils/fullscreen-loading.ts views/pilot-service/project-price-system/index.vue → utils/fullscreen-loading.ts
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
views/basic-info/cell-sample-type/index.vue → utils/fullscreen-loading.ts
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED] - `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
views/basic-info/collection-region/index.vue → utils/fullscreen-loading.ts views/basic-info/collection-region/index.vue → utils/fullscreen-loading.ts
@@ -83,31 +74,31 @@
### Community 0 - "Community 0" ### Community 0 - "Community 0"
Cohesion: 0.01 Cohesion: 0.01
Nodes (81): fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchChannelAgreementPrices(), fetchChannelAgreements() (+73 more) Nodes (108): fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchChannelAgreementPrices(), fetchChannelAgreements(), fetchChannelInvoices() (+100 more)
### Community 1 - "Community 1" ### Community 1 - "Community 1"
Cohesion: 0.03 Cohesion: 0.02
Nodes (56): fetchBatchGenerateProtocolNos(), fetchBatchGenerateSampleCodes(), fetchBatchIssueProtocolNos(), fetchBatchIssueSampleCodes(), fetchCollectionProtocolNoList(), fetchCreateCollectionProtocolNo(), fetchCreateSampleCode(), fetchDeleteCollectionProtocolNo() (+48 more) Nodes (23): fetchCellProductPriceList(), fetchCreateProjectSystem(), fetchCreateProjectSystemItem(), fetchDeleteProjectSystemItem(), fetchGetRoleList(), fetchNotDeletedRegions(), fetchProjectSystemItems(), fetchProjectSystemList() (+15 more)
### Community 2 - "Community 2" ### Community 2 - "Community 2"
Cohesion: 0.04 Cohesion: 0.03
Nodes (32): fetchGetUserInfo(), clickTab(), handleTouchEnd(), setTransition(), IframeRouteManager, RoutePermissionValidator, RouteRegistry, useCommon() (+24 more) Nodes (57): fetchBatchGenerateProtocolNos(), fetchBatchGenerateSampleCodes(), fetchBatchIssueProtocolNos(), fetchBatchIssueSampleCodes(), fetchCollectionProtocolNoList(), fetchCreateCollectionProtocolNo(), fetchCreateSampleCode(), fetchDeleteCollectionProtocolNo() (+49 more)
### Community 3 - "Community 3" ### Community 3 - "Community 3"
Cohesion: 0.03 Cohesion: 0.04
Nodes (37): fetchUploadAttachment(), fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllOutputTypes(), fetchAllProcessCategories(), fetchAllProcesses(), fetchAllReagents(), fetchAllSopDocuments() (+29 more) Nodes (31): fetchGetUserInfo(), clickTab(), handleTouchEnd(), setTransition(), IframeRouteManager, RouteRegistry, useCommon(), setupAfterEachGuard() (+23 more)
### Community 4 - "Community 4" ### Community 4 - "Community 4"
Cohesion: 0.05 Cohesion: 0.05
Nodes (27): FireworkSystem, reload(), collectIds(), formatUserLabel(), onPersonSelectChange(), handleMenuJump(), openExternalLink(), collectAllPostBindDeptIds() (+19 more) Nodes (24): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), fetchAttachmentDownloadUrl(), postorder(), preorder(), applyTreeExpand() (+16 more)
### Community 5 - "Community 5" ### Community 5 - "Community 5"
Cohesion: 0.09 Cohesion: 0.05
Nodes (5): handleReset(), handleSearch(), WebSocketClient, TableCache, emit() Nodes (31): fetchDeptTree(), fetchPostBoundUserIds(), FireworkSystem, reload(), formatUserLabel(), loadDeptData(), onPersonSelectChange(), handleMenuJump() (+23 more)
### Community 6 - "Community 6" ### Community 6 - "Community 6"
Cohesion: 0.06 Cohesion: 0.09
Nodes (14): fetchAttachmentDownloadUrl(), fetchOrderAdjusts(), fetchOrderDetail(), fetchOrderItems(), fetchOrderList(), fetchPriceVersionDetail(), fetchSystemConfig(), handleReceptionAttachmentDownload() (+6 more) Nodes (5): handleReset(), handleSearch(), WebSocketClient, TableCache, emit()
### Community 7 - "Community 7" ### Community 7 - "Community 7"
Cohesion: 0.09 Cohesion: 0.09
@@ -122,40 +113,40 @@ Cohesion: 0.09
Nodes (24): fetchAccessLogList(), fetchCleanRoomList(), fetchCreateAccessLog(), fetchCreateCleanRoom(), fetchDeleteAccessLog(), fetchDeleteCleanRoom(), fetchUpdateAccessLog(), fetchUpdateCleanRoom() (+16 more) Nodes (24): fetchAccessLogList(), fetchCleanRoomList(), fetchCreateAccessLog(), fetchCreateCleanRoom(), fetchDeleteAccessLog(), fetchDeleteCleanRoom(), fetchUpdateAccessLog(), fetchUpdateCleanRoom() (+16 more)
### Community 10 - "Community 10" ### Community 10 - "Community 10"
Cohesion: 0.1 Cohesion: 0.09
Nodes (7): fetchGetMenuList(), fetchGetMenuCodes(), fetchLogin(), MenuProcessor, useAppMode(), useAuth(), buildWebEncryptedLoginBody() Nodes (20): fetchCollectionRegionList(), fetchCreateCollectionRegion(), fetchCreateHospital(), fetchDeleteCollectionRegion(), fetchDeleteHospital(), fetchHospitalList(), fetchUpdateCollectionRegion(), fetchUpdateHospital() (+12 more)
### Community 11 - "Community 11" ### Community 11 - "Community 11"
Cohesion: 0.1 Cohesion: 0.1
Nodes (13): fetchEthnicList(), addSample(), applyDonationBundleToForm(), confirmBatchTransportApply(), createEmptyTransport(), ensureDonationProtocolNoInOptions(), ensureEthnicOptionInList(), handleOpenForAdd() (+5 more) Nodes (7): fetchGetMenuList(), fetchGetMenuCodes(), fetchLogin(), MenuProcessor, useAppMode(), useAuth(), buildWebEncryptedLoginBody()
### Community 12 - "Community 12" ### Community 12 - "Community 12"
Cohesion: 0.09 Cohesion: 0.1
Nodes (18): fetchCollectionRegionList(), fetchCreateCollectionRegion(), fetchCreateHospital(), fetchDeleteCollectionRegion(), fetchDeleteHospital(), fetchHospitalList(), fetchUpdateCollectionRegion(), fetchUpdateHospital() (+10 more) Nodes (13): fetchEthnicList(), addSample(), applyDonationBundleToForm(), confirmBatchTransportApply(), createEmptyTransport(), ensureDonationProtocolNoInOptions(), ensureEthnicOptionInList(), handleOpenForAdd() (+5 more)
### Community 13 - "Community 13" ### Community 13 - "Community 13"
Cohesion: 0.09
Nodes (10): collectIds(), useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), themeAnimation() (+2 more)
### Community 14 - "Community 14"
Cohesion: 0.11 Cohesion: 0.11
Nodes (17): fetchCreateMaterial(), fetchDeleteMaterial(), fetchMaterialList(), fetchMaterialOptions(), fetchMaterialStockLogList(), fetchStockInMaterial(), fetchStockOutMaterial(), fetchUpdateMaterial() (+9 more) Nodes (17): fetchCreateMaterial(), fetchDeleteMaterial(), fetchMaterialList(), fetchMaterialOptions(), fetchMaterialStockLogList(), fetchStockInMaterial(), fetchStockOutMaterial(), fetchUpdateMaterial() (+9 more)
### Community 14 - "Community 14"
Cohesion: 0.1
Nodes (19): fetchCreateSite(), fetchDeleteSite(), fetchDictDataOptions(), fetchSiteList(), fetchUpdateSite(), fetchUserList(), remoteSearchUsers(), loadDictOptions() (+11 more)
### Community 15 - "Community 15" ### Community 15 - "Community 15"
Cohesion: 0.12 Cohesion: 0.1
Nodes (16): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), postorder(), preorder(), applyTreeExpand(), handleAdd() (+8 more) Nodes (20): fetchCreateSite(), fetchDeleteSite(), fetchDictDataOptions(), fetchSiteList(), fetchUpdateSite(), fetchUserList(), remoteSearchUsers(), loadDictOptions() (+12 more)
### Community 16 - "Community 16" ### Community 16 - "Community 16"
Cohesion: 0.12 Cohesion: 0.12
Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more) Nodes (20): fetchUploadAttachment(), fetchCreateSop(), fetchSopList(), fetchUpdateSop(), attachmentsFromApiFiles(), attachmentsFromUrls(), fullFileUrl(), handleAdd() (+12 more)
### Community 17 - "Community 17" ### Community 17 - "Community 17"
Cohesion: 0.14 Cohesion: 0.12
Nodes (17): fetchCreateUser(), fetchDeleteUser(), fetchResetPassword(), fetchUpdateUser(), fetchUserDetail(), formatUserDeptDisplay(), handleAdd(), handleDelete() (+9 more) Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
### Community 18 - "Community 18" ### Community 18 - "Community 18"
Cohesion: 0.13 Cohesion: 0.12
Nodes (17): fetchCreateProjectSystem(), fetchCreateProjectSystemItem(), fetchDeleteProjectSystemItem(), fetchProjectSystemItems(), fetchProjectSystemList(), fetchUpdateProjectSystem(), handleAdd(), handleBatchDelete() (+9 more) Nodes (19): fetchCreateUser(), fetchDeleteUser(), fetchResetPassword(), fetchRoleOptions(), fetchUpdateUser(), fetchUserDetail(), formatUserDeptDisplay(), handleAdd() (+11 more)
### Community 19 - "Community 19" ### Community 19 - "Community 19"
Cohesion: 0.19 Cohesion: 0.19
@@ -182,126 +173,76 @@ Cohesion: 0.18
Nodes (9): auditorDisplay(), dash(), expressName(), formatYm(), formatYmd(), sampleTypeName(), siteName(), unitName() (+1 more) Nodes (9): auditorDisplay(), dash(), expressName(), formatYm(), formatYmd(), sampleTypeName(), siteName(), unitName() (+1 more)
### Community 25 - "Community 25" ### Community 25 - "Community 25"
Cohesion: 0.17 Cohesion: 0.18
Nodes (12): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchDeleteCellSampleType(), fetchUpdateCellSampleType(), handleAdd(), handleBatchDelete(), handleDelete(), handleReset() (+4 more) Nodes (11): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchDeleteCellSampleType(), fetchUpdateCellSampleType(), handleAdd(), handleDelete(), handleReset(), handleSearch() (+3 more)
### Community 26 - "Community 26" ### Community 26 - "Community 26"
Cohesion: 0.14
Nodes (8): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), useCeremony(), useTheme(), themeAnimation(), toggleTheme(), toggleTransition()
### Community 27 - "Community 27"
Cohesion: 0.18 Cohesion: 0.18
Nodes (11): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), handleAdd(), handleDelete(), handleReset(), handleSearch() (+3 more) Nodes (11): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), handleAdd(), handleDelete(), handleReset(), handleSearch() (+3 more)
### Community 28 - "Community 28" ### Community 29 - "Community 29"
Cohesion: 0.14
Nodes (2): fetchProductionTaskDetail(), fetchProductionTaskList()
### Community 30 - "Community 30"
Cohesion: 0.17
Nodes (3): fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList()
### Community 32 - "Community 32"
Cohesion: 0.39 Cohesion: 0.39
Nodes (6): isIgnorableScriptError(), normalizeErrorMessage(), registerPromiseErrorHandler(), registerResourceErrorHandler(), scriptErrorHandler(), setupErrorHandle() Nodes (6): isIgnorableScriptError(), normalizeErrorMessage(), registerPromiseErrorHandler(), registerResourceErrorHandler(), scriptErrorHandler(), setupErrorHandle()
### Community 33 - "Community 33" ### Community 30 - "Community 30"
Cohesion: 0.36 Cohesion: 0.36
Nodes (1): TableHeightCalculator Nodes (1): TableHeightCalculator
### Community 34 - "Community 34" ### Community 31 - "Community 31"
Cohesion: 0.33 Cohesion: 0.33
Nodes (2): logApiCryptoBootInfo(), maskSecret() Nodes (2): logApiCryptoBootInfo(), maskSecret()
### Community 35 - "Community 35" ### Community 32 - "Community 32"
Cohesion: 0.29 Cohesion: 0.29
Nodes (2): fetchLeaveDetail(), fetchLeaveList() Nodes (2): fetchLeaveDetail(), fetchLeaveList()
### Community 36 - "Community 36" ### Community 33 - "Community 33"
Cohesion: 0.29
Nodes (2): fetchQcMaterialList(), fetchQcMaterialOptions()
### Community 37 - "Community 37"
Cohesion: 0.47 Cohesion: 0.47
Nodes (3): isPaymentDueWithinWarnWindow(), parsePaymentDueYmd(), startOfLocalDay() Nodes (3): isPaymentDueWithinWarnWindow(), parsePaymentDueYmd(), startOfLocalDay()
### Community 38 - "Community 38" ### Community 34 - "Community 34"
Cohesion: 0.33
Nodes (2): fetchSampleReceptionCheckItemList(), fetchSampleReceptionCheckItemsActive()
### Community 39 - "Community 39"
Cohesion: 0.33
Nodes (2): fetchQcThirdPartyItemList(), fetchQcThirdPartyItemsActive()
### Community 40 - "Community 40"
Cohesion: 0.33
Nodes (2): fetchQcLabTestItemList(), fetchQcLabTestItemsActive()
### Community 41 - "Community 41"
Cohesion: 0.33
Nodes (2): fetchCellProductDetail(), fetchCellProductList()
### Community 42 - "Community 42"
Cohesion: 0.33
Nodes (2): fetchQcTaskDetail(), fetchQcTaskList()
### Community 43 - "Community 43"
Cohesion: 0.5 Cohesion: 0.5
Nodes (2): focusInput(), handleKeydown() Nodes (2): focusInput(), handleKeydown()
### Community 44 - "Community 44" ### Community 35 - "Community 35"
Cohesion: 0.67 Cohesion: 0.67
Nodes (2): if(), logSidebarMenu() Nodes (2): if(), logSidebarMenu()
### Community 45 - "Community 45" ### Community 36 - "Community 36"
Cohesion: 1.0 Cohesion: 1.0
Nodes (2): getSettingDefaults(), resetToDefaults() Nodes (2): getSettingDefaults(), resetToDefaults()
### Community 47 - "Community 47" ### Community 38 - "Community 38"
Cohesion: 1.0 Cohesion: 1.0
Nodes (2): defaultAvatarPathByRole(), resolveUserAvatarUrl() Nodes (2): defaultAvatarPathByRole(), resolveUserAvatarUrl()
## Knowledge Gaps ## Knowledge Gaps
- **Thin community `Community 22`** (17 nodes): `ComponentLoader`, `.constructor()`, `.createEmptyComponent()`, `.createErrorComponent()`, `.load()`, `.loadIframe()`, `.loadLayout()`, `.load()`, `RouteTransformer`, `.extractFirstSegment()`, `.handleFirstLevelRoute()`, `.handleIframeRoute()`, `.handleNormalRoute()`, `.isFirstLevelRoute()`, `.transform()`, `ComponentLoader.ts`, `RouteTransformer.ts` - **Thin community `Community 22`** (17 nodes): `ComponentLoader`, `.constructor()`, `.createEmptyComponent()`, `.createErrorComponent()`, `.load()`, `.loadIframe()`, `.loadLayout()`, `.load()`, `RouteTransformer`, `.extractFirstSegment()`, `.handleFirstLevelRoute()`, `.handleIframeRoute()`, `.handleNormalRoute()`, `.isFirstLevelRoute()`, `.transform()`, `ComponentLoader.ts`, `RouteTransformer.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 28`** (14 nodes): `fetchAddTaskStep()`, `fetchCreateProductionTask()`, `fetchDeleteTaskStep()`, `fetchProductionTaskDetail()`, `fetchProductionTaskList()`, `fetchReplaceStepConsumables()`, `fetchReplaceStepDataCollection()`, `fetchReplaceStepReagents()`, `fetchSetTaskInputs()`, `fetchSetTaskOutputs()`, `fetchUpdateProductionTask()`, `fetchUpdateProductionTaskStatus()`, `fetchUpdateTaskStep()`, `production-task.ts` - **Thin community `Community 30`** (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. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 33`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts` - **Thin community `Community 31`** (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. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 34`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts` - **Thin community `Community 32`** (7 nodes): `fetchCreateLeave()`, `fetchDeleteLeave()`, `fetchLeaveDetail()`, `fetchLeaveList()`, `fetchSubmitLeave()`, `fetchUpdateLeave()`, `leave.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 35`** (7 nodes): `fetchCreateLeave()`, `fetchDeleteLeave()`, `fetchLeaveDetail()`, `fetchLeaveList()`, `fetchSubmitLeave()`, `fetchUpdateLeave()`, `leave.ts` - **Thin community `Community 34`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 36`** (7 nodes): `fetchCreateQcMaterial()`, `fetchDeleteQcMaterial()`, `fetchQcMaterialList()`, `fetchQcMaterialOptions()`, `fetchStockInQcMaterial()`, `fetchUpdateQcMaterial()`, `qc-material.ts` - **Thin community `Community 35`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 38`** (6 nodes): `fetchCreateSampleReceptionCheckItem()`, `fetchDeleteSampleReceptionCheckItem()`, `fetchSampleReceptionCheckItemList()`, `fetchSampleReceptionCheckItemsActive()`, `fetchUpdateSampleReceptionCheckItem()`, `sample-reception-check-item.ts` - **Thin community `Community 36`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 39`** (6 nodes): `fetchCreateQcThirdPartyItem()`, `fetchDeleteQcThirdPartyItem()`, `fetchQcThirdPartyItemList()`, `fetchQcThirdPartyItemsActive()`, `fetchUpdateQcThirdPartyItem()`, `qc-third-party-item.ts` - **Thin community `Community 38`** (3 nodes): `defaultAvatarPathByRole()`, `resolveUserAvatarUrl()`, `user-avatar.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 40`** (6 nodes): `fetchCreateQcLabTestItem()`, `fetchDeleteQcLabTestItem()`, `fetchQcLabTestItemList()`, `fetchQcLabTestItemsActive()`, `fetchUpdateQcLabTestItem()`, `qc-lab-test-item.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 41`** (6 nodes): `fetchCellProductDetail()`, `fetchCellProductList()`, `fetchCreateCellProduct()`, `fetchDeleteCellProduct()`, `fetchUpdateCellProduct()`, `cell-product.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 42`** (6 nodes): `fetchCompleteQcTask()`, `fetchQcTaskDetail()`, `fetchQcTaskList()`, `fetchStartQcTask()`, `fetchUpdateQcTaskAttachments()`, `qc-task.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 43`** (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 44`** (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 45`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 47`** (3 nodes): `defaultAvatarPathByRole()`, `resolveUserAvatarUrl()`, `user-avatar.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted. Too small to be a meaningful cluster - may be noise or needs more connections extracted.
## Suggested Questions ## Suggested Questions
_Questions this graph is uniquely positioned to answer:_ _Questions this graph is uniquely positioned to answer:_
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 6`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 17`, `Community 18`, `Community 19`, `Community 20`, `Community 25`, `Community 27`, `Community 28`, `Community 30`, `Community 35`, `Community 36`, `Community 38`, `Community 39`, `Community 40`, `Community 41`, `Community 42`?** - **Why does `get()` connect `Community 0` to `Community 32`, `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 14`, `Community 15`, `Community 16`, `Community 18`, `Community 19`, `Community 20`, `Community 25`, `Community 26`?**
_High betweenness centrality (0.235) - this node is a cross-community bridge._ _High betweenness centrality (0.236) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 4` to `Community 0`, `Community 2`, `Community 3`, `Community 5`, `Community 11`, `Community 18`, `Community 19`?** - **Why does `push()` connect `Community 5` to `Community 1`, `Community 3`, `Community 6`, `Community 12`, `Community 13`, `Community 16`, `Community 19`?**
_High betweenness centrality (0.099) - this node is a cross-community bridge._ _High betweenness centrality (0.097) - this node is a cross-community bridge._
- **Why does `handleDynamicRoutes()` connect `Community 2` to `Community 10`?** - **Why does `handleDynamicRoutes()` connect `Community 3` to `Community 11`, `Community 13`?**
_High betweenness centrality (0.046) - this node is a cross-community bridge._ _High betweenness centrality (0.047) - this node is a cross-community bridge._
- **Are the 150 inferred relationships involving `get()` (e.g. with `buildTreePathLabelFromFlat()` and `alignFqPaymentDetailsForDisplay()`) actually correct?** - **Are the 150 inferred relationships involving `get()` (e.g. with `buildTreePathLabelFromFlat()` and `alignFqPaymentDetailsForDisplay()`) actually correct?**
_`get()` has 150 INFERRED edges - model-reasoned connections that need verification._ _`get()` has 150 INFERRED edges - model-reasoned connections that need verification._
- **Are the 20 inferred relationships involving `withFullscreenLoading()` (e.g. with `.close()` and `handleSubmit()`) actually correct?** - **Are the 20 inferred relationships involving `withFullscreenLoading()` (e.g. with `.close()` and `handleSubmit()`) actually correct?**
+4 -4
View File
@@ -57,12 +57,12 @@
</div> </div>
<div id="legend"></div> <div id="legend"></div>
</div> </div>
<div id="stats">1441 nodes &middot; 1845 edges &middot; 241 communities</div> <div id="stats">1444 nodes &middot; 1853 edges &middot; 232 communities</div>
</div> </div>
<script> <script>
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 34, "community_name": "Community 34", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 34, "community_name": "Community 34", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 34, "community_name": "Community 34", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.6, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 34, "community_name": "Community 34", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 34, "community_name": "Community 34", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 34, "community_name": "Community 34", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 80, "community_name": "Community 80", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 81, "community_name": "Community 81", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 16, "community_name": "Community 16", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.7, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 16, "community_name": "Community 16", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 16, "community_name": "Community 16", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 16, "community_name": "Community 16", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 16, "community_name": "Community 16", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_setuprolesdirective", "laLine truncated const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 31, "community_name": "Community 31", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 31, "community_name": "Community 31", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 31, "community_name": "Community 31", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.6, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 31, "community_name": "Community 31", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 31, "community_name": "Community 31", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 31, "community_name": "Community 31", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 71, "community_name": "Community 71", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 72, "community_name": "Community 72", "source_file": "shims-loose.d.ts", "file_type": "code", "degree": 0}, {"id": "directives_index_ts", "label": "index.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "index.ts", "community": 17, "community_name": "Community 17", "source_file": "directives/index.ts", "file_type": "code", "degree": 1}, {"id": "directives_index_setupglobdirectives", "label": "setupGlobDirectives()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.7, "font": {"size": 0, "color": "#ffffff"}, "title": "setupGlobDirectives()", "community": 17, "community_name": "Community 17", "source_file": "directives/index.ts", "file_type": "code", "degree": 5}, {"id": "directives_core_roles_ts", "label": "roles.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "roles.ts", "community": 17, "community_name": "Community 17", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 3}, {"id": "core_roles_checkrolepermission", "label": "checkRolePermission()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "checkRolePermission()", "community": 17, "community_name": "Community 17", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_removeelement", "label": "removeElement()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "removeElement()", "community": 17, "community_name": "Community 17", "source_file": "directives/core/roles.ts", "file_type": "code", "degree": 2}, {"id": "core_roles_setuprolesdirective", "laLine truncated
const RAW_EDGES = [{"from": "app_vue", "to": "src_app_refreshbuttonautoicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "src_app_refreshpaneltitleicons", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "app_vue", "to": "main_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "utils_sys_console_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_masksecret", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "main_ts", "to": "src_main_logapicryptobootinfo", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_main_masksecret", "to": "src_main_logapicryptobootinfo", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_ts", "to": "directives_index_setupglobdirectives", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_index_setupglobdirectives", "to": "core_auth_setupauthdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "core_roles_setuprolesdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_highlight_setuphighlightdirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_index_setupglobdirectives", "to": "business_ripple_setuprippledirective", "label": "calls", "title": "calls [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "directives_core_roles_ts", "to": "core_roles_checkrolepermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_roles_ts", "to": "core_roles_setuprolesdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_roles_checkrolepermission", "to": "core_roles_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_checkauthpermission", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_removeelement", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_core_auth_ts", "to": "core_auth_setupauthdirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "core_auth_checkauthpermission", "to": "core_auth_removeelement", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_ripple_ts", "to": "business_ripple_setuprippledirective", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_highlightcode", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_insertlinenumbers", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "directives_business_highlight_ts", "to": "business_highlight_addcopybutton", "label": "contains", "title": "contains [EXTRACTED]", "dLine truncated const 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": 228}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 86}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 76}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 75}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 49}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 48}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 40}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 36}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 36}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 29}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 27}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 27}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 27}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 26}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 25}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 23}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 22}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 20}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 20}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 19}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 19}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 17}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 17}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 16}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 16}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 16}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 15}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 15}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 14}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 13}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 12}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 9}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 8}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 8}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 7}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 7}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 7}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 6}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 6}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 6}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 6}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 6}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 6}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 5}, {"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": 3}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 3}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 3}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 3}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 3}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 3}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 3}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 3}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 3}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 2}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 2}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 2}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 2}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 2}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 2}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 2}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 2}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 2}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 2}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 2}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 2}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 2}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 2}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 2}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "count": 2}, {Line truncated const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 227}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 139}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 88}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 68}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 51}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 50}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 48}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 36}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 36}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 29}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 28}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 28}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 27}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 26}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 26}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 26}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 25}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 22}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 22}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 19}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 19}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 17}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 17}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 16}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 16}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 15}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 15}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 13}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 9}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 8}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 8}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 7}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 7}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 6}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 5}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 4}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 3}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 3}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 3}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 3}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 3}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 3}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 3}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 3}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 3}, {"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": 2}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 2}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 2}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 2}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 2}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 2}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 2}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 2}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 2}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 2}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 2}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 2}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 2}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 2}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 2}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 2}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 2}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 2}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 2}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 2}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 2}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 2}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "count": 2}, {"cLine truncated
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML // HTML-escape helper — prevents XSS when injecting graph data into innerHTML
function esc(s) { function esc(s) {
+5 -5
View File
@@ -200,7 +200,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/collection-protocol.ts": 1779244706.1724706, "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/collection-protocol.ts": 1779244706.1724706,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/chinaRegion.ts": 1778582067.8620915, "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/chinaRegion.ts": 1778582067.8620915,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts": 1779159587.6033742, "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts": 1779159587.6033742,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts": 1779270874.089264, "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts": 1779280840.7189047,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/ethnic.ts": 1778929297.3919344, "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/ethnic.ts": 1778929297.3919344,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-lab-test-item.ts": 1779017838.8231559, "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-lab-test-item.ts": 1779017838.8231559,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/cell-product.ts": 1779207897.9650705, "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/cell-product.ts": 1779207897.9650705,
@@ -297,12 +297,12 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-price/index.vue": 1779269555.0075119, "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-price/index.vue": 1779269555.0075119,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/project-price-system/index.vue": 1779269568.6848671, "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/project-price-system/index.vue": 1779269568.6848671,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-spec/index.vue": 1779269654.421631, "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-spec/index.vue": 1779269654.421631,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue": 1779257191.2613704, "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue": 1779280841.3977733,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/cell-sample-type/index.vue": 1779257191.2560186, "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/cell-sample-type/index.vue": 1779257191.2560186,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/insurance-company/index.vue": 1779269577.6780305, "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/insurance-company/index.vue": 1779269577.6780305,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue": 1779257191.2566798, "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue": 1779279039.353917,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue": 1779257191.261004, "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue": 1779275520.1554263,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue": 1779257191.260546, "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue": 1779278206.0677836,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/assets/svg/loading.ts": 1778582067.932299, "/Users/wuzilong/work/00code/zkxw/web-admin/src/assets/svg/loading.ts": 1778582067.932299,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/index.ts": 1778582068.0218356, "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/index.ts": 1778582068.0218356,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/worktab.ts": 1779240489.093459, "/Users/wuzilong/work/00code/zkxw/web-admin/src/store/modules/worktab.ts": 1779240489.093459,
+1
View File
@@ -1773,6 +1773,7 @@ export function fetchInsuranceCompanyList(params?: {
page?: number page?: number
pageSize?: number pageSize?: number
keyword?: string keyword?: string
status?: string
}) { }) {
return request.get({ url: '/web/admin/insurance-companies', params }) return request.get({ url: '/web/admin/insurance-companies', params })
} }
+30 -2
View File
@@ -39,6 +39,7 @@ export type MaterialStockLog = {
purpose: string purpose: string
remark: string remark: string
createBy: string createBy: string
createByName?: string
createTime: string createTime: string
updateTime: string updateTime: string
} }
@@ -82,7 +83,10 @@ export function fetchDeleteMaterial(id: string) {
}) })
} }
export function fetchStockInMaterial(id: string, data: { qty: number; remark?: string }) { export function fetchStockInMaterial(
id: string,
data: { qty: number; remark?: string; stockInTime?: string }
) {
return request.post<Material>({ return request.post<Material>({
url: `/web/admin/materials/${id}/stock-in`, url: `/web/admin/materials/${id}/stock-in`,
data data
@@ -91,7 +95,7 @@ export function fetchStockInMaterial(id: string, data: { qty: number; remark?: s
export function fetchStockOutMaterial( export function fetchStockOutMaterial(
id: string, id: string,
data: { qty: number; receiver?: string; purpose?: string; remark?: string } data: { qty: number; receiver?: string; purpose?: string; remark?: string; stockOutTime?: string }
) { ) {
return request.post<Material>({ return request.post<Material>({
url: `/web/admin/materials/${id}/stock-out`, url: `/web/admin/materials/${id}/stock-out`,
@@ -99,6 +103,30 @@ export function fetchStockOutMaterial(
}) })
} }
export function fetchBatchStockInMaterial(data: {
items: { materialId: string; qty: number; remark?: string }[]
remark?: string
stockInTime?: string
}) {
return request.post<{ count: number }>({
url: '/web/admin/materials/batch-stock-in',
data
})
}
export function fetchBatchStockOutMaterial(data: {
items: { materialId: string; qty: number; remark?: string }[]
receiver?: string
purpose?: string
remark?: string
stockOutTime?: string
}) {
return request.post<{ count: number }>({
url: '/web/admin/materials/batch-stock-out',
data
})
}
export function fetchMaterialStockLogList(params?: { export function fetchMaterialStockLogList(params?: {
page?: number page?: number
pageSize?: number pageSize?: number
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_collection_protocol_no_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L1"}, {"id": "collection_protocol_no_index_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L457"}, {"id": "collection_protocol_no_index_resolveissuedusername", "label": "resolveIssuedUserName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L504"}, {"id": "collection_protocol_no_index_handleselectionchange", "label": "handleSelectionChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L539"}, {"id": "collection_protocol_no_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L543"}, {"id": "collection_protocol_no_index_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L559"}, {"id": "collection_protocol_no_index_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L564"}, {"id": "collection_protocol_no_index_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L571"}, {"id": "collection_protocol_no_index_handleadd", "label": "handleAdd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L582"}, {"id": "collection_protocol_no_index_handleedit", "label": "handleEdit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L591"}, {"id": "collection_protocol_no_index_handlesubmit", "label": "handleSubmit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L607"}, {"id": "collection_protocol_no_index_handledelete", "label": "handleDelete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L642"}, {"id": "collection_protocol_no_index_handlebatchdelete", "label": "handleBatchDelete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L649"}, {"id": "collection_protocol_no_index_handlebatchrevoke", "label": "handleBatchRevoke()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L663"}, {"id": "collection_protocol_no_index_openbatchgenerate", "label": "openBatchGenerate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L679"}, {"id": "collection_protocol_no_index_handlebatchgenerate", "label": "handleBatchGenerate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L688"}, {"id": "collection_protocol_no_index_openbatchissue", "label": "openBatchIssue()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L711"}, {"id": "collection_protocol_no_index_handlebatchissue", "label": "handleBatchIssue()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L718"}, {"id": "collection_protocol_no_index_loaduseroptions", "label": "loadUserOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue", "source_location": "L737"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_collection_protocol_no_index_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-aLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_customer_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L1"}, {"id": "customer_index_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L276"}, {"id": "customer_index_handleselectionchange", "label": "handleSelectionChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L296"}, {"id": "customer_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L300"}, {"id": "customer_index_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L315"}, {"id": "customer_index_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L320"}, {"id": "customer_index_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L326"}, {"id": "customer_index_handleadd", "label": "handleAdd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L338"}, {"id": "customer_index_handleedit", "label": "handleEdit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L346"}, {"id": "customer_index_handlesubmit", "label": "handleSubmit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L362"}, {"id": "customer_index_handledelete", "label": "handleDelete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L391"}, {"id": "customer_index_handlebatchdelete", "label": "handleBatchDelete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L398"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_customer_index_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L228", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_customer_index_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L229", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_customer_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_fullscreen_loading", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L230", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_customer_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_admin", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L231", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_customer_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_system_view_dialog_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L237", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_customer_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_status_tag_registry", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue", "source_location": "L238", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_customer_index_vue", "target": "customer_index_handleview", "relation": "contains", "confidence": "EXTRACTED", "Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_admin_ts", "label": "admin.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L1"}, {"id": "api_admin_fetchgetmenulist", "label": "fetchGetMenuList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L10"}, {"id": "api_admin_fetchgetrolelist", "label": "fetchGetRoleList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L19"}, {"id": "api_admin_fetchuseroptions", "label": "fetchUserOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L26"}, {"id": "api_admin_fetchroleoptions", "label": "fetchRoleOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L33"}, {"id": "api_admin_fetchtenantlist", "label": "fetchTenantList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L43"}, {"id": "api_admin_fetchcreatetenant", "label": "fetchCreateTenant()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L56"}, {"id": "api_admin_fetchupdatetenant", "label": "fetchUpdateTenant()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L71"}, {"id": "api_admin_fetchdeletetenant", "label": "fetchDeleteTenant()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L89"}, {"id": "api_admin_fetchuserlist", "label": "fetchUserList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L100"}, {"id": "api_admin_fetchuserdetail", "label": "fetchUserDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L119"}, {"id": "api_admin_fetchcreateuser", "label": "fetchCreateUser()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L125"}, {"id": "api_admin_fetchupdateuser", "label": "fetchUpdateUser()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L147"}, {"id": "api_admin_fetchdeleteuser", "label": "fetchDeleteUser()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L170"}, {"id": "api_admin_fetchresetpassword", "label": "fetchResetPassword()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L177"}, {"id": "api_admin_fetchuploaduseravatar", "label": "fetchUploadUserAvatar()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L185"}, {"id": "api_admin_fetchregionlist", "label": "fetchRegionList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L196"}, {"id": "api_admin_fetchactiveregions", "label": "fetchActiveRegions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L214"}, {"id": "api_admin_fetchnotdeletedregions", "label": "fetchNotDeletedRegions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L231"}, {"id": "api_admin_fetchcategorylist", "label": "fetchCategoryList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L259"}, {"id": "api_admin_fetchcreatecategory", "label": "fetchCreateCategory()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L277"}, {"id": "api_admin_fetchupdatecategory", "label": "fetchUpdateCategory()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L290"}, {"id": "api_admin_fetchdeletecategory", "label": "fetchDeleteCategory()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L307"}, {"id": "api_admin_fetchuploadcategoryimage", "label": "fetchUploadCategoryImage()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L313"}, {"id": "api_admin_fetchunitlist", "label": "fetchUnitList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts", "source_location": "L324"}, {"id": "api_admin_fetchcreateunit", "label": "fetchCrLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_sample_code_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L1"}, {"id": "sample_code_index_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L496"}, {"id": "sample_code_index_handleselectionchange", "label": "handleSelectionChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L573"}, {"id": "sample_code_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L577"}, {"id": "sample_code_index_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L594"}, {"id": "sample_code_index_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L599"}, {"id": "sample_code_index_resetform", "label": "resetForm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L607"}, {"id": "sample_code_index_loaduseroptions", "label": "loadUserOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L619"}, {"id": "sample_code_index_handleadd", "label": "handleAdd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L628"}, {"id": "sample_code_index_handleedit", "label": "handleEdit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L637"}, {"id": "sample_code_index_handlesubmit", "label": "handleSubmit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L654"}, {"id": "sample_code_index_handledelete", "label": "handleDelete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L690"}, {"id": "sample_code_index_handlebatchdelete", "label": "handleBatchDelete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L697"}, {"id": "sample_code_index_handlebatchrevoke", "label": "handleBatchRevoke()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L711"}, {"id": "sample_code_index_openbatchgenerate", "label": "openBatchGenerate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L727"}, {"id": "sample_code_index_handlebatchgenerate", "label": "handleBatchGenerate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L736"}, {"id": "sample_code_index_openbatchissue", "label": "openBatchIssue()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L759"}, {"id": "sample_code_index_handlebatchissue", "label": "handleBatchIssue()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L766"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_sample_code_index_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L430", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_sample_code_index_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue", "source_location": "L431", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_sample_code_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_system_view_dialog_index_vue", "relation": "imports_from", "confidence": "ELine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_collection_region_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L1"}, {"id": "collection_region_index_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L433"}, {"id": "collection_region_index_onhospitalselectionchange", "label": "onHospitalSelectionChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L442"}, {"id": "collection_region_index_handleselectionchange", "label": "handleSelectionChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L446"}, {"id": "collection_region_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L450"}, {"id": "collection_region_index_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L465"}, {"id": "collection_region_index_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L470"}, {"id": "collection_region_index_handleadd", "label": "handleAdd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L476"}, {"id": "collection_region_index_handleedit", "label": "handleEdit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L487"}, {"id": "collection_region_index_submitregion", "label": "submitRegion()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L498"}, {"id": "collection_region_index_handledelete", "label": "handleDelete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L522"}, {"id": "collection_region_index_handlebatchdelete", "label": "handleBatchDelete()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L531"}, {"id": "collection_region_index_openhospitaldialog", "label": "openHospitalDialog()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L551"}, {"id": "collection_region_index_loadhospitals", "label": "loadHospitals()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L561"}, {"id": "collection_region_index_onhospitaldialogclosed", "label": "onHospitalDialogClosed()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L576"}, {"id": "collection_region_index_handleaddhospital", "label": "handleAddHospital()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L583"}, {"id": "collection_region_index_handleedithospital", "label": "handleEditHospital()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L594"}, {"id": "collection_region_index_submithospital", "label": "submitHospital()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L605"}, {"id": "collection_region_index_handledeletehospital", "label": "handleDeleteHospital()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L630"}, {"id": "collection_region_index_handlebatchdeletehospital", "label": "handleBatchDeleteHospital()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue", "source_location": "L637"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_collection_region_index_vue", "target": "element_plus", "relatiLine truncated
@@ -389,6 +389,7 @@
page: pagination.page, page: pagination.page,
pageSize: pagination.pageSize, pageSize: pagination.pageSize,
keyword: searchForm.keyword || undefined, keyword: searchForm.keyword || undefined,
status: searchForm.tag || undefined
}) })
tableData.value = (res as any)?.list || [] tableData.value = (res as any)?.list || []
pagination.total = (res as any)?.total ?? 0 pagination.total = (res as any)?.total ?? 0
@@ -113,13 +113,16 @@
{{ row.changeType === 'ck' ? (row.purpose || '-') : '-' }} {{ row.changeType === 'ck' ? (row.purpose || '-') : '-' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column label="操作人" min-width="100" align="center" header-align="center">
prop="createBy" <template #default="{ row }">
label="操作人" {{ row.createByName || row.createBy || '-' }}
min-width="100" </template>
align="center" </el-table-column>
header-align="center" <el-table-column label="备注" min-width="140" align="center" header-align="center" show-overflow-tooltip>
/> <template #default="{ row }">
{{ row.remark || '-' }}
</template>
</el-table-column>
<el-table-column <el-table-column
prop="createTime" prop="createTime"
label="操作时间" label="操作时间"
@@ -197,9 +200,9 @@
{ label: '变动后库存', value: String(row.stockAfter ?? 0) }, { label: '变动后库存', value: String(row.stockAfter ?? 0) },
{ label: '领用人', value: row.changeType === 'ck' ? (row.receiver || '-') : '-' }, { label: '领用人', value: row.changeType === 'ck' ? (row.receiver || '-') : '-' },
{ label: '用途', value: row.changeType === 'ck' ? (row.purpose || '-') : '-' }, { label: '用途', value: row.changeType === 'ck' ? (row.purpose || '-') : '-' },
{ label: '操作人', value: row.createBy }, { label: '操作人', value: row.createByName || row.createBy || '-' },
{ label: '操作时间', value: row.createTime }, { label: '备注', value: row.remark || '—', span: true },
{ label: '备注', value: row.remark || '—', span: true } { label: '操作时间', value: row.createTime }
] ]
} }
] ]
@@ -54,11 +54,20 @@
<el-icon><Plus /></el-icon> <el-icon><Plus /></el-icon>
新增物料 新增物料
</el-button> </el-button>
<el-button class="btn-ghost" @click="handleBatchStockIn">
<el-icon><Upload /></el-icon>
批量入库
</el-button>
<el-button class="btn-ghost" @click="handleBatchStockOut">
<el-icon><Download /></el-icon>
批量出库
</el-button>
</div> </div>
</div> </div>
<div class="list-body list-wrap"> <div class="list-body list-wrap">
<el-table <el-table
ref="tableRef"
class="list-table" class="list-table"
:data="tableData" :data="tableData"
v-loading="loading" v-loading="loading"
@@ -125,6 +134,14 @@
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column
prop="remark"
label="备注"
min-width="140"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column label="操作" min-width="400" fixed="right" align="center" header-align="center"> <el-table-column label="操作" min-width="400" fixed="right" align="center" header-align="center">
<template #default="{ row }"> <template #default="{ row }">
<el-button class="btn-op-item" @click="handleStockIn(row)"><el-icon><Upload /></el-icon>入库</el-button> <el-button class="btn-op-item" @click="handleStockIn(row)"><el-icon><Upload /></el-icon>入库</el-button>
@@ -190,7 +207,23 @@
<el-input v-model="formData.specModel" placeholder="请输入规格型号" /> <el-input v-model="formData.specModel" placeholder="请输入规格型号" />
</el-form-item> </el-form-item>
<el-form-item label="单位" prop="unit"> <el-form-item label="单位" prop="unit">
<el-input v-model="formData.unit" placeholder="请输入单位" /> <el-select
v-model="formData.unit"
placeholder="请选择单位"
clearable
filterable
remote
reserve-keyword
:loading="unitOptionsLoading"
:remote-method="searchUnitOptions"
>
<el-option
v-for="item in unitOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status"> <el-radio-group v-model="formData.status">
@@ -248,6 +281,15 @@
style="width: 100%" style="width: 100%"
/> />
</el-form-item> </el-form-item>
<el-form-item label="入库时间" prop="stockInTime">
<el-date-picker
v-model="stockInForm.stockInTime"
type="datetime"
placeholder="选择入库时间"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="备注"> <el-form-item label="备注">
<el-input <el-input
v-model="stockInForm.remark" v-model="stockInForm.remark"
@@ -302,8 +344,34 @@
style="width: 100%" style="width: 100%"
/> />
</el-form-item> </el-form-item>
<el-form-item label="出库时间" prop="stockOutTime">
<el-date-picker
v-model="stockOutForm.stockOutTime"
type="datetime"
placeholder="选择出库时间"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="领用人" prop="receiver"> <el-form-item label="领用人" prop="receiver">
<el-input v-model="stockOutForm.receiver" placeholder="请输入领用人" /> <el-select
v-model="stockOutForm.receiver"
placeholder="请选择领用人"
clearable
filterable
remote
reserve-keyword
:loading="receiverUserLoading"
:remote-method="searchReceiverUsers"
style="width: 100%"
>
<el-option
v-for="u in receiverUserOptions"
:key="u.id"
:label="formatReceiverUserLabel(u)"
:value="(u.nickName || '').trim()"
/>
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="用途"> <el-form-item label="用途">
<el-input <el-input
@@ -339,6 +407,307 @@
</template> </template>
</el-dialog> </el-dialog>
<!-- 批量入库弹窗 -->
<el-dialog
v-model="batchStockInVisible"
title="批量入库"
width="920px"
class="dialog-form-layout material-batch-stock-dialog"
align-center
destroy-on-close
:close-on-click-modal="false"
>
<el-form
ref="batchStockInFormRef"
:model="batchStockInForm"
:rules="batchStockInRules"
label-position="top"
scroll-to-error
:scroll-into-view-options="{ behavior: 'smooth', block: 'center' }"
>
<div class="form-grid-2 batch-stock-move-head">
<el-form-item label="入库时间" prop="stockInTime">
<el-date-picker
v-model="batchStockInForm.stockInTime"
type="datetime"
placeholder="选择入库时间"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="备注">
<el-input
v-model="batchStockInForm.remark"
type="textarea"
:rows="2"
placeholder="可选,未填写行备注时将作为默认备注"
/>
</el-form-item>
</div>
<div class="batch-stock-move-lines">
<div class="batch-stock-move-lines-head">
<div class="batch-stock-move-lines-head-left">
<span class="batch-stock-move-lines-title">入库明细</span>
<span class="batch-stock-move-lines-hint">
共 {{ batchStockInLines.length }} 项,请搜索添加物料并填写入库数量
</span>
</div>
<el-select
v-model="batchInMaterialPickId"
class="batch-stock-move-material-select"
placeholder="搜索物料编码/名称并添加"
filterable
remote
clearable
reserve-keyword
:loading="batchInMaterialPickLoading"
:remote-method="searchBatchInMaterials"
@change="onBatchInMaterialPick"
>
<el-option
v-for="m in batchInMaterialOptions"
:key="m.id"
:label="formatBatchMaterialOptionLabel(m)"
:value="m.id"
:disabled="isBatchInMaterialOptionDisabled(m)"
/>
</el-select>
</div>
<el-table
v-if="batchStockInLines.length"
:data="batchStockInLines"
stripe
class="list-table inner-table"
max-height="320"
>
<el-table-column
type="index"
label="序号"
width="56"
align="center"
header-align="center"
:index="(index) => index + 1"
/>
<el-table-column prop="materialCode" label="物料编码" min-width="120" align="center" header-align="center" />
<el-table-column prop="materialName" label="物料名称" min-width="140" align="center" header-align="center" />
<el-table-column prop="unit" label="单位" width="80" align="center" header-align="center" />
<el-table-column label="当前库存" width="100" align="center" header-align="center">
<template #default="{ row }">{{ row.stockQty }}</template>
</el-table-column>
<el-table-column label="入库数量" min-width="130" align="center" header-align="center">
<template #default="{ row }">
<el-input-number
v-model="row.qty"
:min="0.01"
:precision="2"
:step="1"
controls-position="right"
style="width: 100%"
/>
</template>
</el-table-column>
<el-table-column label="备注" min-width="160" align="center" header-align="center">
<template #default="{ row }">
<el-input v-model="row.remark" placeholder="可选" clearable class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="操作" width="80" align="center" header-align="center">
<template #default="{ $index }">
<el-button link type="danger" size="small" @click="batchStockInLines.splice($index, 1)">
移除
</el-button>
</template>
</el-table-column>
</el-table>
<el-empty
v-else
description="请通过上方搜索框添加要入库的物料"
:image-size="56"
/>
</div>
</el-form>
<template #footer>
<el-button class="btn-ghost" @click="batchStockInVisible = false">
<el-icon><Close /></el-icon>
取消
</el-button>
<el-button
class="btn-main"
type="primary"
:loading="batchStockInLoading"
@click="handleBatchStockInSubmit"
>
<el-icon><Check /></el-icon>
确认入库
</el-button>
</template>
</el-dialog>
<!-- 批量出库弹窗 -->
<el-dialog
v-model="batchStockOutVisible"
title="批量出库"
width="920px"
class="dialog-form-layout material-batch-stock-dialog"
align-center
destroy-on-close
:close-on-click-modal="false"
>
<el-form
ref="batchStockOutFormRef"
:model="batchStockOutForm"
:rules="batchStockOutRules"
label-position="top"
scroll-to-error
:scroll-into-view-options="{ behavior: 'smooth', block: 'center' }"
>
<div class="form-grid-2 batch-stock-move-head">
<el-form-item label="出库时间" prop="stockOutTime">
<el-date-picker
v-model="batchStockOutForm.stockOutTime"
type="datetime"
placeholder="选择出库时间"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="领用人" prop="receiver">
<el-select
v-model="batchStockOutForm.receiver"
placeholder="请选择领用人"
clearable
filterable
remote
reserve-keyword
:loading="receiverUserLoading"
:remote-method="searchReceiverUsers"
style="width: 100%"
>
<el-option
v-for="u in receiverUserOptions"
:key="u.id"
:label="formatReceiverUserLabel(u)"
:value="(u.nickName || '').trim()"
/>
</el-select>
</el-form-item>
<el-form-item label="用途">
<el-input
v-model="batchStockOutForm.purpose"
type="textarea"
:rows="2"
placeholder="可选"
/>
</el-form-item>
<el-form-item label="备注">
<el-input
v-model="batchStockOutForm.remark"
type="textarea"
:rows="2"
placeholder="可选"
/>
</el-form-item>
</div>
<div class="batch-stock-move-lines">
<div class="batch-stock-move-lines-head">
<div class="batch-stock-move-lines-head-left">
<span class="batch-stock-move-lines-title">出库明细</span>
<span class="batch-stock-move-lines-hint">
共 {{ batchStockOutLines.length }} 项,请搜索添加物料并填写出库数量
</span>
</div>
<el-select
v-model="batchOutMaterialPickId"
class="batch-stock-move-material-select"
placeholder="搜索物料编码/名称并添加"
filterable
remote
clearable
reserve-keyword
:loading="batchOutMaterialPickLoading"
:remote-method="searchBatchOutMaterials"
@change="onBatchOutMaterialPick"
>
<el-option
v-for="m in batchMaterialOptions"
:key="m.id"
:label="formatBatchMaterialOptionLabel(m)"
:value="m.id"
:disabled="isBatchOutMaterialOptionDisabled(m)"
/>
</el-select>
</div>
<el-table
v-if="batchStockOutLines.length"
:data="batchStockOutLines"
stripe
class="list-table inner-table"
max-height="320"
>
<el-table-column
type="index"
label="序号"
width="56"
align="center"
header-align="center"
:index="(index) => index + 1"
/>
<el-table-column prop="materialCode" label="物料编码" min-width="120" align="center" header-align="center" />
<el-table-column prop="materialName" label="物料名称" min-width="140" align="center" header-align="center" />
<el-table-column prop="unit" label="单位" width="80" align="center" header-align="center" />
<el-table-column label="当前库存" width="100" align="center" header-align="center">
<template #default="{ row }">{{ row.stockQty }}</template>
</el-table-column>
<el-table-column label="出库数量" min-width="130" align="center" header-align="center">
<template #default="{ row }">
<el-input-number
v-model="row.qty"
:min="0.01"
:max="row.stockQty"
:precision="2"
:step="1"
controls-position="right"
style="width: 100%"
/>
</template>
</el-table-column>
<el-table-column label="备注" min-width="160" align="center" header-align="center">
<template #default="{ row }">
<el-input v-model="row.remark" placeholder="可选" clearable class="inner-cell-input" />
</template>
</el-table-column>
<el-table-column label="操作" width="80" align="center" header-align="center">
<template #default="{ $index }">
<el-button link type="danger" size="small" @click="batchStockOutLines.splice($index, 1)">
移除
</el-button>
</template>
</el-table-column>
</el-table>
<el-empty
v-else
description="请通过上方搜索框添加要出库的物料"
:image-size="56"
/>
</div>
</el-form>
<template #footer>
<el-button class="btn-ghost" @click="batchStockOutVisible = false">
<el-icon><Close /></el-icon>
取消
</el-button>
<el-button
class="btn-main"
type="primary"
:loading="batchStockOutLoading"
@click="handleBatchStockOutSubmit"
>
<el-icon><Check /></el-icon>
确认出库
</el-button>
</template>
</el-dialog>
<!-- 查看弹窗 --> <!-- 查看弹窗 -->
<SystemViewDialog <SystemViewDialog
v-model:visible="viewVisible" v-model:visible="viewVisible"
@@ -356,20 +725,23 @@
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Close, Check, View, Box, RefreshLeft, Search, Upload, Download, Edit, Delete } from '@element-plus/icons-vue' import { Plus, Close, Check, View, Box, RefreshLeft, Search, Upload, Download, Edit, Delete } from '@element-plus/icons-vue'
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue' import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
import { fetchDictDataOptions } from '@/api/admin' import { fetchDictDataOptions, fetchItemUnitList, fetchUserList } from '@/api/admin'
import { import {
fetchMaterialList, fetchMaterialList,
fetchCreateMaterial, fetchCreateMaterial,
fetchUpdateMaterial, fetchUpdateMaterial,
fetchDeleteMaterial, fetchDeleteMaterial,
fetchStockInMaterial, fetchStockInMaterial,
fetchStockOutMaterial fetchStockOutMaterial,
fetchBatchStockInMaterial,
fetchBatchStockOutMaterial
} from '@/api/material' } from '@/api/material'
import type { Material } from '@/api/material' import type { Material } from '@/api/material'
defineOptions({ name: 'CellStorageMaterial' }) defineOptions({ name: 'CellStorageMaterial' })
const searchForm = reactive({ keyword: '', category: '', status: '' }) const searchForm = reactive({ keyword: '', category: '', status: '' })
const tableRef = ref()
const tableData = ref<Material[]>([]) const tableData = ref<Material[]>([])
const selectedRows = ref<Material[]>([]) const selectedRows = ref<Material[]>([])
const loading = ref(false) const loading = ref(false)
@@ -378,6 +750,43 @@
// 字典选项 // 字典选项
const categoryOptions = ref<{ label: string; value: string }[]>([]) const categoryOptions = ref<{ label: string; value: string }[]>([])
// 物品单位(来自物品单位管理)
const unitOptions = ref<{ label: string; value: string }[]>([])
const unitOptionsLoading = ref(false)
function mapUnitOption(u: { unitName?: string; unitCode?: string }) {
const name = (u.unitName || '').trim()
const code = (u.unitCode || '').trim()
return {
label: code ? `${name}(${code})` : name,
value: name
}
}
function ensureUnitOption(unitName: string) {
const v = unitName?.trim()
if (!v) return
if (!unitOptions.value.some((o) => o.value === v)) {
unitOptions.value = [{ label: v, value: v }, ...unitOptions.value]
}
}
async function searchUnitOptions(query: string) {
unitOptionsLoading.value = true
try {
const res = await fetchItemUnitList({
page: 1,
pageSize: 100,
keyword: query?.trim() || undefined
})
unitOptions.value = (res.list || []).map(mapUnitOption).filter((o) => o.value)
} catch {
unitOptions.value = []
} finally {
unitOptionsLoading.value = false
}
}
// 新增/编辑 // 新增/编辑
const dialogVisible = ref(false) const dialogVisible = ref(false)
const dialogTitle = ref('新增物料') const dialogTitle = ref('新增物料')
@@ -406,10 +815,11 @@
const stockInLoading = ref(false) const stockInLoading = ref(false)
const stockInFormRef = ref() const stockInFormRef = ref()
const stockInMaterialId = ref<string | null>(null) const stockInMaterialId = ref<string | null>(null)
const stockInForm = reactive({ qty: 1, remark: '' }) const stockInForm = reactive({ qty: 1, stockInTime: '', remark: '' })
const stockInRules = { const stockInRules = {
qty: [{ required: true, message: '请输入入库数量', trigger: 'blur' }] qty: [{ required: true, message: '请输入入库数量', trigger: 'blur' }],
stockInTime: [{ required: true, message: '请选择入库时间', trigger: 'change' }]
} }
// 出库 // 出库
@@ -418,11 +828,104 @@
const stockOutFormRef = ref() const stockOutFormRef = ref()
const stockOutMaterialId = ref<string | null>(null) const stockOutMaterialId = ref<string | null>(null)
const stockOutStockQty = ref(0) const stockOutStockQty = ref(0)
const stockOutForm = reactive({ qty: 1, receiver: '', purpose: '', remark: '' }) const stockOutForm = reactive({ qty: 1, stockOutTime: '', receiver: '', purpose: '', remark: '' })
const receiverUserOptions = ref<Api.User.UserItem[]>([])
const receiverUserLoading = ref(false)
function formatReceiverUserLabel(u: Api.User.UserItem) {
const name = (u.nickName || '').trim() || '-'
const no = (u.userNo || '').trim()
const phone = (u.phoneNo || '').trim()
const parts = [name]
if (no) parts.push(no)
if (phone) parts.push(phone)
return parts.join(' · ')
}
async function searchReceiverUsers(query: string) {
receiverUserLoading.value = true
try {
const res = await fetchUserList({
page: 1,
pageSize: 50,
keyword: query?.trim() || undefined,
status: '1'
})
receiverUserOptions.value = res.list || []
} catch {
receiverUserOptions.value = []
} finally {
receiverUserLoading.value = false
}
}
const stockOutRules = { const stockOutRules = {
qty: [{ required: true, message: '请输入出库数量', trigger: 'blur' }], qty: [{ required: true, message: '请输入出库数量', trigger: 'blur' }],
receiver: [{ required: true, message: '请输入领用人', trigger: 'blur' }] stockOutTime: [{ required: true, message: '请选择出库时间', trigger: 'change' }],
receiver: [{ required: true, message: '请选择领用人', trigger: 'change' }]
}
// 批量入库
type BatchStockInLine = {
materialId: string
materialCode: string
materialName: string
unit: string
stockQty: number
qty: number
remark: string
}
const batchStockInVisible = ref(false)
const batchStockInLoading = ref(false)
const batchStockInFormRef = ref()
const batchStockInLines = ref<BatchStockInLine[]>([])
const batchInMaterialPickId = ref('')
const batchInMaterialOptions = ref<Material[]>([])
const batchInMaterialPickLoading = ref(false)
const batchStockInForm = reactive({
stockInTime: '',
remark: ''
})
const batchStockInRules = {
stockInTime: [{ required: true, message: '请选择入库时间', trigger: 'change' }]
}
// 批量出库
type BatchStockOutLine = {
materialId: string
materialCode: string
materialName: string
unit: string
stockQty: number
qty: number
remark: string
}
const batchStockOutVisible = ref(false)
const batchStockOutLoading = ref(false)
const batchStockOutFormRef = ref()
const batchStockOutLines = ref<BatchStockOutLine[]>([])
const batchOutMaterialPickId = ref('')
const batchOutMaterialOptions = ref<Material[]>([])
const batchOutMaterialPickLoading = ref(false)
const batchStockOutForm = reactive({
stockOutTime: '',
receiver: '',
purpose: '',
remark: ''
})
const batchStockOutRules = {
stockOutTime: [{ required: true, message: '请选择出库时间', trigger: 'change' }],
receiver: [{ required: true, message: '请选择领用人', trigger: 'change' }]
}
function formatNowDatetime() {
const now = new Date()
const pad = (n: number) => String(n).padStart(2, '0')
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
} }
// 查看 // 查看
@@ -535,6 +1038,7 @@
dialogTitle.value = '新增物料' dialogTitle.value = '新增物料'
resetForm() resetForm()
dialogVisible.value = true dialogVisible.value = true
void searchUnitOptions('')
formRef.value?.clearValidate?.() formRef.value?.clearValidate?.()
} }
@@ -549,7 +1053,9 @@
formData.unit = row.unit || '' formData.unit = row.unit || ''
formData.status = row.status || '1' formData.status = row.status || '1'
formData.remark = row.remark || '' formData.remark = row.remark || ''
ensureUnitOption(row.unit || '')
dialogVisible.value = true dialogVisible.value = true
void searchUnitOptions('')
formRef.value?.clearValidate?.() formRef.value?.clearValidate?.()
} }
@@ -596,6 +1102,7 @@
function handleStockIn(row: Material) { function handleStockIn(row: Material) {
stockInMaterialId.value = row.id stockInMaterialId.value = row.id
stockInForm.qty = 1 stockInForm.qty = 1
stockInForm.stockInTime = formatNowDatetime()
stockInForm.remark = '' stockInForm.remark = ''
stockInVisible.value = true stockInVisible.value = true
stockInFormRef.value?.clearValidate?.() stockInFormRef.value?.clearValidate?.()
@@ -607,6 +1114,7 @@
try { try {
await fetchStockInMaterial(stockInMaterialId.value!, { await fetchStockInMaterial(stockInMaterialId.value!, {
qty: stockInForm.qty, qty: stockInForm.qty,
stockInTime: stockInForm.stockInTime || undefined,
remark: stockInForm.remark?.trim() || undefined remark: stockInForm.remark?.trim() || undefined
}) })
ElMessage.success('入库成功') ElMessage.success('入库成功')
@@ -623,10 +1131,12 @@
stockOutMaterialId.value = row.id stockOutMaterialId.value = row.id
stockOutStockQty.value = row.stockQty ?? 0 stockOutStockQty.value = row.stockQty ?? 0
stockOutForm.qty = 1 stockOutForm.qty = 1
stockOutForm.stockOutTime = formatNowDatetime()
stockOutForm.receiver = '' stockOutForm.receiver = ''
stockOutForm.purpose = '' stockOutForm.purpose = ''
stockOutForm.remark = '' stockOutForm.remark = ''
stockOutVisible.value = true stockOutVisible.value = true
void searchReceiverUsers('')
stockOutFormRef.value?.clearValidate?.() stockOutFormRef.value?.clearValidate?.()
} }
@@ -640,6 +1150,7 @@
try { try {
await fetchStockOutMaterial(stockOutMaterialId.value!, { await fetchStockOutMaterial(stockOutMaterialId.value!, {
qty: stockOutForm.qty, qty: stockOutForm.qty,
stockOutTime: stockOutForm.stockOutTime || undefined,
receiver: stockOutForm.receiver?.trim() || undefined, receiver: stockOutForm.receiver?.trim() || undefined,
purpose: stockOutForm.purpose?.trim() || undefined, purpose: stockOutForm.purpose?.trim() || undefined,
remark: stockOutForm.remark?.trim() || undefined remark: stockOutForm.remark?.trim() || undefined
@@ -654,6 +1165,227 @@
} }
} }
function formatBatchMaterialOptionLabel(m: Material) {
const name = m.materialName || '-'
const code = m.materialCode || ''
const stock = m.stockQty ?? 0
return code ? `${name}(${code})· 库存 ${stock}` : `${name} · 库存 ${stock}`
}
function isBatchOutMaterialOptionDisabled(m: Material) {
if (m.status !== '1') return true
if ((m.stockQty ?? 0) <= 0) return true
return batchStockOutLines.value.some((l) => l.materialId === m.id)
}
function isBatchInMaterialOptionDisabled(m: Material) {
if (m.status !== '1') return true
return batchStockInLines.value.some((l) => l.materialId === m.id)
}
async function searchBatchOutMaterials(query: string) {
batchOutMaterialPickLoading.value = true
try {
const res = await fetchMaterialList({
page: 1,
pageSize: 50,
keyword: query?.trim() || undefined,
status: '1'
})
batchOutMaterialOptions.value = res.list || []
} catch {
batchOutMaterialOptions.value = []
} finally {
batchOutMaterialPickLoading.value = false
}
}
async function searchBatchInMaterials(query: string) {
batchInMaterialPickLoading.value = true
try {
const res = await fetchMaterialList({
page: 1,
pageSize: 50,
keyword: query?.trim() || undefined,
status: '1'
})
batchInMaterialOptions.value = res.list || []
} catch {
batchInMaterialOptions.value = []
} finally {
batchInMaterialPickLoading.value = false
}
}
function appendBatchStockOutLine(m: Material) {
if (batchStockOutLines.value.some((l) => l.materialId === m.id)) {
ElMessage.warning('该物料已在明细中')
return false
}
if (m.status !== '1') {
ElMessage.warning('该物料已停用,无法出库')
return false
}
if ((m.stockQty ?? 0) <= 0) {
ElMessage.warning('该物料库存为 0,无法出库')
return false
}
batchStockOutLines.value.push({
materialId: m.id,
materialCode: m.materialCode || '',
materialName: m.materialName || '',
unit: m.unit || '',
stockQty: m.stockQty ?? 0,
qty: 1,
remark: ''
})
return true
}
function onBatchOutMaterialPick(materialId: string | null | undefined) {
if (!materialId) return
const m = batchOutMaterialOptions.value.find((x) => x.id === materialId)
batchOutMaterialPickId.value = ''
if (!m) return
appendBatchStockOutLine(m)
}
function appendBatchStockInLine(m: Material) {
if (batchStockInLines.value.some((l) => l.materialId === m.id)) {
ElMessage.warning('该物料已在明细中')
return false
}
if (m.status !== '1') {
ElMessage.warning('该物料已停用,无法入库')
return false
}
batchStockInLines.value.push({
materialId: m.id,
materialCode: m.materialCode || '',
materialName: m.materialName || '',
unit: m.unit || '',
stockQty: m.stockQty ?? 0,
qty: 1,
remark: ''
})
return true
}
function onBatchInMaterialPick(materialId: string | null | undefined) {
if (!materialId) return
const m = batchInMaterialOptions.value.find((x) => x.id === materialId)
batchInMaterialPickId.value = ''
if (!m) return
appendBatchStockInLine(m)
}
function handleBatchStockIn() {
batchStockInLines.value = []
batchInMaterialPickId.value = ''
batchInMaterialOptions.value = []
batchStockInForm.stockInTime = formatNowDatetime()
batchStockInForm.remark = ''
batchStockInVisible.value = true
void searchBatchInMaterials('')
batchStockInFormRef.value?.clearValidate?.()
}
async function handleBatchStockInSubmit() {
await batchStockInFormRef.value?.validate?.()
if (!batchStockInLines.value.length) {
ElMessage.warning('请至少添加一条入库物料')
return
}
for (const line of batchStockInLines.value) {
if (!line.qty || line.qty <= 0) {
ElMessage.warning(`「${line.materialName}」入库数量必须大于 0`)
return
}
}
await ElMessageBox.confirm(
`确定批量入库 ${batchStockInLines.value.length} 项物料吗?`,
'批量入库确认',
{ type: 'warning' }
)
batchStockInLoading.value = true
try {
const res = await fetchBatchStockInMaterial({
items: batchStockInLines.value.map((l) => ({
materialId: l.materialId,
qty: l.qty,
remark: l.remark?.trim() || undefined
})),
stockInTime: batchStockInForm.stockInTime || undefined,
remark: batchStockInForm.remark?.trim() || undefined
})
ElMessage.success(`批量入库成功,共 ${res.count ?? batchStockInLines.value.length} 项`)
batchStockInVisible.value = false
await loadData()
} catch {
/* 校验或接口错误已由全局处理 */
} finally {
batchStockInLoading.value = false
}
}
function handleBatchStockOut() {
batchStockOutLines.value = []
batchOutMaterialPickId.value = ''
batchOutMaterialOptions.value = []
batchStockOutForm.stockOutTime = formatNowDatetime()
batchStockOutForm.receiver = ''
batchStockOutForm.purpose = ''
batchStockOutForm.remark = ''
batchStockOutVisible.value = true
void searchReceiverUsers('')
void searchBatchOutMaterials('')
batchStockOutFormRef.value?.clearValidate?.()
}
async function handleBatchStockOutSubmit() {
await batchStockOutFormRef.value?.validate?.()
if (!batchStockOutLines.value.length) {
ElMessage.warning('请至少添加一条出库物料')
return
}
for (const line of batchStockOutLines.value) {
if (!line.qty || line.qty <= 0) {
ElMessage.warning(`「${line.materialName}」出库数量必须大于 0`)
return
}
if (line.qty > line.stockQty) {
ElMessage.warning(`「${line.materialName}」出库数量不能超过当前库存 ${line.stockQty}`)
return
}
}
await ElMessageBox.confirm(
`确定为领用人「${batchStockOutForm.receiver}」批量出库 ${batchStockOutLines.value.length} 项物料吗?`,
'批量出库确认',
{ type: 'warning' }
)
batchStockOutLoading.value = true
try {
const res = await fetchBatchStockOutMaterial({
items: batchStockOutLines.value.map((l) => ({
materialId: l.materialId,
qty: l.qty,
remark: l.remark?.trim() || undefined
})),
stockOutTime: batchStockOutForm.stockOutTime || undefined,
receiver: batchStockOutForm.receiver?.trim() || undefined,
purpose: batchStockOutForm.purpose?.trim() || undefined,
remark: batchStockOutForm.remark?.trim() || undefined
})
ElMessage.success(`批量出库成功,共 ${res.count ?? batchStockOutLines.value.length} 项`)
batchStockOutVisible.value = false
await loadData()
} catch {
/* 校验或接口错误已由全局处理 */
} finally {
batchStockOutLoading.value = false
}
}
onMounted(() => { onMounted(() => {
loadDictOptions() loadDictOptions()
loadData() loadData()
@@ -666,4 +1398,49 @@
margin-bottom: 0; margin-bottom: 0;
} }
} }
.material-batch-stock-dialog {
.batch-stock-move-head {
margin-bottom: 16px;
}
.batch-stock-move-lines-head {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 16px;
margin-bottom: 10px;
}
.batch-stock-move-lines-head-left {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}
.batch-stock-move-material-select {
flex-shrink: 0;
width: 320px;
}
.batch-stock-move-lines-title {
font-size: 14px;
font-weight: 600;
color: var(--mint-text, #0f172a);
}
.batch-stock-move-lines-hint {
font-size: 12px;
color: var(--mint-text-muted, #64748b);
}
.inner-table {
width: 100%;
}
.inner-cell-input {
width: 100%;
}
}
</style> </style>