This commit is contained in:
zlwu committed 2026-05-25 17:43:49 +08:00
1 parent 771f010a39
commit ee4abd361e
102 files changed
+8021 -4094

No files matched your search

+1
View File
@@ -29,6 +29,7 @@ Full specs: `openspec/changes/zkxw-engineering-standards/specs/*/spec.md`. Below
- **Tab bar (WorkTab) icons**: Tab bar tabs SHALL NOT show icons — only text titles. `meta.icon` is for sidebar only.
- **Form field annotations**: Field hints (e.g. "数值越小越靠前") SHALL appear as small text after the label via `<template #label>字段名<span class="form-label-tip">注释</span></template>`, NOT beside the input control. Style class: `.form-label-tip` (12px, `--mint-text-muted`).
- **Attachment upload card layout**: Upload trigger SHALL be a card (140×96px, dashed border `#a7f3d0`) inline as the first item in the same flex row as uploaded attachment cards; select file → immediate upload via `fetchUploadAttachment`; preview/download/delete on cards; hint below the row. Authority: `ProtocolFormDialog.vue` «协议附件». See `openspec/changes/zkxw-engineering-standards/specs/ui-conventions/spec.md` §「附件上传卡片化布局」for full Vue template + SCSS + interaction rules.
- **Button icons**: All `web-admin` `el-button` with visible text labels SHALL include a leading `<el-icon>` from `@element-plus/icons-vue` (explicit import). See `openspec/.../ui-conventions/spec.md` §「按钮须携带图标」.
- **Sort fields (sort_order/orderNum)**: web-admin 列表、新增弹窗、编辑弹窗中默认不展示排序字段。后续根据功能需要自行添加。
- **Status/conclusion/type fields as Tags**: All status, conclusion, and type fields in table columns and view dialogs SHALL render as `<el-tag>` with semantic colors. Tables: use `<el-tag :type="..." size="small">` in column templates. SystemViewDialog: use `tagType` property on `ViewField`. Semantic colors: `success`=正常/启用/已完成/通过, `warning`=进行中/待确认/已过期, `danger`=异常/已作废/拒绝/不通过, `info`=待执行/待生效/停用/默认, `primary`=特殊分类/来源类型. SHALL NOT use plain text or custom `<span class="tag">`. See `openspec/.../ui-conventions/spec.md` "状态、结论与类型字段使用 Tag 标签展示".
- **Template pages** — new pages SHALL match these exactly:
+1 -1
View File
@@ -1 +1 @@
89592
21868
+42 -13
View File
@@ -1619,6 +1619,7 @@ class TxnRechargeBody(BaseModel):
amount: float = Field(..., gt=0, alias="amount")
remark: Optional[str] = Field(None, alias="remark")
finance_submit_attachments: Optional[str] = Field(None, alias="financeSubmitAttachments")
class TxnRefundBody(BaseModel):
@@ -1654,6 +1655,14 @@ class TxnUnsubscribeBody(BaseModel):
remark: Optional[str] = Field(None, alias="remark")
class TxnUpdateBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
amount: Optional[float] = Field(None, gt=0, alias="amount")
remark: Optional[str] = Field(None, alias="remark")
finance_submit_attachments: Optional[str] = Field(None, alias="financeSubmitAttachments")
class TxnFinanceSubmitBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
@@ -1933,6 +1942,7 @@ async def list_service_order_txns(
keyword: Optional[str] = None,
createTimeStart: Optional[str] = Query(None, alias="createTimeStart"),
createTimeEnd: Optional[str] = Query(None, alias="createTimeEnd"),
financeDoneOnly: Optional[bool] = Query(False, alias="financeDoneOnly"),
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
@@ -1945,6 +1955,7 @@ async def list_service_order_txns(
keyword=keyword,
create_time_start=createTimeStart,
create_time_end=createTimeEnd,
finance_done_only=bool(financeDoneOnly),
page=page,
page_size=pageSize,
tenant_no=tenant_no,
@@ -1966,17 +1977,7 @@ async def get_service_order_txn_detail(
txn = ps_svc.get_service_order_txn(db, txn_id, tenant_no=tenant_no)
if not txn:
return error_response(404, "流水不存在")
txn_dict = ps_svc._row_to_dict_service_order_txn(txn, db, tenant_no)
order = ps_svc.get_service_order(db, txn.service_order_id, tenant_no=tenant_no)
if order:
txn_dict["channelName"] = order.channel_name or ""
txn_dict["orderType"] = order.order_type or ""
user_ids = [x for x in (txn.create_by, txn.finance_submit_by) if x]
name_map = ps_svc._user_nick_name_map(db, user_ids)
txn_dict["createByName"] = name_map.get(txn.create_by or "", "") or (txn.create_by or "")
txn_dict["financeSubmitByName"] = name_map.get(txn.finance_submit_by or "", "") or (
txn.finance_submit_by or ""
)
txn_dict = ps_svc._service_order_txn_to_response_dict(db, txn, tenant_no)
return success_response(txn_dict)
except ValueError as e:
return error_response(400, str(e))
@@ -1996,6 +1997,7 @@ async def create_recharge_txn(
order_id,
amount=body.amount,
remark=body.remark,
finance_submit_attachments=body.finance_submit_attachments,
tenant_no=tenant_no,
user_id=user.get("user_id"),
)
@@ -2080,6 +2082,31 @@ async def create_unsubscribe_txn(
return error_response(400, str(e))
@router.put("/channel-service-order-txns/{txn_id}")
async def update_service_order_txn(
txn_id: str,
body: TxnUpdateBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
txn = ps_svc.update_service_order_txn(
db,
txn_id,
amount=body.amount,
remark=body.remark,
finance_submit_attachments=body.finance_submit_attachments,
tenant_no=tenant_no,
user_id=user.get("user_id"),
)
return success_response(
ps_svc._row_to_dict_service_order_txn(txn, db, tenant_no), message="更新成功"
)
except ValueError as e:
return error_response(400, str(e))
@router.post("/channel-service-order-txns/{txn_id}/submit-finance")
async def submit_txn_finance(
txn_id: str,
@@ -2122,7 +2149,8 @@ async def confirm_txn(
user_id=user.get("user_id"),
)
return success_response(
ps_svc._row_to_dict_service_order_txn(txn, db, tenant_no), message="财务确认成功"
ps_svc._service_order_txn_to_response_dict(db, txn, tenant_no),
message="财务确认成功",
)
except ValueError as e:
return error_response(400, str(e))
@@ -2143,7 +2171,8 @@ async def void_txn(
user_id=user.get("user_id"),
)
return success_response(
ps_svc._row_to_dict_service_order_txn(txn, db, tenant_no), message="作废成功"
ps_svc._service_order_txn_to_response_dict(db, txn, tenant_no),
message="作废成功",
)
except ValueError as e:
return error_response(400, str(e))
+226 -25
View File
@@ -2598,9 +2598,12 @@ def _row_to_dict_service_order_txn(row, db=None, tenant_no=None) -> Dict[str, An
"financeSubmitAttachments": row.finance_submit_attachments or "",
"financeSubmitAttachmentFiles": urls_to_attachment_list(row.finance_submit_attachments, db, tn) if db and row.finance_submit_attachments else [],
"financeConfirmTime": row.finance_confirm_time.strftime("%Y-%m-%d %H:%M:%S") if row.finance_confirm_time else "",
"financeConfirmBy": row.finance_confirm_by or "",
"financeConfirmAttachments": row.finance_confirm_attachments or "",
"financeConfirmAttachmentFiles": urls_to_attachment_list(row.finance_confirm_attachments, db, tn) if db and row.finance_confirm_attachments else [],
"financeRemark": row.finance_remark or "",
"voidBy": row.void_by or "",
"voidTime": row.void_time.strftime("%Y-%m-%d %H:%M:%S") if row.void_time else "",
"balanceBefore": float(row.balance_before) if row.balance_before else 0,
"balanceAfter": float(row.balance_after) if row.balance_after else 0,
"tenantNo": row.tenant_no or "",
@@ -2618,6 +2621,71 @@ def _row_to_dict_service_order_txn(row, db=None, tenant_no=None) -> Dict[str, An
return d
def _service_order_txn_to_response_dict(
db,
txn,
tenant_no=None,
*,
order=None,
name_map=None,
) -> Dict[str, Any]:
"""流水响应字典:含订单渠道信息与提交人/创建人昵称。"""
d = _row_to_dict_service_order_txn(txn, db, tenant_no)
if order is None and txn.service_order_id:
order = get_service_order(db, txn.service_order_id, tenant_no)
if order:
d["channelName"] = order.channel_name or ""
d["deptName"] = order.dept_name or ""
d["orderType"] = order.order_type or ""
confirm_uid = txn.finance_confirm_by or (
txn.update_by
if (txn.txn_status or "") == "yqr" and txn.finance_confirm_time and not txn.finance_confirm_by
else None
)
void_uid = txn.void_by or (
txn.update_by
if (txn.txn_status or "") == "yzf"
and txn.finance_submit_time
and not txn.void_by
else None
)
if name_map is None:
user_ids = [x for x in (txn.create_by, txn.finance_submit_by, confirm_uid, void_uid) if x]
name_map = _user_nick_name_map(db, user_ids) if db and user_ids else {}
d["createByName"] = name_map.get(txn.create_by or "", "") or (txn.create_by or "")
d["financeSubmitByName"] = name_map.get(txn.finance_submit_by or "", "") or (
txn.finance_submit_by or ""
)
d["financeConfirmByName"] = name_map.get(confirm_uid or "", "") or (confirm_uid or "")
if not d.get("voidTime") and (txn.txn_status or "") == "yzf" and txn.update_time:
d["voidTime"] = txn.update_time.strftime("%Y-%m-%d %H:%M:%S")
d["voidByName"] = name_map.get(void_uid or "", "") or (void_uid or "")
if not (d.get("financeSubmitRemark") or "").strip() and (d.get("remark") or "").strip():
d["financeSubmitRemark"] = (d.get("remark") or "").strip()
_enrich_finance_operate_fields(d, txn)
return d
def _enrich_finance_operate_fields(d: Dict[str, Any], txn) -> None:
"""财务页「已处理」展示:操作类型、操作人、操作时间。"""
status = txn.txn_status or ""
if status == "yqr" and txn.finance_confirm_time:
d["financeOperateType"] = "confirm"
d["financeOperateTypeLabel"] = "财务确认"
d["financeOperateByName"] = d.get("financeConfirmByName") or d.get("financeConfirmBy") or ""
d["financeOperateTime"] = d.get("financeConfirmTime") or ""
elif status == "yzf" and txn.finance_submit_time:
d["financeOperateType"] = "void"
d["financeOperateTypeLabel"] = "财务作废"
d["financeOperateByName"] = d.get("voidByName") or d.get("voidBy") or ""
d["financeOperateTime"] = d.get("voidTime") or ""
else:
d["financeOperateType"] = ""
d["financeOperateTypeLabel"] = ""
d["financeOperateByName"] = ""
d["financeOperateTime"] = ""
def list_channel_service_orders(
db,
*,
@@ -2879,11 +2947,10 @@ def create_channel_service_order(
order_status = "dsx"
if order_type == "yfk":
# 预存款订单:创建后为待生效,市场发起财务确认后进入待确认
if not prepay_amount or float(prepay_amount) <= 0:
raise ValueError("预存金额必须大于0")
# 预存款订单:创建后为待生效,充值金额通过「发起充值」流水录入
_get_valid_channel_agreement(db, channel_agreement_id, channel_id, tenant_no)
order_status = "dsx"
prepay_amount = None
elif order_type == "gmcp":
# 购买产品订单:创建后为待生效,走财务确认后生效
@@ -2903,7 +2970,7 @@ def create_channel_service_order(
channel_name=channel_name or channel.channel_name or "",
dept_name=dept_name or "",
order_type=order_type,
prepay_amount=prepay_amount if order_type == "yfk" else None,
prepay_amount=None,
purchase_total_amount=purchase_total_amount,
order_status=order_status,
channel_agreement_id=channel_agreement_id,
@@ -2932,7 +2999,7 @@ def create_channel_service_order(
def update_channel_service_order(db, order_id, *, tenant_no=None, user_id=None, products=None, **kwargs):
"""待生效状态下可更新;预存款可改协议与充值金额,购买订单可改协议与产品明细"""
"""待生效状态下可更新;预存款可改协议,购买订单可改协议与产品明细"""
order = get_service_order(db, order_id, tenant_no)
if not order:
raise ValueError("订单不存在")
@@ -2943,11 +3010,6 @@ def update_channel_service_order(db, order_id, *, tenant_no=None, user_id=None,
if "remark" in kwargs and kwargs["remark"] is not None:
order.remark = kwargs["remark"]
if order.order_type == "yfk":
if "prepay_amount" in kwargs and kwargs["prepay_amount"] is not None:
amt = float(kwargs["prepay_amount"])
if amt <= 0:
raise ValueError("预存金额必须大于0")
order.prepay_amount = amt
if "channel_agreement_id" in kwargs and kwargs["channel_agreement_id"] is not None:
_get_valid_channel_agreement(
db, kwargs["channel_agreement_id"], order.channel_id, tenant_no
@@ -3185,21 +3247,33 @@ def list_service_order_txns(
keyword=None,
create_time_start=None,
create_time_end=None,
finance_done_only=False,
page=1,
page_size=20,
tenant_no=None,
):
"""查询操作流水列表"""
"""查询操作流水列表。finance_done_only:财务已处理(已确认或财务侧作废)。"""
q = db.query(BizChannelServiceOrderTxn).filter(BizChannelServiceOrderTxn.del_flag == 0)
if tenant_no:
q = q.filter(BizChannelServiceOrderTxn.tenant_no == tenant_no)
if service_order_id:
q = q.filter(BizChannelServiceOrderTxn.service_order_id == service_order_id)
ss = (txn_status or "").strip()
if ss:
statuses = [s.strip() for s in ss.split(",") if s.strip()]
if statuses:
q = q.filter(BizChannelServiceOrderTxn.txn_status.in_(statuses))
if finance_done_only:
q = q.filter(
or_(
BizChannelServiceOrderTxn.txn_status == "yqr",
and_(
BizChannelServiceOrderTxn.txn_status == "yzf",
BizChannelServiceOrderTxn.finance_submit_time.isnot(None),
),
)
)
else:
ss = (txn_status or "").strip()
if ss:
statuses = [s.strip() for s in ss.split(",") if s.strip()]
if statuses:
q = q.filter(BizChannelServiceOrderTxn.txn_status.in_(statuses))
tt = (txn_type or "").strip()
if tt:
types = [t.strip() for t in tt.split(",") if t.strip()]
@@ -3234,8 +3308,66 @@ def list_service_order_txns(
total = q.order_by(None).with_entities(func.count(BizChannelServiceOrderTxn.id)).scalar() or 0
page = max(1, page)
page_size = min(max(1, page_size), 100)
rows = q.order_by(BizChannelServiceOrderTxn.create_time.desc()).offset((page - 1) * page_size).limit(page_size).all()
return [_row_to_dict_service_order_txn(r, db, tenant_no) for r in rows], int(total)
if finance_done_only:
operate_time = func.coalesce(
BizChannelServiceOrderTxn.finance_confirm_time,
BizChannelServiceOrderTxn.void_time,
)
rows = (
q.order_by(operate_time.desc(), BizChannelServiceOrderTxn.create_time.desc())
.offset((page - 1) * page_size)
.limit(page_size)
.all()
)
else:
rows = (
q.order_by(BizChannelServiceOrderTxn.create_time.desc())
.offset((page - 1) * page_size)
.limit(page_size)
.all()
)
if not rows:
return [], int(total)
order_ids = list({r.service_order_id for r in rows if r.service_order_id})
orders: Dict[str, Any] = {}
if order_ids:
oq = db.query(BizChannelServiceOrder).filter(
BizChannelServiceOrder.id.in_(order_ids),
BizChannelServiceOrder.del_flag == 0,
)
if tenant_no:
oq = oq.filter(BizChannelServiceOrder.tenant_no == tenant_no)
for o in oq.all():
orders[o.id] = o
user_ids: List[str] = []
for r in rows:
if r.create_by:
user_ids.append(r.create_by)
if r.finance_submit_by:
user_ids.append(r.finance_submit_by)
if r.finance_confirm_by:
user_ids.append(r.finance_confirm_by)
elif (r.txn_status or "") == "yqr" and r.update_by:
user_ids.append(r.update_by)
if r.void_by:
user_ids.append(r.void_by)
elif (r.txn_status or "") == "yzf" and r.finance_submit_time and r.update_by:
user_ids.append(r.update_by)
name_map = _user_nick_name_map(db, user_ids) if db and user_ids else {}
items = [
_service_order_txn_to_response_dict(
db,
r,
tenant_no,
order=orders.get(r.service_order_id),
name_map=name_map,
)
for r in rows
]
return items, int(total)
def get_service_order_txn(db, txn_id, *, tenant_no=None):
@@ -3248,8 +3380,17 @@ def get_service_order_txn(db, txn_id, *, tenant_no=None):
return q.first()
def create_recharge_txn(db, order_id, *, amount, remark=None, tenant_no=None, user_id=None):
"""创建充值流水(yfk订单),状态 dsx"""
def create_recharge_txn(
db,
order_id,
*,
amount,
remark=None,
finance_submit_attachments=None,
tenant_no=None,
user_id=None,
):
"""创建充值流水(yfk订单),状态 dsx;附件预存于 finance_submit_attachments 供后续财务确认"""
order = get_service_order(db, order_id, tenant_no)
if not order:
raise ValueError("订单不存在")
@@ -3270,6 +3411,7 @@ def create_recharge_txn(db, order_id, *, amount, remark=None, tenant_no=None, us
amount=amount,
txn_status="dsx",
remark=remark or "",
finance_submit_attachments=(finance_submit_attachments or "").strip() or None,
tenant_no=tenant_no or order.tenant_no,
order_num=0,
create_by=user_id,
@@ -3497,6 +3639,56 @@ def create_unsubscribe_txn(db, order_id, *, products, remark=None, tenant_no=Non
return txn
def update_service_order_txn(
db,
txn_id,
*,
amount=None,
remark=None,
finance_submit_attachments=None,
tenant_no=None,
user_id=None,
):
"""更新待生效流水:仅 dsx;充值/退款可改金额,购买/退订仅可改备注与凭证"""
txn = get_service_order_txn(db, txn_id, tenant_no=tenant_no)
if not txn:
raise ValueError("流水不存在")
if txn.txn_status != "dsx":
raise ValueError("仅待生效流水可编辑")
now = datetime.now()
txn_type = (txn.txn_type or "").strip()
if amount is not None:
amt = float(amount)
if amt <= 0:
raise ValueError("金额必须大于0")
if txn_type in ("recharge", "refund"):
if txn_type == "refund":
order = get_service_order(db, txn.service_order_id, tenant_no)
if not order:
raise ValueError("关联订单不存在")
current_balance = float(order.current_balance) if order.current_balance else 0
if amt > current_balance:
raise ValueError(f"退款金额不能大于当前余额 {current_balance}")
txn.amount = amt
else:
raise ValueError("购买/退订流水不可修改金额,请作废后重新发起")
if remark is not None:
txn.remark = remark or ""
if finance_submit_attachments is not None:
txn.finance_submit_attachments = (finance_submit_attachments or "").strip() or None
txn.update_by = user_id
txn.update_time = now
db.add(txn)
db.commit()
db.refresh(txn)
return txn
def submit_txn_finance(db, txn_id, *, finance_submit_remark=None, finance_submit_attachments=None, tenant_no=None, user_id=None):
"""发起流水财务确认:dsx → dqr"""
txn = get_service_order_txn(db, txn_id, tenant_no=tenant_no)
@@ -3509,8 +3701,14 @@ def submit_txn_finance(db, txn_id, *, finance_submit_remark=None, finance_submit
txn.txn_status = "dqr"
txn.finance_submit_by = user_id
txn.finance_submit_time = now
txn.finance_submit_remark = finance_submit_remark or ""
txn.finance_submit_attachments = finance_submit_attachments or ""
submit_remark = (finance_submit_remark or "").strip()
if not submit_remark:
submit_remark = (txn.remark or "").strip()
txn.finance_submit_remark = submit_remark
if finance_submit_attachments:
txn.finance_submit_attachments = finance_submit_attachments
elif not (txn.finance_submit_attachments or "").strip():
txn.finance_submit_attachments = ""
txn.update_by = user_id
txn.update_time = now
db.add(txn)
@@ -3615,6 +3813,7 @@ def confirm_txn(db, txn_id, *, finance_remark=None, finance_confirm_attachments=
# Update txn status
txn.txn_status = "yqr"
txn.finance_confirm_time = now
txn.finance_confirm_by = user_id
txn.finance_confirm_attachments = finance_confirm_attachments or ""
txn.finance_remark = finance_remark or ""
txn.update_by = user_id
@@ -3634,12 +3833,12 @@ def confirm_txn(db, txn_id, *, finance_remark=None, finance_confirm_attachments=
def void_txn(db, txn_id, *, tenant_no=None, user_id=None):
"""作废流水:dsx → yzf。如果是 purchase/unsubscribe 还需要回滚产品持仓"""
"""作废流水:dsx/dqr → yzf。如果是 purchase/unsubscribe 还需要回滚产品持仓"""
txn = get_service_order_txn(db, txn_id, tenant_no=tenant_no)
if not txn:
raise ValueError("流水不存在")
if txn.txn_status != "dsx":
raise ValueError("仅待生效流水可作废")
if txn.txn_status not in ("dsx", "dqr"):
raise ValueError("仅待生效或待财务确认流水可作废")
now = datetime.now()
order = get_service_order(db, txn.service_order_id, tenant_no)
@@ -3692,6 +3891,8 @@ def void_txn(db, txn_id, *, tenant_no=None, user_id=None):
db.add(existing)
txn.txn_status = "yzf"
txn.void_by = user_id
txn.void_time = now
txn.update_by = user_id
txn.update_time = now
db.add(txn)
+41 -3
View File
@@ -1,9 +1,12 @@
"""FastAPI 应用入口(骨架工程)"""
from contextlib import asynccontextmanager
import logging
from datetime import datetime
from fastapi import FastAPI
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from sqlalchemy.exc import SQLAlchemyError
from app.core.config import settings
from app.core.database import SessionLocal
@@ -58,6 +61,43 @@ app.add_middleware(CORSMiddleware, **_cors_kw)
app.add_middleware(ApiRequestLogMiddleware)
app.add_middleware(ApiCryptoMiddleware)
logger = logging.getLogger("sqxp")
def _error_json(status_code: int, code: int, message: str) -> JSONResponse:
return JSONResponse(
status_code=status_code,
content={
"code": code,
"message": message,
"data": None,
"timestamp": int(datetime.now().timestamp() * 1000),
},
)
@app.exception_handler(SQLAlchemyError)
async def sqlalchemy_exception_handler(request: Request, exc: SQLAlchemyError):
"""数据库异常:返回 JSON 并保留 CORS 头,避免浏览器只报跨域错误"""
logger.exception("Database error on %s %s", request.method, request.url.path)
if settings.DEBUG:
message = f"数据库不可用:{exc.orig if getattr(exc, 'orig', None) else exc}"
else:
message = "数据库不可用,请确认 MySQL 已启动且连接配置正确"
return _error_json(503, 503, message)
@app.exception_handler(Exception)
async def unhandled_exception_handler(request: Request, exc: Exception):
"""未捕获异常:统一 JSON 500,确保跨域场景下仍有 Access-Control-Allow-Origin"""
logger.exception("Unhandled error on %s %s", request.method, request.url.path)
if settings.DEBUG:
message = str(exc) or "服务器内部错误"
else:
message = "服务器内部错误,请稍后重试"
return _error_json(500, 500, message)
app.include_router(public_router, prefix=settings.API_V1_PREFIX)
app.include_router(menu_router, prefix=settings.API_V1_PREFIX)
app.include_router(admin_router, prefix=settings.API_V1_PREFIX)
@@ -83,8 +123,6 @@ app.include_router(pilot_delivery_router, prefix=settings.API_V1_PREFIX)
app.include_router(pilot_infusion_confirm_router, prefix=settings.API_V1_PREFIX)
app.include_router(outbound_release_review_router, prefix=settings.API_V1_PREFIX)
logger = logging.getLogger("sqxp")
def _mask_secret(value: str) -> str:
if not value:
+3
View File
@@ -1850,8 +1850,11 @@ class BizChannelServiceOrderTxn(Base):
finance_submit_remark = Column(String(512), nullable=True, comment="发起确认备注")
finance_submit_attachments = Column(Text, nullable=True, comment="发起确认附件")
finance_confirm_time = Column(DateTime, nullable=True, comment="财务确认时间")
finance_confirm_by = Column(String(64), nullable=True, comment="财务确认人ID")
finance_confirm_attachments = Column(Text, nullable=True, comment="财务确认附件")
finance_remark = Column(String(512), nullable=True, comment="财务确认备注")
void_by = Column(String(64), nullable=True, comment="作废人ID")
void_time = Column(DateTime, nullable=True, comment="作废时间")
balance_before = Column(Numeric(18, 2), nullable=True, comment="操作前余额")
balance_after = Column(Numeric(18, 2), nullable=True, comment="操作后余额")
tenant_no = Column(String(64), nullable=False, default="zkxw", comment="租户编号")
@@ -0,0 +1,15 @@
-- 渠道服务订单操作流水:财务确认人、作废人、作废时间
ALTER TABLE `biz_channel_service_order_txn`
ADD COLUMN `finance_confirm_by` varchar(64) DEFAULT NULL COMMENT '财务确认人ID' AFTER `finance_confirm_time`,
ADD COLUMN `void_by` varchar(64) DEFAULT NULL COMMENT '作废人ID' AFTER `finance_remark`,
ADD COLUMN `void_time` datetime DEFAULT NULL COMMENT '作废时间' AFTER `void_by`;
-- 历史已确认流水:用 update_by 回填确认人
UPDATE `biz_channel_service_order_txn`
SET `finance_confirm_by` = `update_by`
WHERE `txn_status` = 'yqr' AND `finance_confirm_time` IS NOT NULL AND `finance_confirm_by` IS NULL;
-- 历史已作废流水:用 update_by / update_time 回填(仅曾提交财务的流水视为财务作废)
UPDATE `biz_channel_service_order_txn`
SET `void_by` = `update_by`, `void_time` = `update_time`
WHERE `txn_status` = 'yzf' AND `finance_submit_time` IS NOT NULL AND `void_by` IS NULL;
+3
View File
@@ -1035,8 +1035,11 @@ CREATE TABLE `biz_channel_service_order_txn` (
`finance_submit_remark` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发起确认备注',
`finance_submit_attachments` text COLLATE utf8mb4_unicode_ci COMMENT '发起确认附件',
`finance_confirm_time` datetime DEFAULT NULL COMMENT '财务确认时间',
`finance_confirm_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '财务确认人ID',
`finance_confirm_attachments` text COLLATE utf8mb4_unicode_ci COMMENT '财务确认附件',
`finance_remark` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '财务确认备注',
`void_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '作废人ID',
`void_time` datetime DEFAULT NULL COMMENT '作废时间',
`balance_before` decimal(18,2) DEFAULT NULL COMMENT '操作前余额(yfk类型)',
`balance_after` decimal(18,2) DEFAULT NULL COMMENT '操作后余额(yfk类型)',
`tenant_no` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
@@ -0,0 +1,176 @@
# 金额/单价千分位输入与展示 — Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 在 web-admin 统一金额/单价的「聚焦纯数字、失焦千分位、提交数值」交互,并统一只读列表/详情的千分位展示。
**Architecture:** 抽取 `money-format.ts` 纯函数 + `AmountInput` 封装 `el-input`;业务页替换金额类 `el-input-number` 与局部重复逻辑;只读处使用 `formatMoneyDisplay`。
**Tech Stack:** Vue 3、Element Plus、TypeScript、现有 Prettier/ESLint 规范。
**Design spec:** `docs/superpowers/specs/2026-05-25-money-input-thousand-separator-design.md`
---
## File map
| 操作 | 路径 |
|------|------|
| Create | `web-admin/src/utils/money-format.ts` |
| Create | `web-admin/src/components/common/amount-input/index.vue` |
| Modify | `web-admin/src/views/pilot-service/channel-service-order/index.vue` |
| Modify | `web-admin/src/views/pilot-service/channel-service-order-finance/index.vue` |
| Modify | `openspec/changes/zkxw-engineering-standards/specs/ui-conventions/spec.md` |
| Later P1+ | `channel/index.vue`, `cell-product-price/index.vue`, `project-price-system/index.vue`, `ProtocolFormDialog.vue`, `payment-info/index.vue`, … |
---
### Task 1: 金额格式化工具
**Files:**
- Create: `web-admin/src/utils/money-format.ts`
- [ ] **Step 1: 实现三个导出函数**
```typescript
export function addThousandSeparators(intStr: string): string { /* 字符串分段,无前瞻正则 */ }
export function sanitizeMoneyInput(value: string, precision = 2): string { /* 去逗号、单小数点、截断小数 */ }
export function formatMoneyDisplay(value: string | number | null | undefined, precision = 2): string
export function parseMoneyToNumber(value: string, precision = 2): number | null
```
- [ ] **Step 2: 本地快速验证**
在 Node 或浏览器控制台执行:
```javascript
formatMoneyDisplay(1234567.89) // '1,234,567.89'
parseMoneyToNumber('1,234.56') // 1234.56
```
---
### Task 2: AmountInput 组件
**Files:**
- Create: `web-admin/src/components/common/amount-input/index.vue`
- [ ] **Step 1: 实现组件**
- `defineModel<number | null>()` 或 `modelValue` + `emit('update:modelValue')`
- 内部 `displayText`,`watch(modelValue)` 在非聚焦时同步为 `formatMoneyDisplay`
- `@focus` → sanitize 展示
- `@input` → `sanitizeMoneyInput` 写回 `displayText`
- `@blur` → `parseMoneyToNumber` → emit;`displayText = formatMoneyDisplay`
- Props: `min`, `max`, `precision`, `placeholder`, `disabled`, `clearable`
- [ ] **Step 2: 在渠道服务订单页面临时引用验证**
仅 import 一个弹窗字段 smoke test(Task 3 会全量替换)。
---
### Task 3: 渠道服务订单页(P0)
**Files:**
- Modify: `web-admin/src/views/pilot-service/channel-service-order/index.vue`
- [ ] **Step 1: 删除页面内重复函数**
移除 `addThousandSeparators`、`formatRechargeAmountDisplay`、`sanitizeRechargeAmountInput`、`parseRechargeAmountInput`、`parseAmountInputToNumber`(若仅用于充值)、`rechargeAmountInput` 及相关 handler。
- [ ] **Step 2: 替换可编辑金额**
| 位置 | 替换为 |
|------|--------|
| 发起充值 | `<AmountInput v-model="rechargeForm.amount" :min="0.01" />` |
| 申请退款 | `<AmountInput v-model="refundTxnForm.amount" :min="0.01" :max="currentBalance" />` |
| 新增/编辑 产品明细单价 | `<AmountInput v-model="row.unitPrice" :min="0" @change="calcItemAmount(row)" />` |
- [ ] **Step 3: 只读展示**
将列表/查看/合计中的 `formatAmount`(金额类)改为 `formatMoneyDisplay`,或:
```typescript
const formatAmount = (v: any) => formatMoneyDisplay(v, 2)
```
仅当该文件内 `formatAmount` 全部用于金额时方可整文件替换。
- [ ] **Step 4: 手工验收**
按 spec 第 6 节 5 条检查;提交充值/退款 payload 为 number。
---
### Task 4: 财务确认页只读列(P1 片段)
**Files:**
- Modify: `web-admin/src/views/pilot-service/channel-service-order-finance/index.vue`
- [ ] **Step 1: `formatAmount` → `formatMoneyDisplay`**
列表金额、详情单价/金额、确认弹窗中的金额文案。
---
### Task 5: UI 规范 OpenSpec
**Files:**
- Modify: `openspec/changes/zkxw-engineering-standards/specs/ui-conventions/spec.md`
- [ ] **Step 1: 新增 Requirement「金额与单价千分位」**
SHALL 行为表 + `AmountInput` + `formatMoneyDisplay` 路径说明。
---
### Task 6: P1 中试服务其余页(可并行子任务)
**Files:**
- Modify: `web-admin/src/views/pilot-service/channel/index.vue`(协议价行内)
- Modify: `web-admin/src/views/pilot-service/cell-product-price/index.vue`
- Modify: `web-admin/src/views/pilot-service/project-price-system/index.vue`
- Modify: `web-admin/src/views/pilot-service/checkup-institution/index.vue`、`CheckupPackagePanel.vue`
每文件重复 Task 3 的替换模式:金额类 `el-input-number` → `AmountInput`;只读 → `formatMoneyDisplay`。
---
### Task 7: P2 细胞存储(后续迭代)
**Files:**
- Modify: `web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue`
- Modify: `web-admin/src/views/cell-storage/payment-info/index.vue`
- 只读:`ProtocolViewDialog.vue`、payment/refund confirm 列表
---
### Task 8: 图谱更新(Agent 规则)
- [ ] **Step 1:** `./scripts/update-graph.sh frontend`(完成 P0 后)
---
## Self-review(plan ↔ spec)
| Spec 要求 | Task |
|-----------|------|
| 聚焦/失焦/提交行为 | Task 1–2 |
| 只读千分位 | Task 3–4, 6–7 |
| 禁止页面内复制正则 | Task 3 删除重复 |
| 数量字段排除 | 各 Task 仅改单价/金额 |
| OpenSpec | Task 5 |
| 分期 P0–P3 | Task 3–7 |
## 执行选项
Plan 已保存至 `docs/superpowers/plans/2026-05-25-money-input-thousand-separator.md`。
1. **Subagent-Driven** — 按 Task 派发子代理,逐 Task 评审
2. **Inline Execution** — 当前会话按 Task 1→3 连续实现(建议先 P0)
请告知:是否批准设计 spec,以及希望先执行 **P0(工具 + 组件 + 渠道服务订单)** 还是全量分期推进。
@@ -0,0 +1,189 @@
# Web 管理端金额/单价千分位输入与展示 — 设计说明
## 背景
业务人员在录入或核对大额「单价」「金额」时,需要千分位逗号辅助阅读,但输入过程中插入逗号会干扰光标与连续键入。渠道服务订单「发起充值」已在 `channel-service-order/index.vue` 用页面内局部函数实现「聚焦纯数字、失焦千分位」,尚未复用到其他页面。
本设计将交互固化为**统一工具 + 统一组件**,并明确**可编辑输入**与**只读展示**两类场景,避免再次在 `.vue` 中复制正则或误用前瞻表达式导致编译错误。
## 目标行为(SHALL)
| 时机 | 可编辑输入框 | 列表/查看等只读展示 |
|------|----------------|---------------------|
| 聚焦输入中 | 纯数字,如 `1234567.89`(无逗号) | — |
| 失焦后 | 千分位,如 `1,234,567.89` | 始终千分位(同上格式) |
| 再次聚焦 | 去掉逗号,恢复纯数字 | — |
| 提交/API | `number` 或约定精度的小数,**不受逗号影响** | — |
**不在范围:** 数量、份数、排序号、百分比系数等非金额字段(仍用 `el-input-number` 整数或原控件)。
## 范围
### 纳入(单价 / 金额类)
**中试服务(pilot-service)**
| 页面 | 路由 | 可编辑 | 只读展示 |
|------|------|--------|----------|
| 渠道服务购买订单 | `/#/pilot-service/channel-service-order` | 充值金额、退款金额、产品明细单价;发起充值已改 | 列表余额/购买总额、查看流水与持仓、合计 |
| 渠道服务订单财务确认 | `/#/pilot-service/channel-service-order-finance` | — | 列表/详情金额、单价 |
| 渠道信息管理 | `/#/pilot-service/channel` | 协议价(元)行内编辑 | 价格选择器单价列 |
| 细胞产品价格体系 | `/#/pilot-service/cell-product-price` | 表单单价 | 列表单价 |
| 细胞产品项目价格 | `/#/pilot-service/project-price-system` | 表格单价 | 查看单价 |
| 体检机构及项目 | `/#/pilot-service/checkup-institution` | 项目费用等 | 套餐合计费用 |
**细胞存储(cell-storage)**
| 页面 | 路由 | 可编辑 | 只读展示 |
|------|------|--------|----------|
| 采集协议单录入 | `/#/cell-storage/protocol` | 合同金额、应缴费、转账金额、采集金额等 | 查看弹窗同字段 |
| 缴费信息 | `/#/cell-storage/payment-info` | 退费金额 | 应缴/实缴列 |
| 缴费/退费确认(财务) | `/#/cell-storage/payment-confirm`、`refund-confirm` | — | 金额列 |
**其他(第二批)**
| 页面 | 说明 |
|------|------|
| 订单 Demo `system/order/index.vue` | 供货价/售价及金额(若仍为可编辑控件则纳入) |
| 研究捐赠 `DonationFormDialog` | 采集金额等 |
| 第三方检测公司等 | `feeAmount` 等 `:precision="2"` 的金额 |
### 明确排除
- 小程序端 `miniprogram/`
- 后端 API(仍接收 JSON number)
- 非金额 `el-input-number`(数量、排序、`priceCoefficient` 百分比等)
## 方案对比
### 方案 A:每页复制 focus/blur 函数(现状扩展)
- 优点:无新依赖,单页改动快
- 缺点:已出现正则笔误导致整页无法加载;难维护;`formatAmount` 与输入逻辑不一致
### 方案 B:工具函数 + `AmountInput` 组件(推荐)
- `@/utils/money-format.ts`:`sanitizeMoneyInput`、`formatMoneyDisplay`、`parseMoneyToNumber`
- `@/components/common/amount-input/index.vue`:`v-model` 绑定 `number | null`,封装 focus/blur/input
- 只读:`formatMoneyDisplay(n)` 或增强现有列表 `formatAmount` 的展示路径
- 优点:单测友好、符合 Fresh Mint 组件化、表格/弹窗同一套
- 缺点:需逐页替换 `el-input-number`(金额类)
### 方案 C:全局指令 `v-money-input`
- 优点:模板改动小
- 缺点:难支持 `min`/`max`/`precision`、表格行绑定不清晰、与 Element Plus 集成弱
**结论:采用方案 B。**
## 技术设计
### 1. 工具模块 `web-admin/src/utils/money-format.ts`
```typescript
// 展示:整数千分位 + 最多 precision 位小数(默认 2)
export function formatMoneyDisplay(value: string | number | null | undefined, precision?: number): string
// 输入清洗:去逗号、仅保留数字与一个点
export function sanitizeMoneyInput(value: string, precision?: number): string
// 提交:number | null;空串 / 仅 '.' → null
export function parseMoneyToNumber(value: string, precision?: number): number | null
```
实现要点:
- 千分位用**字符串分段拼接**(`addThousandSeparators`),**禁止**在 `.vue` 内联复杂前瞻正则。
- 小数位截断与 `el-input-number` 的 `:precision="2"` 行为对齐。
### 2. 组件 `AmountInput`
路径:`web-admin/src/components/common/amount-input/index.vue`
| Prop | 类型 | 默认 | 说明 |
|------|------|------|------|
| `modelValue` | `number \| null` | — | 双向绑定数值 |
| `min` | `number` | — | 可选下限 |
| `max` | `number` | — | 可选上限 |
| `precision` | `number` | `2` | 小数位数;单价/金额均为 2 |
| `placeholder` | `string` | — | |
| `disabled` | `boolean` | `false` | |
| `clearable` | `boolean` | `true` | |
事件:`update:modelValue`、`change`(失焦且数值变化时,便于触发行内 `calcAmount`)
内部状态:
- `displayText: ref<string>` — 绑定 `el-input`
- `@focus` → `displayText = sanitize(modelValue)`
- `@input` → 清洗 + 临时更新 `displayText`;可选同步 `modelValue` 为中间值
- `@blur` → `emit(update:modelValue, parseMoneyToNumber(...))`;`displayText = formatMoneyDisplay(...)`
校验:`min`/`max` 在 blur 或 submit 时由父级 `el-form` rules 负责;组件可在 blur 时 `ElMessage.warning` 可选(默认不弹,避免表格内刷屏)。
样式:宽度 `100%`;与现有 `el-input` 高度 36px 规范一致。
### 3. 只读展示
- 列表列、查看弹窗、合计文案:统一 `formatMoneyDisplay(v)`,前缀 `¥` 仍在模板侧拼接(与现网 `¥{{ formatAmount(...) }}` 一致)。
- **迁移策略:** 在 `money-format.ts` 导出 `formatMoneyDisplay`;各页逐步将只读 `formatAmount` 替换为 `formatMoneyDisplay`(或全局别名 `formatAmount = formatMoneyDisplay` 仅用于金额列——需逐文件审查,避免误改非金额 toFixed)。
建议新增 `formatMoneyAmount(v)` 专用于金额展示,保留原 `formatAmount` 为两位小数无逗号直至迁移完成,**P0 页面直接使用 `formatMoneyDisplay`**。
### 4. 与 OpenSpec / UI 规范
在 `openspec/changes/zkxw-engineering-standards/specs/ui-conventions/spec.md`(或归档后 `openspec/specs/ui-conventions/spec.md`)增补一节:
- 金额/单价**可编辑**字段 SHALL 使用 `AmountInput`(或经评审的等价封装),SHALL 满足聚焦/失焦/提交行为表。
- 金额/单价**只读**展示 SHALL 使用 `formatMoneyDisplay`,整数部分千分位、小数位默认 2 位。
- SHALL NOT 在业务 `.vue` 中复制千分位正则实现。
### 5. 渠道服务订单页迁移(含已改充值)
- 删除页面内 `addThousandSeparators`、`formatRechargeAmountDisplay` 等重复函数,改为 import 工具 + `AmountInput`。
- 「发起充值」「申请退款」弹窗金额 → `AmountInput`。
- 新增/编辑订单产品明细「单价」列 → `AmountInput`(`@change` 仍调 `calcItemAmount`)。
### 6. 测试与验收
**单元(建议)** `web-admin/src/utils/money-format.spec.ts` 或 vitest:
- `formatMoneyDisplay(1234567.89)` → `1,234,567.89`
- `sanitizeMoneyInput('1,234.5')` → `1234.5`
- `parseMoneyToNumber('1,234.56')` → `1234.56`
**手工验收(每批至少 1 页)**
1. 聚焦输入 `1000000.5`,框内无逗号
2. 失焦显示 `1,000,000.5`
3. 再聚焦变回 `1000000.5`
4. 保存后网络请求 payload 为数字 `1000000.5`
5. 列表只读列为千分位
## 分期交付
| 阶段 | 内容 | 产出 |
|------|------|------|
| P0 | 工具 + 组件 + 规范 + 渠道服务订单全页 | 可复用基座 |
| P1 | 渠道信息、细胞价格、项目价格、财务确认页只读列 | 中试服务闭环 |
| P2 | 细胞存储协议/缴费/退费 | 存储线金额 |
| P3 | Demo 订单、捐赠、第三方费用等 | 余量 |
## 风险与约束
- **表格行内多个 `AmountInput`**:须 `row-key` 稳定,避免 Vue 复用 DOM 导致显示串行。
- **`el-form` 校验**:rules 仍针对 `number` 字段,blur 后须已 `emit` 最新值。
- **min/max**:退款金额等保留 `max=currentBalance`,在 `AmountInput` 上透传并在 blur 校验。
- **不要**对 `quantity` 等整数字段使用本组件。
## 非目标(YAGNI)
- 货币符号内置于组件(仍由模板加 `¥`)
- 多币种、汇率
- 输入法全角数字自动转换(可后续加)
---
**状态:** 待评审
**关联实现:** `docs/superpowers/plans/2026-05-25-money-input-thousand-separator.md`
@@ -544,7 +544,7 @@ watchDebounced(
- **THEN** SHALL 拒绝 `picture-card`、`show-file-list` 默认列表、与规范不一致的尺寸/色值
### Requirement: 按钮须携带图标
`web-admin` 中所有带文字标签的 `el-button`(或 `ElButton`)SHALL 在文字前方包含 `<el-icon>` 子元素,使用 `@element-plus/icons-vue` 提供的图标组件;SHALL NOT 出现仅有文字而无图标的按钮。图标的引入方式为在文件 `<script setup>` 中显式 `import` 所需图标组件(`@element-plus/icons-vue` 不属于 auto-import 范围)。
`web-admin` 中所有带文字标签的 `el-button`(或 `ElButton`)SHALL 在文字**前方**包含 `<el-icon>` 子元素,使用 `@element-plus/icons-vue` 提供的图标组件;SHALL NOT 出现仅有文字而无图标的按钮。该规则适用于列表工具栏、表格操作列、`el-dialog` / 抽屉的 `#footer` 底栏、表单内 `link` / `plain` / `size="small"` 等**凡渲染可见文案的按钮**,不限于 `type="primary"`。图标的引入方式为在文件 `<script setup>` 中显式 `import` 所需图标组件(`@element-plus/icons-vue` 不属于 auto-import 范围)。图标与文字间距由全局样式保证(与 Fresh Mint 弹窗底栏约定一致,约 6px)。
#### 常用按钮图标映射
@@ -562,6 +562,12 @@ watchDebounced(
| 配置 / 设置 | `Setting` 或 `SetUp` | 操作列「配置」按钮 |
| 导入 / 上传 | `Upload` | 工具栏「导入」、表单「上传」按钮 |
| 折叠 / 展开 | `ArrowDown` / `ArrowUp` | 工具栏「展开/收起」按钮 |
| 充值 / 发起充值 | `Wallet` | 渠道服务订单等预付款充值操作 |
| 退款 / 申请退款 | `Sell` | 退款、退费类操作 |
| 购买产品 | `ShoppingCart` | 购买、下单类操作 |
| 退订 | `Remove` | 退订、减少持有类操作 |
| 作废 | `Delete` | 作废流水/订单(与删除同图标,可用 `op-warn` 样式区分) |
| 操作流水 / 记录列表 | `List` | 「操作流水」等子列表入口 |
#### Scenario: 新增列表页工具栏按钮
@@ -588,6 +594,12 @@ watchDebounced(
- **WHEN** PR 包含新增或修改的 `el-button`
- **THEN** 审查者 SHALL 确认该按钮包含 `<el-icon>` 子元素,且图标组件已从 `@element-plus/icons-vue` 显式导入
#### Scenario: 渠道服务订单与财务确认页
- **WHEN** 实现或修改 `web-admin/src/views/pilot-service/channel-service-order/**` 或 `channel-service-order-finance/**` 中的按钮(含弹窗底栏、表格操作列、行内 link 删除)
- **THEN** 每个带文案的 `el-button` SHALL 按上表携带图标(如查看 `View`、确认 `Check`、取消 `Close`、作废 `Delete`、发起充值 `Wallet` 等)
- **THEN** 弹窗底栏取消/确定 SHALL 使用 `btn-ghost` / `btn-main` 类名并与 Demo 页图标约定一致
#### 标准写法示例
```html
@@ -944,3 +956,37 @@ import { protocolStatusLabel, protocolStatusTagType } from '@/utils/status-tag-r
- **WHEN** 新增 P28 或更高级别模式,或全站页面映射变更
- **THEN** 维护者 SHALL 同步更新 `docs/web-admin-ui-pattern-index.md` 与本 Requirement 决策表
### Requirement: 金额与单价千分位输入与展示
金额、单价等可编辑输入字段 SHALL 使用 `AmountInput` 组件(路径 `@/components/common/amount-input/index.vue`),满足以下行为:
| 时机 | 行为 |
|------|------|
| 聚焦输入中 | 纯数字展示,无千分位逗号,如 `1234567.89` |
| 失焦后 | 千分位展示,如 `1,234,567.89` |
| 再次聚焦 | 自动去掉逗号,恢复纯数字便于修改 |
| 提交/API | `number` 类型,不受逗号影响 |
金额、单价等只读展示(列表列、查看弹窗、合计文案)SHALL 使用 `formatMoneyDisplay` 工具函数(路径 `@/utils/money-format.ts`),整数部分千分位、小数位默认 2 位。
业务 `.vue` 文件 SHALL NOT 复制千分位正则或 `addThousandSeparators` 等函数实现;SHALL 统一引用 `@/utils/money-format.ts`。
不在范围内:数量、份数、排序号、百分比系数等非金额字段(仍用 `el-input-number`)。
#### Scenario: 新增金额输入字段
- **WHEN** 新增可编辑的金额或单价字段
- **THEN** SHALL 使用 `<AmountInput v-model="..." />` 组件
- **THEN** SHALL NOT 使用 `<el-input-number>` 或页面内联 focus/blur 千分位逻辑
#### Scenario: 新增金额只读展示
- **WHEN** 在列表列、查看弹窗、合计文案中展示金额
- **THEN** SHALL 使用 `formatMoneyDisplay(v, 2)` 格式化
- **THEN** 货币符号 `¥` 仍在模板侧拼接,不内置于函数
#### Scenario: Code review 金额展示
- **WHEN** PR 涉及金额/单价字段展示
- **THEN** 审查者 SHALL 确认使用 `AmountInput`(可编辑)或 `formatMoneyDisplay`(只读),拒绝页面内复制千分位实现
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+141 -89
View File
@@ -1,11 +1,11 @@
# Graph Report - src (2026-05-25)
## Corpus Check
- Large corpus: 612 files · ~351,591 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
- Large corpus: 616 files · ~355,459 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
## Summary
- 1689 nodes · 2148 edges · 38 communities detected
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 476 edges (avg confidence: 0.8)
- 1717 nodes · 2195 edges · 46 communities detected
- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 490 edges (avg confidence: 0.8)
- Token cost: 0 input · 0 output
## Community Hubs (Navigation)
@@ -28,29 +28,37 @@
- [[_COMMUNITY_Community 16|Community 16]]
- [[_COMMUNITY_Community 17|Community 17]]
- [[_COMMUNITY_Community 18|Community 18]]
- [[_COMMUNITY_Community 19|Community 19]]
- [[_COMMUNITY_Community 20|Community 20]]
- [[_COMMUNITY_Community 21|Community 21]]
- [[_COMMUNITY_Community 22|Community 22]]
- [[_COMMUNITY_Community 23|Community 23]]
- [[_COMMUNITY_Community 24|Community 24]]
- [[_COMMUNITY_Community 25|Community 25]]
- [[_COMMUNITY_Community 26|Community 26]]
- [[_COMMUNITY_Community 27|Community 27]]
- [[_COMMUNITY_Community 28|Community 28]]
- [[_COMMUNITY_Community 29|Community 29]]
- [[_COMMUNITY_Community 30|Community 30]]
- [[_COMMUNITY_Community 31|Community 31]]
- [[_COMMUNITY_Community 32|Community 32]]
- [[_COMMUNITY_Community 33|Community 33]]
- [[_COMMUNITY_Community 34|Community 34]]
- [[_COMMUNITY_Community 35|Community 35]]
- [[_COMMUNITY_Community 36|Community 36]]
- [[_COMMUNITY_Community 37|Community 37]]
- [[_COMMUNITY_Community 38|Community 38]]
- [[_COMMUNITY_Community 39|Community 39]]
- [[_COMMUNITY_Community 40|Community 40]]
- [[_COMMUNITY_Community 41|Community 41]]
- [[_COMMUNITY_Community 42|Community 42]]
- [[_COMMUNITY_Community 43|Community 43]]
- [[_COMMUNITY_Community 45|Community 45]]
- [[_COMMUNITY_Community 46|Community 46]]
- [[_COMMUNITY_Community 47|Community 47]]
- [[_COMMUNITY_Community 48|Community 48]]
- [[_COMMUNITY_Community 49|Community 49]]
- [[_COMMUNITY_Community 51|Community 51]]
## God Nodes (most connected - your core abstractions)
1. `get()` - 182 edges
2. `push()` - 27 edges
2. `push()` - 28 edges
3. `WebSocketClient` - 26 edges
4. `request()` - 23 edges
5. `withFullscreenLoading()` - 17 edges
@@ -61,208 +69,252 @@
10. `StorageCompatibilityManager` - 12 edges
## Surprising Connections (you probably didn't know these)
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
views/basic-info/collection-protocol-no/index.vue → utils/fullscreen-loading.ts
- `handleBatchRevoke()` --calls--> `withFullscreenLoading()` [INFERRED]
views/basic-info/collection-protocol-no/index.vue → utils/fullscreen-loading.ts
- `handleBatchDelete()` --calls--> `withFullscreenLoading()` [INFERRED]
views/basic-info/customer/index.vue → utils/fullscreen-loading.ts
- `subscribeTokenRefresh()` --calls--> `push()` [INFERRED]
utils/http/index.ts → views/operations/storage-facility/index.vue
- `handleUnauthorizedResponse()` --calls--> `fetchRefreshToken()` [INFERRED]
utils/http/index.ts → api/auth.ts
- `fetchStorageReleaseReviewList()` --calls--> `get()` [INFERRED]
api/storage-release-review.ts → views/production/process-route/index.vue
- `fetchStorageReleaseReviewDetail()` --calls--> `get()` [INFERRED]
api/storage-release-review.ts → views/production/process-route/index.vue
## Communities
### Community 0 - "Community 0"
Cohesion: 0.01
Nodes (138): fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchCellSampleTypeList(), fetchChannelAccount() (+130 more)
Nodes (86): fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchCellSampleTypeList(), fetchChannelAccount() (+78 more)
### Community 1 - "Community 1"
Cohesion: 0.01
Nodes (47): autoGenerateSchedules(), completePilotApplication(), createPilotApplication(), createPilotInfusionPlan(), deletePilotApplication(), deletePilotInfusionPlan(), deletePilotInfusionSchedule(), fetchChannelList() (+39 more)
Cohesion: 0.03
Nodes (60): fetchBatchGenerateSampleCodes(), fetchBatchIssueSampleCodes(), fetchCollectionRegionList(), fetchCreateCollectionRegion(), fetchCreateHospital(), fetchCreateSampleCode(), fetchDeleteCollectionRegion(), fetchDeleteHospital() (+52 more)
### Community 2 - "Community 2"
Cohesion: 0.03
Nodes (62): fetchBatchGenerateProtocolNos(), fetchBatchGenerateSampleCodes(), fetchBatchIssueProtocolNos(), fetchBatchIssueSampleCodes(), fetchCollectionProtocolNoList(), fetchCreateCollectionProtocolNo(), fetchCreateSampleCode(), fetchDeleteCollectionProtocolNo() (+54 more)
Nodes (39): fetchGetMenuList(), fetchGetMenuCodes(), fetchGetUserInfo(), fetchLogin(), fetchRefreshToken(), clickTab(), handleTouchEnd(), setTransition() (+31 more)
### Community 3 - "Community 3"
Cohesion: 0.03
Nodes (39): fetchGetMenuList(), fetchGetMenuCodes(), fetchGetUserInfo(), fetchLogin(), fetchRefreshToken(), clickTab(), handleTouchEnd(), setTransition() (+31 more)
Nodes (45): fetchDeptTree(), fetchPostBoundUserIds(), fetchUploadAttachment(), FireworkSystem, reload(), handleConfirmAttachmentChange(), loadDeptData(), onPersonSelectChange() (+37 more)
### Community 4 - "Community 4"
Cohesion: 0.04
Nodes (43): fetchDeptTree(), fetchPostBoundUserIds(), fetchUploadAttachment(), reload(), loadDeptData(), onPersonSelectChange(), handleAttachmentChange(), handleMenuJump() (+35 more)
Cohesion: 0.03
Nodes (22): fetchAllConsumablePacks(), fetchAllConsumables(), fetchAllConsumableStockLogs(), fetchAllOutputTypes(), fetchAllProcessCategories(), fetchAllProcesses(), fetchAllReagents(), fetchAllReagentStockLogs() (+14 more)
### Community 5 - "Community 5"
Cohesion: 0.05
Nodes (48): autoGenerateSchedules(), completePilotApplication(), createPilotApplication(), createPilotInfusionPlan(), deletePilotApplication(), deletePilotInfusionPlan(), deletePilotInfusionSchedule(), fetchChannelList() (+40 more)
### Community 6 - "Community 6"
Cohesion: 0.06
Nodes (11): fetchGetLatestUpgradeLog(), getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager (+3 more)
### Community 6 - "Community 6"
Cohesion: 0.05
Nodes (43): fetchAccessLogList(), fetchCleanRoomList(), fetchCreateAccessLog(), fetchCreateCleanRoom(), fetchCreateSite(), fetchDeleteAccessLog(), fetchDeleteCleanRoom(), fetchDeleteSite() (+35 more)
### Community 7 - "Community 7"
Cohesion: 0.05
Nodes (41): fetchAccessLogList(), fetchCleanRoomList(), fetchCreateAccessLog(), fetchCreateCleanRoom(), fetchCreateSite(), fetchDeleteAccessLog(), fetchDeleteCleanRoom(), fetchDeleteSite() (+33 more)
### Community 8 - "Community 8"
Cohesion: 0.08
Nodes (6): handleReset(), handleSearch(), WebSocketClient, TableCache, emit(), handleSubmit()
### Community 8 - "Community 8"
Cohesion: 0.06
Nodes (12): collectIds(), useSettingsHandlers(), useSettingsPanel(), useSettingsState(), ComponentLoader, RoutePermissionValidator, RouteTransformer, useCeremony() (+4 more)
### Community 9 - "Community 9"
Cohesion: 0.06
Nodes (28): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList(), fetchPaymentDetailList(), fetchReceiptConfirmedList(), fetchReceiptConfirmList() (+20 more)
### Community 10 - "Community 10"
Cohesion: 0.07
Nodes (11): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), ComponentLoader, RoutePermissionValidator, RouteTransformer, useCeremony(), useTheme() (+3 more)
### Community 11 - "Community 11"
Cohesion: 0.07
Nodes (21): auditorDisplay(), dash(), expressName(), formatYm(), formatYmd(), sampleTypeName(), siteName(), unitName() (+13 more)
### Community 10 - "Community 10"
Cohesion: 0.08
Nodes (31): toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes() (+23 more)
### Community 11 - "Community 11"
Cohesion: 0.09
Nodes (16): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), postorder(), preorder(), applyTreeExpand(), handleAdd() (+8 more)
### Community 12 - "Community 12"
Cohesion: 0.1
Nodes (13): fetchEthnicList(), addSample(), applyDonationBundleToForm(), confirmBatchTransportApply(), createEmptyTransport(), ensureDonationProtocolNoInOptions(), ensureEthnicOptionInList(), handleOpenForAdd() (+5 more)
Cohesion: 0.07
Nodes (22): handleBlur(), handleFocus(), handleInput(), fetchEthnicList(), addSample(), applyDonationBundleToForm(), confirmBatchTransportApply(), createEmptyTransport() (+14 more)
### Community 13 - "Community 13"
Cohesion: 0.11
Nodes (21): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolDetail(), buildInsuranceAttachmentsValue(), buildInsurancePayload(), formatYmdFromAny(), fullFileUrl(), handleBatchEdit() (+13 more)
Cohesion: 0.06
Nodes (20): fetchAttachmentDownloadUrl(), fetchOrderAdjusts(), fetchOrderDetail(), fetchOrderItems(), fetchOrderList(), fetchPriceVersionDetail(), fetchSystemConfig(), handleDownloadAttachment() (+12 more)
### Community 14 - "Community 14"
Cohesion: 0.09
Nodes (13): fetchAttachmentDownloadUrl(), handleDownloadAttachment(), handleReceptionAttachmentDownload(), attachmentFullUrl(), handleAttachmentDownload(), handleAttachmentPreview(), attachmentFullUrl(), handleAttachmentDownload() (+5 more)
Cohesion: 0.07
Nodes (17): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), collectIds(), postorder(), preorder(), applyTreeExpand() (+9 more)
### Community 15 - "Community 15"
Cohesion: 0.1
Nodes (18): fetchCollectionRegionList(), fetchCreateCollectionRegion(), fetchCreateHospital(), fetchDeleteCollectionRegion(), fetchDeleteHospital(), fetchHospitalList(), fetchUpdateCollectionRegion(), fetchUpdateHospital() (+10 more)
Cohesion: 0.11
Nodes (26): toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes() (+18 more)
### Community 16 - "Community 16"
Cohesion: 0.12
Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
Cohesion: 0.11
Nodes (20): fetchBatchGenerateProtocolNos(), fetchBatchIssueProtocolNos(), fetchCollectionProtocolNoList(), fetchCreateCollectionProtocolNo(), fetchDeleteCollectionProtocolNo(), fetchUpdateCollectionProtocolNo(), handleAdd(), handleBatchDelete() (+12 more)
### Community 17 - "Community 17"
Cohesion: 0.12
Nodes (19): fetchCreateUser(), fetchDeleteUser(), fetchResetPassword(), fetchRoleOptions(), fetchUpdateUser(), fetchUserDetail(), formatUserDeptDisplay(), handleAdd() (+11 more)
Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
### Community 18 - "Community 18"
Cohesion: 0.1
Nodes (6): fetchProductionTaskDetail(), fetchProductionTaskList(), fetchUpdateProductionTask(), handleClose(), handleSubmit(), loadTaskDetail()
### Community 19 - "Community 19"
Cohesion: 0.14
Nodes (17): fetchCreateUser(), fetchDeleteUser(), fetchResetPassword(), fetchUpdateUser(), fetchUserDetail(), formatUserDeptDisplay(), handleAdd(), handleDelete() (+9 more)
### Community 20 - "Community 20"
Cohesion: 0.15
Nodes (12): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), handleAdd(), handleBatchDelete(), handleDelete(), handleReset() (+4 more)
Cohesion: 0.14
Nodes (14): fetchConfirmTxn(), fetchServiceOrderTxnList(), fetchVoidTxn(), executeSubmitConfirm(), fullFileUrl(), handlePreviewAttachment(), handleReset(), handleSearch() (+6 more)
### Community 21 - "Community 21"
Cohesion: 0.12
Nodes (12): fetchApproveTask(), fetchBusinessAllTasks(), fetchCompletedTasks(), fetchDesignerData(), fetchInstanceDetail(), fetchMyInstances(), fetchPendingTasks(), fetchProcessDefList() (+4 more)
### Community 23 - "Community 23"
Cohesion: 0.16
Nodes (10): useTable(), useTableImpl(), getColumnChecks(), useTableColumns(), createErrorHandler(), createSmartDebounce(), defaultResponseAdapter(), extractPagination() (+2 more)
### Community 22 - "Community 22"
### Community 24 - "Community 24"
Cohesion: 0.15
Nodes (12): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), handleAdd(), handleBatchDelete(), handleDelete(), handleReset() (+4 more)
### Community 25 - "Community 25"
Cohesion: 0.27
Nodes (14): useChart(), useChartComponent(), useChartOps(), colourBlend(), getCssVar(), getDarkColor(), getLightColor(), handleElementThemeColor() (+6 more)
### Community 24 - "Community 24"
### Community 27 - "Community 27"
Cohesion: 0.17
Nodes (3): fetchResearchDonationAuditList(), fetchResearchDonationDetail(), fetchResearchDonationList()
### Community 25 - "Community 25"
### Community 28 - "Community 28"
Cohesion: 0.18
Nodes (3): fetchMaterialList(), fetchMaterialOptions(), fetchMaterialStockLogList()
### Community 26 - "Community 26"
### Community 29 - "Community 29"
Cohesion: 0.2
Nodes (2): fetchQcMaterialList(), fetchQcMaterialOptions()
### Community 27 - "Community 27"
Cohesion: 0.28
Nodes (1): FireworkSystem
### Community 29 - "Community 29"
### Community 31 - "Community 31"
Cohesion: 0.39
Nodes (6): isIgnorableScriptError(), normalizeErrorMessage(), registerPromiseErrorHandler(), registerResourceErrorHandler(), scriptErrorHandler(), setupErrorHandle()
### Community 30 - "Community 30"
### Community 32 - "Community 32"
Cohesion: 0.36
Nodes (1): TableHeightCalculator
### Community 31 - "Community 31"
### Community 33 - "Community 33"
Cohesion: 0.25
Nodes (2): fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList()
### Community 32 - "Community 32"
### Community 34 - "Community 34"
Cohesion: 0.25
Nodes (2): fetchQcTaskDetail(), fetchQcTaskList()
### Community 33 - "Community 33"
### Community 35 - "Community 35"
Cohesion: 0.33
Nodes (2): logApiCryptoBootInfo(), maskSecret()
### Community 34 - "Community 34"
### Community 36 - "Community 36"
Cohesion: 0.29
Nodes (2): fetchLeaveDetail(), fetchLeaveList()
### Community 37 - "Community 37"
Cohesion: 0.29
Nodes (2): fetchQcWorkOrderDetail(), fetchQcWorkOrderList()
### Community 38 - "Community 38"
Cohesion: 0.47
Nodes (3): isPaymentDueWithinWarnWindow(), parsePaymentDueYmd(), startOfLocalDay()
### Community 37 - "Community 37"
Cohesion: 0.53
Nodes (4): isEtaTodayOrEarlier(), parseEtaLocalDate(), sampleReceptionRowClassName(), startOfLocalDay()
### Community 40 - "Community 40"
Cohesion: 0.33
Nodes (2): fetchSampleReceptionCheckItemList(), fetchSampleReceptionCheckItemsActive()
### Community 38 - "Community 38"
### Community 41 - "Community 41"
Cohesion: 0.33
Nodes (2): fetchQcThirdPartyItemList(), fetchQcThirdPartyItemsActive()
### Community 42 - "Community 42"
Cohesion: 0.33
Nodes (2): fetchQcThirdPartyCompanyList(), fetchQcThirdPartyCompanyOptions()
### Community 43 - "Community 43"
Cohesion: 0.33
Nodes (2): fetchQcLabTestItemList(), fetchQcLabTestItemsActive()
### Community 45 - "Community 45"
Cohesion: 0.5
Nodes (2): focusInput(), handleKeydown()
### Community 39 - "Community 39"
### Community 46 - "Community 46"
Cohesion: 0.67
Nodes (2): if(), logSidebarMenu()
### Community 40 - "Community 40"
### Community 47 - "Community 47"
Cohesion: 0.5
Nodes (1): fetchStorageEntrySmsList()
### Community 41 - "Community 41"
### Community 48 - "Community 48"
Cohesion: 0.5
Nodes (1): fetchSampleSmsNotificationList()
### Community 49 - "Community 49"
Cohesion: 1.0
Nodes (2): getSettingDefaults(), resetToDefaults()
### Community 43 - "Community 43"
### Community 51 - "Community 51"
Cohesion: 1.0
Nodes (2): defaultAvatarPathByRole(), resolveUserAvatarUrl()
## Knowledge Gaps
- **Thin community `Community 26`** (10 nodes): `fetchBatchStockInQcMaterial()`, `fetchBatchStockOutQcMaterial()`, `fetchCreateQcMaterial()`, `fetchDeleteQcMaterial()`, `fetchQcMaterialList()`, `fetchQcMaterialOptions()`, `fetchStockInQcMaterial()`, `fetchStockOutQcMaterial()`, `fetchUpdateQcMaterial()`, `qc-material.ts`
- **Thin community `Community 29`** (10 nodes): `fetchBatchStockInQcMaterial()`, `fetchBatchStockOutQcMaterial()`, `fetchCreateQcMaterial()`, `fetchDeleteQcMaterial()`, `fetchQcMaterialList()`, `fetchQcMaterialOptions()`, `fetchStockInQcMaterial()`, `fetchStockOutQcMaterial()`, `fetchUpdateQcMaterial()`, `qc-material.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 27`** (9 nodes): `FireworkSystem`, `.constructor()`, `.createFirework()`, `.createParticle()`, `.getAvailableParticle()`, `.initializePool()`, `.preloadAllImages()`, `.preloadImage()`, `index.vue`
- **Thin community `Community 32`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 30`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
- **Thin community `Community 33`** (8 nodes): `fetchCompleteProductionWorkOrder()`, `fetchConfigureProductionWorkOrder()`, `fetchCreateProductionWorkOrder()`, `fetchDeleteProductionWorkOrder()`, `fetchProductionWorkOrderDetail()`, `fetchProductionWorkOrderList()`, `fetchUpdateProductionWorkOrder()`, `production-work-order.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 31`** (8 nodes): `fetchCompleteProductionWorkOrder()`, `fetchConfigureProductionWorkOrder()`, `fetchCreateProductionWorkOrder()`, `fetchDeleteProductionWorkOrder()`, `fetchProductionWorkOrderDetail()`, `fetchProductionWorkOrderList()`, `fetchUpdateProductionWorkOrder()`, `production-work-order.ts`
- **Thin community `Community 34`** (8 nodes): `fetchCompleteQcTask()`, `fetchCreateQcTask()`, `fetchDeleteQcTask()`, `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 32`** (8 nodes): `fetchCompleteQcTask()`, `fetchCreateQcTask()`, `fetchDeleteQcTask()`, `fetchQcTaskDetail()`, `fetchQcTaskList()`, `fetchStartQcTask()`, `fetchUpdateQcTaskAttachments()`, `qc-task.ts`
- **Thin community `Community 35`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 33`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
- **Thin community `Community 36`** (7 nodes): `fetchCreateLeave()`, `fetchDeleteLeave()`, `fetchLeaveDetail()`, `fetchLeaveList()`, `fetchSubmitLeave()`, `fetchUpdateLeave()`, `leave.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 38`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
- **Thin community `Community 37`** (7 nodes): `fetchConfigureQcWorkOrder()`, `fetchCreateQcWorkOrder()`, `fetchDeleteQcWorkOrder()`, `fetchQcWorkOrderDetail()`, `fetchQcWorkOrderList()`, `fetchUpdateQcWorkOrder()`, `qc-work-order.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 39`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
- **Thin community `Community 40`** (6 nodes): `fetchCreateSampleReceptionCheckItem()`, `fetchDeleteSampleReceptionCheckItem()`, `fetchSampleReceptionCheckItemList()`, `fetchSampleReceptionCheckItemsActive()`, `fetchUpdateSampleReceptionCheckItem()`, `sample-reception-check-item.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 40`** (4 nodes): `fetchGenerateStorageEntrySms()`, `fetchStorageEntrySmsList()`, `fetchToggleStorageEntrySmsNotified()`, `storage-entry-sms-notification.ts`
- **Thin community `Community 41`** (6 nodes): `fetchCreateQcThirdPartyItem()`, `fetchDeleteQcThirdPartyItem()`, `fetchQcThirdPartyItemList()`, `fetchQcThirdPartyItemsActive()`, `fetchUpdateQcThirdPartyItem()`, `qc-third-party-item.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 41`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
- **Thin community `Community 42`** (6 nodes): `fetchCreateQcThirdPartyCompany()`, `fetchDeleteQcThirdPartyCompany()`, `fetchQcThirdPartyCompanyList()`, `fetchQcThirdPartyCompanyOptions()`, `fetchUpdateQcThirdPartyCompany()`, `qc-third-party-company.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 43`** (3 nodes): `defaultAvatarPathByRole()`, `resolveUserAvatarUrl()`, `user-avatar.ts`
- **Thin community `Community 43`** (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 45`** (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 46`** (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 47`** (4 nodes): `fetchGenerateStorageEntrySms()`, `fetchStorageEntrySmsList()`, `fetchToggleStorageEntrySmsNotified()`, `storage-entry-sms-notification.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 48`** (4 nodes): `fetchGenerateSms()`, `fetchSampleSmsNotificationList()`, `fetchToggleSmsNotified()`, `sample-sms-notification.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 49`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 51`** (3 nodes): `defaultAvatarPathByRole()`, `resolveUserAvatarUrl()`, `user-avatar.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 11`, `Community 12`, `Community 13`, `Community 15`, `Community 17`, `Community 18`, `Community 20`, `Community 24`, `Community 25`, `Community 26`, `Community 31`, `Community 32`, `Community 40`?**
_High betweenness centrality (0.270) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 4` to `Community 1`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 10`, `Community 12`, `Community 13`, `Community 27`?**
_High betweenness centrality (0.127) - this node is a cross-community bridge._
- **Why does `handleDynamicRoutes()` connect `Community 3` to `Community 8`?**
_High betweenness centrality (0.040) - this node is a cross-community bridge._
- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 9`, `Community 12`, `Community 13`, `Community 14`, `Community 16`, `Community 18`, `Community 19`, `Community 20`, `Community 21`, `Community 24`, `Community 27`, `Community 28`, `Community 29`, `Community 33`, `Community 34`, `Community 36`, `Community 37`, `Community 40`, `Community 41`, `Community 42`, `Community 43`, `Community 47`, `Community 48`?**
_High betweenness centrality (0.256) - this node is a cross-community bridge._
- **Why does `push()` connect `Community 3` to `Community 0`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 12`, `Community 15`?**
_High betweenness centrality (0.141) - this node is a cross-community bridge._
- **Why does `handleDynamicRoutes()` connect `Community 2` to `Community 10`?**
_High betweenness centrality (0.054) - this node is a cross-community bridge._
- **Are the 181 inferred relationships involving `get()` (e.g. with `collectLeafFacilityNodesInTreeOrder()` and `buildTreePathLabelFromFlat()`) actually correct?**
_`get()` has 181 INFERRED edges - model-reasoned connections that need verification._
- **Are the 26 inferred relationships involving `push()` (e.g. with `collectLeafFacilityNodesInTreeOrder()` and `fetchAllPagedRecords()`) actually correct?**
_`push()` has 26 INFERRED edges - model-reasoned connections that need verification._
- **Are the 27 inferred relationships involving `push()` (e.g. with `collectLeafFacilityNodesInTreeOrder()` and `fetchAllPagedRecords()`) actually correct?**
_`push()` has 27 INFERRED edges - model-reasoned connections that need verification._
- **Are the 21 inferred relationships involving `request()` (e.g. with `showSuccess()` and `showError()`) actually correct?**
_`request()` has 21 INFERRED edges - model-reasoned connections that need verification._
- **Are the 16 inferred relationships involving `withFullscreenLoading()` (e.g. with `.close()` and `handleSubmit()`) actually correct?**
+4 -4
View File
@@ -57,12 +57,12 @@
</div>
<div id="legend"></div>
</div>
<div id="stats">1689 nodes &middot; 2148 edges &middot; 253 communities</div>
<div id="stats">1717 nodes &middot; 2195 edges &middot; 262 communities</div>
</div>
<script>
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 33, "community_name": "Community 33", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 33, "community_name": "Community 33", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 33, "community_name": "Community 33", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 33, "community_name": "Community 33", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 33, "community_name": "Community 33", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 33, "community_name": "Community 33", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 77, "community_name": "Community 77", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 78, "community_name": "Community 78", "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.5, "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.3, "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.2, "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.2, "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_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": 253}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 207}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 105}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 96}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 72}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 55}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 54}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 51}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 47}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 42}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 39}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 30}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 27}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 27}, {"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": 22}, {"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": 17}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 17}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 17}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 16}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 13}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 12}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 11}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 10}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 9}, {"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": 8}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 8}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 7}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 6}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 6}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 6}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 6}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 5}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 4}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 4}, {"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": 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": 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
const RAW_NODES = [{"id": "app_vue", "label": "App.vue", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.3, "font": {"size": 0, "color": "#ffffff"}, "title": "App.vue", "community": 35, "community_name": "Community 35", "source_file": "App.vue", "file_type": "code", "degree": 3}, {"id": "src_app_refreshbuttonautoicons", "label": "refreshButtonAutoIcons()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshButtonAutoIcons()", "community": 35, "community_name": "Community 35", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "src_app_refreshpaneltitleicons", "label": "refreshPanelTitleIcons()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.1, "font": {"size": 0, "color": "#ffffff"}, "title": "refreshPanelTitleIcons()", "community": 35, "community_name": "Community 35", "source_file": "App.vue", "file_type": "code", "degree": 1}, {"id": "main_ts", "label": "main.ts", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.4, "font": {"size": 0, "color": "#ffffff"}, "title": "main.ts", "community": 35, "community_name": "Community 35", "source_file": "main.ts", "file_type": "code", "degree": 4}, {"id": "src_main_masksecret", "label": "maskSecret()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "maskSecret()", "community": 35, "community_name": "Community 35", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "src_main_logapicryptobootinfo", "label": "logApiCryptoBootInfo()", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.2, "font": {"size": 0, "color": "#ffffff"}, "title": "logApiCryptoBootInfo()", "community": 35, "community_name": "Community 35", "source_file": "main.ts", "file_type": "code", "degree": 2}, {"id": "env_d_ts", "label": "env.d.ts", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 85, "community_name": "Community 85", "source_file": "env.d.ts", "file_type": "code", "degree": 0}, {"id": "shims_loose_d_ts", "label": "shims-loose.d.ts", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "shims-loose.d.ts", "community": 86, "community_name": "Community 86", "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.5, "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.3, "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.2, "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.2, "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 LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 259}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 108}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 96}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 80}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 65}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 56}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 55}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 52}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 51}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 45}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 42}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 41}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 40}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 39}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 35}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 31}, {"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": 20}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 20}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 19}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 17}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 17}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 17}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 16}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 13}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 12}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 11}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 10}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 9}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 8}, {"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": 8}, {"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": 7}, {"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": 6}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 6}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 5}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 4}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 4}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 4}, {"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": 3}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 3}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 3}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 3}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 3}, {"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
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
function esc(s) {
File diff suppressed because it is too large. Load diff
+36 -32
View File
@@ -17,8 +17,8 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/common/index.ts": 1778582068.0254738,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/directive/directive.d.ts": 1778582068.026978,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/api/api.d.ts": 1778582068.0246184,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1779685868.3519082,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1779685098.1460314,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1779700098.614053,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1779700080.6929684,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/store/index.ts": 1778582068.0293276,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/types/router/index.ts": 1778775532.895603,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/locales/index.ts": 1778582068.004279,
@@ -51,6 +51,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/mask-sensitive.ts": 1778984825.4182227,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-labels.ts": 1779615806.1798687,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/index.ts": 1778582068.0369413,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts": 1779695444.9027524,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/category-path-display.ts": 1778582068.0304127,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-labels.ts": 1779199108.173778,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/loginRsa.ts": 1778582068.0373487,
@@ -184,6 +185,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/system-view-dialog/index.vue": 1779586311.488459,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/production-task-view-dialog/index.vue": 1779615853.6423426,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/business/order-operate-dialog-bridge/index.vue": 1779525781.611354,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue": 1779695502.3228035,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/index.ts": 1778582068.0037498,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/core/useFastEnter.ts": 1778582068.0014625,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/hooks/core/useTableColumns.ts": 1778582068.0029352,
@@ -203,14 +205,14 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-third-party-item.ts": 1779017836.101254,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-release-review.ts": 1779615813.3431153,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/workflow.ts": 1778729873.096252,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts": 1779615080.6717544,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts": 1779692786.7954206,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-task-result.ts": 1779332042.258692,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-third-party-company.ts": 1779021425.3773527,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/collection-protocol.ts": 1779691498.8437068,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/chinaRegion.ts": 1778582067.8620915,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/storage-entry-sms-notification.ts": 1779691739.8547683,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/business.ts": 1779159587.6033742,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts": 1779692218.2173133,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/admin.ts": 1779696010.1232035,
"/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/cell-product.ts": 1779594447.3049195,
@@ -218,30 +220,30 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/research-donation.ts": 1779692338.7516685,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-task.ts": 1779612098.519313,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-item-param.ts": 1779022632.5658252,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts": 1779586811.7854652,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts": 1779692910.5154753,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material-usage.ts": 1779284726.00147,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-material.ts": 1779283280.0705447,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/system.ts": 1778582067.862994,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material.ts": 1779283387.4196396,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts": 1779255909.8553667,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts": 1779692503.163169,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/auth.ts": 1778582067.8610063,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts": 1779611630.4600656,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts": 1779692694.5895822,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/auth/login/index.vue": 1779525781.6116724,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/refund-confirm/index.vue": 1779691522.6943383,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/refund-confirm/index.vue": 1779699061.836399,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/index.vue": 1779686149.7501445,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolStatusChangeDialog.vue": 1779525781.613681,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue": 1779583778.6780727,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue": 1779699075.4044075,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue": 1779525781.6162472,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue": 1779525781.6179993,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue": 1779699092.0957584,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolAuditDialog.vue": 1779525781.6193507,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/sample-reception-info/index.vue": 1779691690.1009152,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-info/index.vue": 1779686339.3853126,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-info/index.vue": 1779699056.0146186,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/storage-cert/index.vue": 1779692218.217227,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol-audit/index.vue": 1779686205.7531993,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material/index.vue": 1779543540.7084875,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue": 1779692218.2173543,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue": 1779699073.6049047,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/storage-entry-info/index.vue": 1779691749.1963794,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-confirm/index.vue": 1779691305.390457,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-confirm/index.vue": 1779699057.959591,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/material-stock-log/index.vue": 1779543540.7038007,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/outside/Iframe.vue": 1779525781.6271372,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/operations/demo/index.vue": 1779525781.6276834,
@@ -251,19 +253,19 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/audit/index.vue": 1779692379.194848,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/index.vue": 1779692356.4217088,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationAuditDialog.vue": 1779525781.6319423,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue": 1779591471.046118,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue": 1779699979.6871445,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationFormDialog.vue": 1779525781.635114,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationStatusChangeDialog.vue": 1779525781.6357327,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/dashboard/console/index.vue": 1779525781.636181,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/tenant/index.vue": 1779543443.6733122,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/order/index.vue": 1779543540.74551,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/order/index.vue": 1779699966.1783187,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/unit/index.vue": 1779543540.7397332,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/role/index.vue": 1779543540.7380679,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/post/index.vue": 1779543540.7481663,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/category/index.vue": 1779543540.749298,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/express/index.vue": 1779543540.7485101,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/index.vue": 1779543540.7475703,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/detail.vue": 1779525781.6442838,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/detail.vue": 1779699977.6617017,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/modules/user-dialog.vue": 1779525781.6434622,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/modules/user-search.vue": 1779525781.643876,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/product/index.vue": 1779543540.7469623,
@@ -291,9 +293,9 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/source-chain/chainToFlow.ts": 1779601450.3906622,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process-route/index.vue": 1779543540.7289982,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/sop/index.vue": 1779543540.726837,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-task/index.vue": 1779615840.3873165,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-task/index.vue": 1779692921.2198172,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/reagent/index.vue": 1779589143.1296964,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue": 1779615827.927988,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue": 1779692806.8630154,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/useTaskStepEditor.ts": 1779615478.2475564,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/StepDetailPanel.vue": 1779525781.678735,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/CompleteProductionTaskDialog.vue": 1779615467.9727454,
@@ -308,35 +310,37 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process/index.vue": 1779543540.717012,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/process-category/index.vue": 1779543540.7154598,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/index/index.vue": 1779525781.6949234,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue": 1779615108.02306,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue": 1779699975.3058991,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception-check-item/index.vue": 1779543540.7019148,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/lab-test-item/index.vue": 1779543540.7013087,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material/index.vue": 1779543540.7000535,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue": 1779543540.698455,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue": 1779612120.724959,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue": 1779692594.0406384,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue": 1779699971.8908935,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/storage-release-review/index.vue": 1779543540.695075,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/storage-release-review/StorageReleaseReviewDialog.vue": 1779525781.7374997,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/storage-release-review/StorageReleaseViewDialog.vue": 1779613667.0297782,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-material-usage/index.vue": 1779543540.693297,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/third-party-company/index.vue": 1779543540.692346,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/third-party-company/index.vue": 1779699924.4409633,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/exception/500/index.vue": 1779546148.0553653,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/exception/403/index.vue": 1779546144.3909206,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/exception/404/index.vue": 1779546146.242008,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-type/index.vue": 1779543540.6913223,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-institution/index.vue": 1779543540.6905549,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-institution/CheckupPackagePanel.vue": 1779525781.7596755,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue": 1779633189.469777,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue": 1779543540.6894271,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelViewDialog.vue": 1779619832.8572278,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-institution/index.vue": 1779697615.6754658,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-institution/CheckupPackagePanel.vue": 1779697623.5824215,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue": 1779699826.455601,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnTable.vue": 1779699863.6833217,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue": 1779699868.898797,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue": 1779697613.264022,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelViewDialog.vue": 1779697640.6669152,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/index.vue": 1779637937.8548203,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/pilot-application/ApplicationDetail.vue": 1779657466.23388,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-price/index.vue": 1779543540.6862803,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue": 1779632871.1355302,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/project-price-system/index.vue": 1779543540.6854389,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-price/index.vue": 1779697593.9746604,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue": 1779699868.3981209,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/project-price-system/index.vue": 1779697597.2297914,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-spec/index.vue": 1779543540.6845775,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/sample-code/index.vue": 1779543540.6835444,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/cell-sample-type/index.vue": 1779543540.6821191,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/insurance-company/index.vue": 1779543540.6812408,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/insurance-company/index.vue": 1779699898.7911212,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-protocol-no/index.vue": 1779543540.6802733,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/customer/index.vue": 1779686149.7501822,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/collection-region/index.vue": 1779543540.6782162,
@@ -357,7 +361,7 @@
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/core/RoutePermissionValidator.ts": 1778582068.0127926,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/core/index.ts": 1778582068.0138035,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/core/IframeRouteManager.ts": 1778582068.0121944,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/sqxp.ts": 1779637692.9707448,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/sqxp.ts": 1779693179.2014906,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/index.ts": 1778598510.6043763,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/exception.ts": 1779546186.993006,
"/Users/wuzilong/work/00code/zkxw/web-admin/src/router/routes/staticRoutes.ts": 1779546226.1088154,
+5
View File
@@ -2007,6 +2007,11 @@ export function fetchCreateUnsubscribeTxn(orderId: string, data: Record<string,
return request.post({ url: `/web/admin/channel-service-orders/${orderId}/unsubscribe`, params: data })
}
/** 更新待生效流水 */
export function fetchUpdateServiceOrderTxn(txnId: string, data: Record<string, any>) {
return request.put({ url: `/web/admin/channel-service-order-txns/${txnId}`, params: data })
}
/** 流水发起财务确认 */
export function fetchSubmitTxnFinance(txnId: string, data: Record<string, any>) {
return request.post({ url: `/web/admin/channel-service-order-txns/${txnId}/submit-finance`, params: data })
@@ -70,7 +70,7 @@
</div>
</div>
</div>
<p class="upload-hint">支持图片、视频、文档等,单文件不超过 20MB。</p>
<p class="upload-hint">支持图片、视频、文档等。</p>
</div>
</el-form-item>
</div>
@@ -158,11 +158,6 @@
async function handleAttachmentChange(uploadFile: { raw?: File }) {
const file = uploadFile.raw
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
const uploading: FinanceAttachmentItem = {
id: tempId,
@@ -0,0 +1,80 @@
<template>
<el-input
v-model="displayText"
:placeholder="placeholder"
:disabled="disabled"
:clearable="clearable"
style="width: 100%"
@focus="handleFocus"
@blur="handleBlur"
@input="handleInput"
/>
</template>
<script setup lang="ts">
import {
formatMoneyDisplay,
parseMoneyToNumber,
sanitizeMoneyInput,
} from '@/utils/money-format'
defineOptions({ name: 'AmountInput' })
interface Props {
modelValue: number | null
min?: number
max?: number
precision?: number
placeholder?: string
disabled?: boolean
clearable?: boolean
}
const props = withDefaults(defineProps<Props>(), {
min: undefined,
max: undefined,
precision: 2,
placeholder: '',
disabled: false,
clearable: true,
})
const emit = defineEmits<{
'update:modelValue': [value: number | null]
change: [value: number | null]
}>()
const displayText = ref('')
const isFocused = ref(false)
watch(
() => props.modelValue,
(val) => {
if (!isFocused.value) {
displayText.value = formatMoneyDisplay(val, props.precision)
}
},
{ immediate: true }
)
function handleFocus() {
isFocused.value = true
displayText.value = sanitizeMoneyInput(displayText.value, props.precision)
}
function handleInput(val: string) {
displayText.value = sanitizeMoneyInput(val, props.precision)
}
function handleBlur() {
isFocused.value = false
let num = parseMoneyToNumber(displayText.value, props.precision)
if (num !== null) {
if (props.min !== undefined && num < props.min) num = props.min
if (props.max !== undefined && num > props.max) num = props.max
}
emit('update:modelValue', num)
emit('change', num)
displayText.value = formatMoneyDisplay(num, props.precision)
}
</script>
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_cell_product_price_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/cell-product-price/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_basic_info_insurance_company_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/basic-info/insurance-company/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_finance_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_sample_reception_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/sample-reception/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -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_pilot_service_project_price_system_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/project-price-system/index.vue", "source_location": "L1"}, {"id": "project_price_system_index_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/project-price-system/index.vue", "source_location": "L497"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_project_price_system_index_vue", "target": "project_price_system_index_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/project-price-system/index.vue", "source_location": "L497", "weight": 1.0}], "raw_calls": [{"caller_nid": "project_price_system_index_if", "callee": "fetchDeleteProjectSystemItem", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/project-price-system/index.vue", "source_location": "L498"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_payment_info_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-info/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1"}, {"id": "qc_work_order_index_formatconfiguredlabitems", "label": "formatConfiguredLabItems()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L713"}, {"id": "qc_work_order_index_formatconfiguredthirditems", "label": "formatConfiguredThirdItems()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L719"}, {"id": "qc_work_order_index_buildtasktypesections", "label": "buildTaskTypeSections()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L727"}, {"id": "qc_work_order_index_buildconfiguredonlysection", "label": "buildConfiguredOnlySection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L786"}, {"id": "qc_work_order_index_formatdetectmethods", "label": "formatDetectMethods()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L804"}, {"id": "qc_work_order_index_formatmetric", "label": "formatMetric()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L811"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_formatconfiguredlabitems", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L713", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_formatconfiguredthirditems", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L719", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_buildtasktypesections", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L727", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_buildconfiguredonlysection", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L786", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_formatdetectmethods", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L804", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_formatmetric", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L811", "weight": 1.0}], "raw_calls": [{"caller_nid": "qc_work_order_index_formatconfiguredlabitems", "callee": "join", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L715"}, {"caller_nid": "qc_work_order_index_formatconfiguredlabitems", "callee": "map", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L715"}, {"caller_nid": "qc_work_order_index_formatconfiguredthirditems", "callee": "join", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L721"}, {"caller_nid": "qc_work_order_index_formatconfiguredthirditems", "callee": "map", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L721"}, {"caller_nid": "qc_work_order_index_Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_components_common_amount_input_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L1"}, {"id": "amount_input_index_handlefocus", "label": "handleFocus()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L60"}, {"id": "amount_input_index_handleinput", "label": "handleInput()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L65"}, {"id": "amount_input_index_handleblur", "label": "handleBlur()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L69"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_common_amount_input_index_vue", "target": "amount_input_index_handlefocus", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L60", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_common_amount_input_index_vue", "target": "amount_input_index_handleinput", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L65", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_components_common_amount_input_index_vue", "target": "amount_input_index_handleblur", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L69", "weight": 1.0}], "raw_calls": [{"caller_nid": "amount_input_index_handlefocus", "callee": "sanitizeMoneyInput", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L62"}, {"caller_nid": "amount_input_index_handleinput", "callee": "sanitizeMoneyInput", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L66"}, {"caller_nid": "amount_input_index_handleblur", "callee": "parseMoneyToNumber", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L71"}, {"caller_nid": "amount_input_index_handleblur", "callee": "emit", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L76"}, {"caller_nid": "amount_input_index_handleblur", "callee": "emit", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L77"}, {"caller_nid": "amount_input_index_handleblur", "callee": "formatMoneyDisplay", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue", "source_location": "L78"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_checkup_institution_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-institution/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_work_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-work-order/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_finance_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L1"}, {"id": "channel_service_order_finance_index_txnamountlabel", "label": "txnAmountLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L416"}, {"id": "channel_service_order_finance_index_financesubmitremarkdisplay", "label": "financeSubmitRemarkDisplay()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L424"}, {"id": "channel_service_order_finance_index_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L430"}, {"id": "channel_service_order_finance_index_isimagefile", "label": "isImageFile()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L437"}, {"id": "channel_service_order_finance_index_isvideofile", "label": "isVideoFile()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L447"}, {"id": "channel_service_order_finance_index_formatlocaldate", "label": "formatLocalDate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L467"}, {"id": "channel_service_order_finance_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L497"}, {"id": "channel_service_order_finance_index_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L522"}, {"id": "channel_service_order_finance_index_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L527"}, {"id": "channel_service_order_finance_index_handletabchange", "label": "handleTabChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L536"}, {"id": "channel_service_order_finance_index_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L638"}, {"id": "channel_service_order_finance_index_openconfirmdialog", "label": "openConfirmDialog()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L667"}, {"id": "channel_service_order_finance_index_submitconfirm", "label": "submitConfirm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L674"}, {"id": "channel_service_order_finance_index_executesubmitconfirm", "label": "executeSubmitConfirm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L683"}, {"id": "channel_service_order_finance_index_handleconfirmattachmentchange", "label": "handleConfirmAttachmentChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L706"}, {"id": "channel_service_order_finance_index_hasuploadingattachments", "label": "hasUploadingAttachments()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L752"}, {"id": "channel_service_order_finance_index_handlepreviewattachment", "label": "handlePreviewAttachment()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L763"}, {"id": "channel_service_order_finance_index_handledownloadattachment", "label": "handleDownloadAttachment()", "file_type": "codeLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_finance_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L1"}, {"id": "channel_service_order_finance_index_txnamountlabel", "label": "txnAmountLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L446"}, {"id": "channel_service_order_finance_index_financesubmitremarkdisplay", "label": "financeSubmitRemarkDisplay()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L454"}, {"id": "channel_service_order_finance_index_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L460"}, {"id": "channel_service_order_finance_index_isimagefile", "label": "isImageFile()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L467"}, {"id": "channel_service_order_finance_index_isvideofile", "label": "isVideoFile()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L477"}, {"id": "channel_service_order_finance_index_formatlocaldate", "label": "formatLocalDate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L497"}, {"id": "channel_service_order_finance_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L528"}, {"id": "channel_service_order_finance_index_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L553"}, {"id": "channel_service_order_finance_index_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L558"}, {"id": "channel_service_order_finance_index_handletabchange", "label": "handleTabChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L567"}, {"id": "channel_service_order_finance_index_handleview", "label": "handleView()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L669"}, {"id": "channel_service_order_finance_index_openconfirmdialog", "label": "openConfirmDialog()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L698"}, {"id": "channel_service_order_finance_index_handlevoidtxn", "label": "handleVoidTxn()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L705"}, {"id": "channel_service_order_finance_index_submitconfirm", "label": "submitConfirm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L723"}, {"id": "channel_service_order_finance_index_executesubmitconfirm", "label": "executeSubmitConfirm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L732"}, {"id": "channel_service_order_finance_index_handleconfirmattachmentchange", "label": "handleConfirmAttachmentChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L755"}, {"id": "channel_service_order_finance_index_hasuploadingattachments", "label": "hasUploadingAttachments()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L801"}, {"id": "channel_service_order_finance_index_handlepreviewattachment", "label": "handlePreviewAttachment()", "file_type": "code", "source_file": "/UsLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_refund_confirm_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/refund-confirm/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxntable_vue", "label": "ServiceOrderTxnTable.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnTable.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_fullmoon_todo_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L1"}, {"id": "fullmoon_todo_index_loaddata", "label": "loadData()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L638"}, {"id": "fullmoon_todo_index_handlesearch", "label": "handleSearch()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L656"}, {"id": "fullmoon_todo_index_handlereset", "label": "handleReset()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L661"}, {"id": "fullmoon_todo_index_formatymdfromany", "label": "formatYmdFromAny()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L669"}, {"id": "fullmoon_todo_index_normalizenewbornsex", "label": "normalizeNewbornSex()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L677"}, {"id": "fullmoon_todo_index_handleexportinsurancesheet", "label": "handleExportInsuranceSheet()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L685"}, {"id": "fullmoon_todo_index_resolveprotocolid", "label": "resolveProtocolId()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L834"}, {"id": "fullmoon_todo_index_resetformfields", "label": "resetFormFields()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L858"}, {"id": "fullmoon_todo_index_resetdialogcontext", "label": "resetDialogContext()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L874"}, {"id": "fullmoon_todo_index_handleinsurancedialogclosed", "label": "handleInsuranceDialogClosed()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L881"}, {"id": "fullmoon_todo_index_parseinsuranceattachmentsfromurls", "label": "parseInsuranceAttachmentsFromUrls()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L885"}, {"id": "fullmoon_todo_index_buildinsuranceattachmentsvalue", "label": "buildInsuranceAttachmentsValue()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L897"}, {"id": "fullmoon_todo_index_buildinsurancepayload", "label": "buildInsurancePayload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L904"}, {"id": "fullmoon_todo_index_handlebatchedit", "label": "handleBatchEdit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L921"}, {"id": "fullmoon_todo_index_handleedit", "label": "handleEdit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L934"}, {"id": "fullmoon_todo_index_handleinsurancecompanychange", "label": "handleInsuranceCompanyChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L957"}, {"id": "fullmoon_todo_index_handleinsurancetypechange", "label": "handleInsuranceTypeChange()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L965"}, {"id": "fullmoon_todo_index_handlesubmit", "label": "handleSubmit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L972"}, {"id": "fullmoon_todo_index_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/fullmoon-todo/index.vue", "source_location": "L1034"}, {"id": "fullmoon_todo_index_isimagefile", "label": "isImageFile()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admiLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_finance_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order-finance/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "label": "ServiceOrderTxnDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L1"}, {"id": "channel_service_order_serviceordertxndialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L494"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "channel_service_order_serviceordertxndialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L494", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "channel_service_order_serviceordertxndialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L501", "weight": 1.0}], "raw_calls": [{"caller_nid": "channel_service_order_serviceordertxndialog_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L495"}, {"caller_nid": "channel_service_order_serviceordertxndialog_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L502"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "label": "ServiceOrderTxnDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L1"}, {"id": "channel_service_order_serviceordertxndialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L519"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "channel_service_order_serviceordertxndialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L519", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "channel_service_order_serviceordertxndialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L526", "weight": 1.0}], "raw_calls": [{"caller_nid": "channel_service_order_serviceordertxndialog_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L520"}, {"caller_nid": "channel_service_order_serviceordertxndialog_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L527"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_system_user_detail_vue", "label": "detail.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/user/detail.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1"}, {"id": "channel_service_order_index_validate", "label": "validate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1268"}, {"id": "channel_service_order_index_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1273"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "target": "channel_service_order_index_validate", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1268", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "target": "channel_service_order_index_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1273", "weight": 1.0}], "raw_calls": [{"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1275"}, {"caller_nid": "channel_service_order_index_if", "callee": "filter", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1278"}, {"caller_nid": "channel_service_order_index_if", "callee": "map", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1278"}, {"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1280"}, {"caller_nid": "channel_service_order_index_if", "callee": "some", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1283"}, {"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1287"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationviewdialog_vue", "label": "DonationViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L1"}, {"id": "list_donationviewdialog_dash", "label": "dash()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L760"}, {"id": "list_donationviewdialog_formatmetric", "label": "formatMetric()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L765"}, {"id": "list_donationviewdialog_formatymd", "label": "formatYmd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L771"}, {"id": "list_donationviewdialog_formatym", "label": "formatYm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L777"}, {"id": "list_donationviewdialog_auditordisplay", "label": "auditorDisplay()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L783"}, {"id": "list_donationviewdialog_sampletypename", "label": "sampleTypeName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L789"}, {"id": "list_donationviewdialog_unitname", "label": "unitName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L793"}, {"id": "list_donationviewdialog_sitename", "label": "siteName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L797"}, {"id": "list_donationviewdialog_expressname", "label": "expressName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L801"}, {"id": "list_donationviewdialog_samplereceptionchecklist", "label": "sampleReceptionCheckList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L805"}, {"id": "list_donationviewdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L827"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationviewdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_money_format", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L584", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationviewdialog_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L585", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationviewdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolattachmentreadonly_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L586", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationviewdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_qc_info_cards_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L587", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_research_donation_list_donationviewdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_business_sample_production_info_cards_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/research-donation/list/DonationViewDialog.vue", "source_location": "L588", Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "label": "production-work-order.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L1"}, {"id": "api_production_work_order_fetchproductionworkorderlist", "label": "fetchProductionWorkOrderList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L24"}, {"id": "api_production_work_order_fetchproductionworkorderdetail", "label": "fetchProductionWorkOrderDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L42"}, {"id": "api_production_work_order_fetchcompleteproductionworkorder", "label": "fetchCompleteProductionWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L46"}, {"id": "api_production_work_order_fetchcreateproductionworkorder", "label": "fetchCreateProductionWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L50"}, {"id": "api_production_work_order_fetchconfigureproductionworkorder", "label": "fetchConfigureProductionWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L63"}, {"id": "api_production_work_order_fetchupdateproductionworkorder", "label": "fetchUpdateProductionWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L79"}, {"id": "api_production_work_order_fetchdeleteproductionworkorder", "label": "fetchDeleteProductionWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L86"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_http", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L2", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchproductionworkorderlist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L24", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchproductionworkorderdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L42", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchcompleteproductionworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L46", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchcreateproductionworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L50", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchconfigureproductionworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L63", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchupdateproductionworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-work-order.ts", "source_location": "L79", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_work_order_ts", "target": "api_production_work_order_fetchdeleteproductioLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1"}, {"id": "channel_service_order_index_validate", "label": "validate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1330"}, {"id": "channel_service_order_index_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1335"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "target": "channel_service_order_index_validate", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1330", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "target": "channel_service_order_index_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1335", "weight": 1.0}], "raw_calls": [{"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1337"}, {"caller_nid": "channel_service_order_index_if", "callee": "filter", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1340"}, {"caller_nid": "channel_service_order_index_if", "callee": "map", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1340"}, {"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1342"}, {"caller_nid": "channel_service_order_index_if", "callee": "some", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1345"}, {"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1349"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "label": "ServiceOrderTxnDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L1"}, {"id": "channel_service_order_serviceordertxndialog_formatamount", "label": "formatAmount()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L181"}, {"id": "channel_service_order_serviceordertxndialog_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L190"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L125", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L126", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolattachmentreadonly_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L127", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_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/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L128", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_download_attachment", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L133", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_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/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L134", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "channel_service_order_serviceordertxndialog_formatamount", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L181", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "channel_service_order_serviceordertxndialog_fullfileurl", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L190", "weight": 1.0}], "raw_calls": [{"caller_nid": "channel_service_order_serviceordertxndialog_formatamount", "callee": "Number", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L183"}, {"caller_nid": "channel_service_order_serviceordertxndialog_formatamount", "callee": "isNaN", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L184"}, {"caller_nid": "channel_service_order_serviceordertxndialog_formatamount", "callee": "toFixed", "source_file": "/Users/wuzilong/work/00code/zkxw/web-aLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "label": "ServiceOrderTxnDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L1"}, {"id": "channel_service_order_serviceordertxndialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L519"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "channel_service_order_serviceordertxndialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L519", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "channel_service_order_serviceordertxndialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L526", "weight": 1.0}], "raw_calls": [{"caller_nid": "channel_service_order_serviceordertxndialog_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L520"}, {"caller_nid": "channel_service_order_serviceordertxndialog_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L527"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_money_format_ts", "label": "money-format.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L1"}, {"id": "utils_money_format_addthousandseparators", "label": "addThousandSeparators()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L7"}, {"id": "utils_money_format_sanitizemoneyinput", "label": "sanitizeMoneyInput()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L22"}, {"id": "utils_money_format_formatmoneydisplay", "label": "formatMoneyDisplay()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L49"}, {"id": "utils_money_format_parsemoneytonumber", "label": "parseMoneyToNumber()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L66"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_money_format_ts", "target": "utils_money_format_addthousandseparators", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L7", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_money_format_ts", "target": "utils_money_format_sanitizemoneyinput", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L22", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_money_format_ts", "target": "utils_money_format_formatmoneydisplay", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L49", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_money_format_ts", "target": "utils_money_format_parsemoneytonumber", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L66", "weight": 1.0}, {"source": "utils_money_format_formatmoneydisplay", "target": "utils_money_format_addthousandseparators", "relation": "calls", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L60", "weight": 1.0}, {"source": "utils_money_format_parsemoneytonumber", "target": "utils_money_format_sanitizemoneyinput", "relation": "calls", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L67", "weight": 1.0}], "raw_calls": [{"caller_nid": "utils_money_format_addthousandseparators", "callee": "startsWith", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L9"}, {"caller_nid": "utils_money_format_addthousandseparators", "callee": "slice", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L10"}, {"caller_nid": "utils_money_format_addthousandseparators", "callee": "max", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L14"}, {"caller_nid": "utils_money_format_addthousandseparators", "callee": "unshift", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L15"}, {"caller_nid": "utils_money_format_addthousandseparators", "callee": "slice", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L15"}, {"caller_nid": "utils_money_format_addthousandseparators", "callee": "join", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L17"}, {"caller_nid": "utils_money_format_sanitizemoneyinput", "callee": "replace", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L25"}, {"caller_nid": "utils_money_format_sanitizemoneyinput", "callee": "replace", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L27"}, {"caller_nid": "utils_money_format_sanitizemoneyinput", "callee": "indexOf", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L29"}, {"caller_nid": "utils_money_format_sanitizemoneyinput", "callee": "slice", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/money-format.ts", "source_location": "L31"}, {"caller_nid": "utils_money_format_sanitizemoneyinput", "callee": "replace", "source_file": "/Users/wuzilong/work/00codLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolformdialog_vue", "label": "ProtocolFormDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1"}, {"id": "protocol_protocolformdialog_fmtmoney", "label": "fmtMoney()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1227"}, {"id": "protocol_protocolformdialog_createemptytransport", "label": "createEmptyTransport()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1291"}, {"id": "protocol_protocolformdialog_fullfileurl", "label": "fullFileUrl()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1311"}, {"id": "protocol_protocolformdialog_loadethnicoptions", "label": "loadEthnicOptions()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1318"}, {"id": "protocol_protocolformdialog_ensureethnicoptioninlist", "label": "ensureEthnicOptionInList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1329"}, {"id": "protocol_protocolformdialog_expressname", "label": "expressName()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1357"}, {"id": "protocol_protocolformdialog_for", "label": "for()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L2025"}, {"id": "protocol_protocolformdialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L2561"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolformdialog_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1177", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolformdialog_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1178", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_collection_protocol", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1190", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_business", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1196", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_download_attachment", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1197", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolformdialog_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/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1198", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolformdialog_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_ethnic", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolFormDialog.vue", "source_location": "L1211", "weight": 1.0}, {"source":Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "label": "ServiceOrderTxnDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L1"}, {"id": "channel_service_order_serviceordertxndialog_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L492"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "channel_service_order_serviceordertxndialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L492", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxndialog_vue", "target": "channel_service_order_serviceordertxndialog_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L499", "weight": 1.0}], "raw_calls": [{"caller_nid": "channel_service_order_serviceordertxndialog_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L493"}, {"caller_nid": "channel_service_order_serviceordertxndialog_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnDialog.vue", "source_location": "L500"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_payment_confirm_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/payment-confirm/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_sample_reception_ts", "label": "sample-reception.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L1"}, {"id": "api_sample_reception_fetchsamplereceptionpendinglist", "label": "fetchSampleReceptionPendingList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L11"}, {"id": "api_sample_reception_fetchsamplereceptionreceivedlist", "label": "fetchSampleReceptionReceivedList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L25"}, {"id": "api_sample_reception_fetchsamplereceptiondetail", "label": "fetchSampleReceptionDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L39"}, {"id": "api_sample_reception_fetchsamplereceptionupdate", "label": "fetchSampleReceptionUpdate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L54"}, {"id": "api_sample_reception_fetchsamplereceptionsubmit", "label": "fetchSampleReceptionSubmit()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L75"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_sample_reception_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_http", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_sample_reception_ts", "target": "api_sample_reception_fetchsamplereceptionpendinglist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L11", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_sample_reception_ts", "target": "api_sample_reception_fetchsamplereceptionreceivedlist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L25", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_sample_reception_ts", "target": "api_sample_reception_fetchsamplereceptiondetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L39", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_sample_reception_ts", "target": "api_sample_reception_fetchsamplereceptionupdate", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L54", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_sample_reception_ts", "target": "api_sample_reception_fetchsamplereceptionsubmit", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L75", "weight": 1.0}], "raw_calls": [{"caller_nid": "api_sample_reception_fetchsamplereceptionpendinglist", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L19"}, {"caller_nid": "api_sample_reception_fetchsamplereceptionreceivedlist", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L33"}, {"caller_nid": "api_sample_reception_fetchsamplereceptiondetail", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L40"}, {"caller_nid": "api_sample_reception_fetchsamplereceptionupdate", "callee": "put", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L69"}, {"caller_nid": "api_sample_reception_fetchsamplereceptionsubmit", "callee": "post", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-reception.ts", "source_location": "L90"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L1"}, {"id": "qc_work_order_index_formatconfiguredlabitems", "label": "formatConfiguredLabItems()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L712"}, {"id": "qc_work_order_index_formatconfiguredthirditems", "label": "formatConfiguredThirdItems()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L718"}, {"id": "qc_work_order_index_buildtasktypesections", "label": "buildTaskTypeSections()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L726"}, {"id": "qc_work_order_index_buildconfiguredonlysection", "label": "buildConfiguredOnlySection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L785"}, {"id": "qc_work_order_index_formatdetectmethods", "label": "formatDetectMethods()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L803"}, {"id": "qc_work_order_index_formatmetric", "label": "formatMetric()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L810"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_formatconfiguredlabitems", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L712", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_formatconfiguredthirditems", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L718", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_buildtasktypesections", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L726", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_buildconfiguredonlysection", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L785", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_formatdetectmethods", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L803", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_work_order_index_vue", "target": "qc_work_order_index_formatmetric", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L810", "weight": 1.0}], "raw_calls": [{"caller_nid": "qc_work_order_index_formatconfiguredlabitems", "callee": "join", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L714"}, {"caller_nid": "qc_work_order_index_formatconfiguredlabitems", "callee": "map", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L714"}, {"caller_nid": "qc_work_order_index_formatconfiguredthirditems", "callee": "join", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L720"}, {"caller_nid": "qc_work_order_index_formatconfiguredthirditems", "callee": "map", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-work-order/index.vue", "source_location": "L720"}, {"caller_nid": "qc_work_order_index_Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1"}, {"id": "channel_service_order_index_validate", "label": "validate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1297"}, {"id": "channel_service_order_index_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1302"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "target": "channel_service_order_index_validate", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1297", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "target": "channel_service_order_index_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1302", "weight": 1.0}], "raw_calls": [{"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1304"}, {"caller_nid": "channel_service_order_index_if", "callee": "filter", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1307"}, {"caller_nid": "channel_service_order_index_if", "callee": "map", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1307"}, {"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1309"}, {"caller_nid": "channel_service_order_index_if", "callee": "some", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1312"}, {"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1316"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_channelviewdialog_vue", "label": "ChannelViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/ChannelViewDialog.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_serviceordertxntable_vue", "label": "ServiceOrderTxnTable.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/ServiceOrderTxnTable.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task_ts", "label": "production-task.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L1"}, {"id": "api_production_task_fetchcreateproductiontask", "label": "fetchCreateProductionTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L3"}, {"id": "api_production_task_fetchproductiontasklist", "label": "fetchProductionTaskList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L7"}, {"id": "api_production_task_fetchproductiontaskdetail", "label": "fetchProductionTaskDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L25"}, {"id": "api_production_task_fetchupdateproductiontask", "label": "fetchUpdateProductionTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L29"}, {"id": "api_production_task_fetchupdateproductiontaskstatus", "label": "fetchUpdateProductionTaskStatus()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L33"}, {"id": "api_production_task_fetchdeleteproductiontask", "label": "fetchDeleteProductionTask()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L37"}, {"id": "api_production_task_fetchaddtaskstep", "label": "fetchAddTaskStep()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L41"}, {"id": "api_production_task_fetchupdatetaskstep", "label": "fetchUpdateTaskStep()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L45"}, {"id": "api_production_task_fetchdeletetaskstep", "label": "fetchDeleteTaskStep()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L49"}, {"id": "api_production_task_fetchreplacestepreagents", "label": "fetchReplaceStepReagents()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L53"}, {"id": "api_production_task_fetchreplacestepconsumables", "label": "fetchReplaceStepConsumables()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L60"}, {"id": "api_production_task_fetchreplacestepdatacollection", "label": "fetchReplaceStepDataCollection()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L67"}, {"id": "api_production_task_fetchsettaskinputs", "label": "fetchSetTaskInputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L74"}, {"id": "api_production_task_fetchsettaskoutputs", "label": "fetchSetTaskOutputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L78"}, {"id": "api_production_task_fetchreordertasksteps", "label": "fetchReorderTaskSteps()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L82"}, {"id": "api_production_task_fetchcopytaskstep", "label": "fetchCopyTaskStep()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L86"}, {"id": "api_production_task_fetchreplacestepoutputs", "label": "fetchReplaceStepOutputs()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L93"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_http", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task_ts", "target": "api_production_task_fetchcreateproductiontask", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/production-task.ts", "source_location": "L3", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_production_task_ts", "target": "api_production_task_fetchproductiontasklist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_task_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L1"}, {"id": "qc_task_index_canfillresult", "label": "canFillResult()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L543"}, {"id": "qc_task_index_clearmaterialrow", "label": "clearMaterialRow()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L565"}, {"id": "qc_task_index_ismaterialoptiondisabled", "label": "isMaterialOptionDisabled()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L572"}, {"id": "qc_task_index_isduplicatematerial", "label": "isDuplicateMaterial()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L577"}, {"id": "qc_task_index_handlereceptionattachmentdownload", "label": "handleReceptionAttachmentDownload()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L724"}, {"id": "qc_task_index_normalizeresultparams", "label": "normalizeResultParams()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L728"}, {"id": "qc_task_index_toresultnumber", "label": "toResultNumber()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L736"}, {"id": "qc_task_index_setresultnumber", "label": "setResultNumber()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L742"}, {"id": "qc_task_index_hasresultvalue", "label": "hasResultValue()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L746"}, {"id": "qc_task_index_formatmetric", "label": "formatMetric()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L750"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_task_index_vue", "target": "qc_task_index_canfillresult", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L543", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_task_index_vue", "target": "qc_task_index_clearmaterialrow", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L565", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_task_index_vue", "target": "qc_task_index_ismaterialoptiondisabled", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L572", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_task_index_vue", "target": "qc_task_index_isduplicatematerial", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L577", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_task_index_vue", "target": "qc_task_index_handlereceptionattachmentdownload", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L724", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_task_index_vue", "target": "qc_task_index_normalizeresultparams", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/qc-task/index.vue", "source_location": "L728", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_qc_task_index_vue", "target": "qc_task_index_toresultnumber", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/Line truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "label": "qc-work-order.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L1"}, {"id": "api_qc_work_order_fetchqcworkorderlist", "label": "fetchQcWorkOrderList()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L113"}, {"id": "api_qc_work_order_fetchqcworkorderdetail", "label": "fetchQcWorkOrderDetail()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L128"}, {"id": "api_qc_work_order_fetchconfigureqcworkorder", "label": "fetchConfigureQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L134"}, {"id": "api_qc_work_order_fetchcreateqcworkorder", "label": "fetchCreateQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L149"}, {"id": "api_qc_work_order_fetchupdateqcworkorder", "label": "fetchUpdateQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L164"}, {"id": "api_qc_work_order_fetchdeleteqcworkorder", "label": "fetchDeleteQcWorkOrder()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L171"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_http", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L1", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchqcworkorderlist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L113", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchqcworkorderdetail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L128", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchconfigureqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L134", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchcreateqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L149", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchupdateqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L164", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_api_qc_work_order_ts", "target": "api_qc_work_order_fetchdeleteqcworkorder", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L171", "weight": 1.0}], "raw_calls": [{"caller_nid": "api_qc_work_order_fetchqcworkorderlist", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L122"}, {"caller_nid": "api_qc_work_order_fetchqcworkorderdetail", "callee": "get", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L129"}, {"caller_nid": "api_qc_work_order_fetchconfigureqcworkorder", "callee": "post", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L143"}, {"caller_nid": "api_qc_work_order_fetchcreateqcworkorder", "callee": "post", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L158"}, {"caller_nid": "api_qc_work_order_fetchupdateqcworkorder", "callee": "put", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L165"}, {"caller_nid": "api_qc_work_order_fetchdeleteqcworkorder", "callee": "del", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-work-order.ts", "source_location": "L172"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_types_import_components_d_ts", "label": "components.d.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_router_modules_sqxp_ts", "label": "sqxp.ts", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/sqxp.ts", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_router_modules_sqxp_ts", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_types_router", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/router/modules/sqxp.ts", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_production_production_task_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/production-task/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1"}, {"id": "channel_service_order_index_validate", "label": "validate()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1236"}, {"id": "channel_service_order_index_if", "label": "if()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1241"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "target": "channel_service_order_index_validate", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1236", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_service_order_index_vue", "target": "channel_service_order_index_if", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1241", "weight": 1.0}], "raw_calls": [{"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1243"}, {"caller_nid": "channel_service_order_index_if", "callee": "filter", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1246"}, {"caller_nid": "channel_service_order_index_if", "callee": "map", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1246"}, {"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1248"}, {"caller_nid": "channel_service_order_index_if", "callee": "some", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1251"}, {"caller_nid": "channel_service_order_index_if", "callee": "warning", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel-service-order/index.vue", "source_location": "L1255"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_quality_inspection_third_party_company_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/quality-inspection/third-party-company/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_cell_storage_protocol_protocolviewdialog_vue", "label": "ProtocolViewDialog.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1"}, {"id": "protocol_protocolviewdialog_fullmoontodostatuslabel", "label": "fullmoonTodoStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1346"}, {"id": "protocol_protocolviewdialog_fullmoontodostatustagtype", "label": "fullmoonTodoStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1350"}, {"id": "protocol_protocolviewdialog_insurancesubscribedlabel", "label": "insuranceSubscribedLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1354"}, {"id": "protocol_protocolviewdialog_insurancesubscribedtagtype", "label": "insuranceSubscribedTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1358"}, {"id": "protocol_protocolviewdialog_fmtmoney", "label": "fmtMoney()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1363"}, {"id": "protocol_protocolviewdialog_storagecertmakestatuslabel", "label": "storageCertMakeStatusLabel()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1368"}, {"id": "protocol_protocolviewdialog_storagecertmakestatustagtype", "label": "storageCertMakeStatusTagType()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1372"}, {"id": "protocol_protocolviewdialog_dash", "label": "dash()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1431"}, {"id": "protocol_protocolviewdialog_formatmetric", "label": "formatMetric()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1436"}, {"id": "protocol_protocolviewdialog_formatymd", "label": "formatYmd()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1442"}, {"id": "protocol_protocolviewdialog_formatym", "label": "formatYm()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1448"}, {"id": "protocol_protocolviewdialog_paydetailcolorclass", "label": "payDetailColorClass()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1454"}, {"id": "protocol_protocolviewdialog_isreceiptfinanceconfirmed", "label": "isReceiptFinanceConfirmed()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1462"}, {"id": "protocol_protocolviewdialog_financeconfirmattachmentfiles", "label": "financeConfirmAttachmentFiles()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1722"}, {"id": "protocol_protocolviewdialog_refundattachmentfiles", "label": "refundAttachmentFiles()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1729"}, {"id": "protocol_protocolviewdialog_refundfinanceconfirmattachmentfiles", "label": "refundFinanceConfirmAttachmentFiles()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1736"}, {"id": "protocol_protocolviewdialog_hasfinanceconfirmattachments", "label": "hasFinanceConfirmAttachments()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_location": "L1760"}, {"id": "protocol_protocolviewdialog_hasrefundapplyinfo", "label": "hasRefundApplyInfo()", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/cell-storage/protocol/ProtocolViewDialog.vue", "source_locationLine truncated
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_checkup_institution_checkuppackagepanel_vue", "label": "CheckupPackagePanel.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/checkup-institution/CheckupPackagePanel.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_system_order_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/order/index.vue", "source_location": "L1"}], "edges": [], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_index_vue", "label": "index.vue", "file_type": "code", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue", "source_location": "L1"}], "edges": [{"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_index_vue", "target": "element_plus", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue", "source_location": "L1025", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_index_vue", "target": "icons_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue", "source_location": "L1026", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_channelviewdialog_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue", "source_location": "L1027", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_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/pilot-service/channel/index.vue", "source_location": "L1028", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_api_business", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue", "source_location": "L1029", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_download_attachment", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue", "source_location": "L1030", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_components_common_amount_input_index_vue", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue", "source_location": "L1031", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_index_vue", "target": "users_wuzilong_work_00code_zkxw_web_admin_src_utils_money_format", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/pilot-service/channel/index.vue", "source_location": "L1032", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_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/pilot-service/channel/index.vue", "source_location": "L1033", "weight": 1.0}, {"source": "users_wuzilong_work_00code_zkxw_web_admin_src_views_pilot_service_channel_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/pilot-service/channel/index.vue", "source_location": "L1046", "weight": 1.0}], "raw_calls": []}
+73
View File
@@ -0,0 +1,73 @@
/**
* 金额格式化工具模块
* 提供千分位分隔、输入清洗、展示格式化、数值解析等功能
*/
/** 字符串分段拼接千分位,禁止使用前瞻正则 */
export function addThousandSeparators(intStr: string): string {
if (!intStr) return ''
const isNegative = intStr.startsWith('-')
const absStr = isNegative ? intStr.slice(1) : intStr
const parts: string[] = []
const len = absStr.length
for (let i = len; i > 0; i -= 3) {
const start = Math.max(0, i - 3)
parts.unshift(absStr.slice(start, i))
}
const result = parts.join(',')
return isNegative ? `-${result}` : result
}
/** 输入清洗:去逗号、仅保留数字与一个点、截断小数位 */
export function sanitizeMoneyInput(value: string, precision = 2): string {
if (!value) return ''
// 去逗号
let cleaned = value.replace(/,/g, '')
// 去非数字非点字符
cleaned = cleaned.replace(/[^0-9.]/g, '')
// 只保留第一个小数点
const dotIndex = cleaned.indexOf('.')
if (dotIndex !== -1) {
const intPart = cleaned.slice(0, dotIndex + 1)
const decPart = cleaned.slice(dotIndex + 1).replace(/\./g, '')
cleaned = intPart + decPart
}
// 截断小数到 precision 位
if (dotIndex !== -1) {
const dotIdx = cleaned.indexOf('.')
const intPart = cleaned.slice(0, dotIdx + 1)
let decPart = cleaned.slice(dotIdx + 1)
if (decPart.length > precision) {
decPart = decPart.slice(0, precision)
}
cleaned = intPart + decPart
}
return cleaned
}
/** 展示:整数部分千分位 + 最多 precision 位小数 */
export function formatMoneyDisplay(
value: string | number | null | undefined,
precision = 2
): string {
if (value === null || value === undefined || value === '') return '0.00'
const num = typeof value === 'string' ? parseFloat(value) : value
if (isNaN(num)) return '0.00'
const isNegative = num < 0
const absNum = Math.abs(num)
const fixed = absNum.toFixed(precision)
const [intStr, decStr] = fixed.split('.')
const formatted = addThousandSeparators(intStr)
const result = `${formatted}.${decStr}`
return isNegative ? `-${result}` : result
}
/** 提交:number | null;空串 / 仅 '.' → null */
export function parseMoneyToNumber(value: string, precision = 2): number | null {
const sanitized = sanitizeMoneyInput(value, precision)
if (!sanitized || sanitized === '.') return null
const num = Number(sanitized)
if (isNaN(num)) return null
const factor = Math.pow(10, precision)
return Math.round(num * factor) / factor
}
@@ -200,7 +200,7 @@
<el-table-column type="index" label="序号" min-width="68" align="center" header-align="center" />
<el-table-column prop="projectName" label="险种名称" min-width="160" align="center" header-align="center" />
<el-table-column prop="projectFee" label="险种费用(元)" min-width="120" align="center" header-align="center">
<template #default="{ row }">{{ row.projectFee != null ? `¥${row.projectFee}` : '—' }}</template>
<template #default="{ row }">{{ row.projectFee != null ? '¥' + formatMoneyDisplay(row.projectFee) : '—' }}</template>
</el-table-column>
<el-table-column prop="status" label="状态" min-width="90" align="center" header-align="center">
<template #default="{ row }">
@@ -245,7 +245,7 @@
<el-input v-model="itemForm.projectName" placeholder="请输入险种名称" />
</el-form-item>
<el-form-item label="险种费用(元)" prop="projectFee">
<el-input-number v-model="itemForm.projectFee" :min="0" :precision="2" style="width: 100%" />
<AmountInput v-model="itemForm.projectFee" :min="0" placeholder="请输入项目费用" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="itemForm.status">
@@ -305,6 +305,8 @@
fetchDeleteInsuranceProjectPrice
} from '@/api/admin'
import { withFullscreenLoading, fullscreenLoadingText } from '@/utils/fullscreen-loading'
import AmountInput from '@/components/common/amount-input/index.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
defineOptions({ name: 'BasicInfoInsuranceCompany' })
@@ -297,11 +297,10 @@
<el-input v-model="formData.insurancePolicyNo" placeholder="请输入保险单号" />
</el-form-item>
<el-form-item label="保单费用(元)">
<el-input-number
<AmountInput
v-model="formData.insuranceFee"
:precision="2"
:min="0"
style="width: 100%"
placeholder="请输入保单费用"
/>
</el-form-item>
<el-form-item label="保险单生效时间">
@@ -415,7 +414,7 @@
</div>
</div>
<span class="upload-hint"
>支持图片、视频、PDF、Word、Excel等文件,单文件不超过 20MB</span
>支持图片、视频、PDF、Word、Excel等文件</span
>
</div>
</el-form-item>
@@ -474,6 +473,7 @@
Delete
} from '@element-plus/icons-vue'
import ProtocolViewDialog from '../protocol/ProtocolViewDialog.vue'
import AmountInput from '@/components/common/amount-input/index.vue'
import {
fetchCollectionProtocolDetail,
type CollectionProtocolRow
@@ -1062,13 +1062,6 @@
const file = uploadFile.raw || uploadFile
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
attachmentUploadRef.value?.clearFiles()
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
formData.attachments.push({
id: tempId,
@@ -285,16 +285,21 @@
import { maskIdCard } from '@/utils/mask-sensitive'
import { downloadAttachmentFile } from '@/utils/download-attachment'
import {
formatPaymentAmount,
formatPaymentDueDate,
payModeLabel,
protocolStatusLabel,
protocolStatusTagType,
transferTypeLabel
} from '@/utils/protocol-payment-labels'
import { formatMoneyDisplay } from '@/utils/money-format'
defineOptions({ name: 'CellStoragePaymentConfirm' })
function formatPaymentAmount(v: unknown): string {
if (v == null || v === '') return '-'
return '¥' + formatMoneyDisplay(v)
}
function formatLocalDate(d: Date): string {
const y = d.getFullYear()
const m = String(d.getMonth() + 1).padStart(2, '0')
@@ -332,13 +332,11 @@
>
<div class="form-grid-2">
<el-form-item label="退费金额(元)" prop="refundAmount" class="form-col-span-2">
<el-input-number
<AmountInput
v-model="refundForm.refundAmount"
:min="0.01"
:precision="2"
:step="100"
controls-position="right"
style="width: 100%"
placeholder="请输入退费金额"
/>
</el-form-item>
<el-form-item label="退费备注" prop="refundRemark" class="form-col-span-2">
@@ -447,6 +445,8 @@
import { fetchUploadAttachment } from '@/api/business'
import { maskIdCard } from '@/utils/mask-sensitive'
import { isPaymentDueWithinWarnWindow } from '@/utils/protocol-payment-labels'
import AmountInput from '@/components/common/amount-input/index.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
import {
protocolStatusLabel,
protocolStatusTagType,
@@ -544,11 +544,9 @@
return isPaymentDueWithinWarnWindow(row.installmentDueDate) ? 'row-due-soon' : ''
}
function formatAmount(v: unknown) {
function formatAmount(v: unknown): string {
if (v == null || v === '') return '-'
const n = Number(v)
if (Number.isNaN(n)) return String(v)
return '¥' + n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
return '¥' + formatMoneyDisplay(v)
}
async function loadData() {
@@ -668,11 +666,6 @@
async function handleRefundAttachmentChange(uploadFile: { raw?: File }) {
const file = uploadFile.raw
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
return
}
const tempId = `temp_${Date.now()}`
refundForm.attachments.push({
id: tempId,
@@ -188,7 +188,7 @@
</div>
</div>
<span class="upload-hint"
>支持图片、视频、PDF、Word、Excel等文件,单文件不超过 20MB</span
>支持图片、视频、PDF、Word、Excel等文件</span
>
</div>
</el-form-item>
@@ -585,12 +585,10 @@
</el-select>
</el-form-item>
<el-form-item label="价格(元)">
<el-input
<AmountInput
v-model="row.price"
type="number"
step="any"
:min="0"
style="width: 100%"
placeholder="请输入价格"
@change="onSamplePriceChange"
/>
</el-form-item>
@@ -844,7 +842,7 @@
class="detail-amount"
:class="detail.payStatus === 'yjf' ? 'green' : 'amber'"
>
¥{{ detail.dueAmount }}
{{ fmtMoney(detail.dueAmount) }}
</span>
<span
v-if="detail.payStatus"
@@ -896,12 +894,10 @@
</el-select>
</el-form-item>
<el-form-item label="转账金额(元)">
<el-input
<AmountInput
v-model="detail.transferAmount"
type="number"
step="any"
:min="0"
style="width: 100%"
placeholder="请输入转账金额"
/>
</el-form-item>
<el-form-item label="转账时间">
@@ -1010,7 +1006,7 @@
</div>
</div>
<span class="upload-hint"
>支持图片、视频、PDF、Word、Excel等文件,单文件不超过 20MB</span
>支持图片、视频、PDF、Word、Excel等文件</span
>
</div>
</div>
@@ -1215,6 +1211,8 @@
import { fetchEthnicList, type EthnicOption } from '@/api/ethnic'
import { useUserStore } from '@/store/modules/user'
import { syncFqPaymentDetailRowCount } from '@/utils/protocol-payment-installment'
import AmountInput from '@/components/common/amount-input/index.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
import {
payModeLabel,
newbornSexLabel,
@@ -1225,6 +1223,12 @@
payStatusLabel
} from '@/utils/status-tag-registry'
/** 金额只读展示:千分位 + ¥ 前缀 */
function fmtMoney(v: unknown): string {
if (v == null || v === '') return '—'
return '¥' + formatMoneyDisplay(v)
}
const userStore = useUserStore()
const customerId = ref<string | null>(null)
@@ -2738,13 +2742,6 @@
const file = uploadFile.raw || uploadFile
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
attachmentUploadRef.value?.clearFiles()
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
formData.attachments.push({
id: tempId,
@@ -2789,11 +2786,6 @@
const file = uploadFile.raw || uploadFile
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
return
}
const detail = formData.paymentDetails[detailIndex]
if (!detail) return
@@ -454,7 +454,7 @@
<div class="data-item"
><div class="data-label">保单费用(元)</div
><div class="data-value">{{
formatMoney(fullmoonInsuranceInfo?.insuranceFee)
fmtMoney(fullmoonInsuranceInfo?.insuranceFee)
}}</div></div
>
<div class="data-item"
@@ -722,13 +722,13 @@
<div class="payment-metric"
><div class="pm-label">合同金额(元)</div
><div class="pm-value pm-value--amount">{{
payment?.contractAmount ? `¥${payment.contractAmount}` : '—'
fmtMoney(payment?.contractAmount)
}}</div></div
>
<div class="payment-metric"
><div class="pm-label">已收金额(元)</div
><div class="pm-value pm-value--amount pm-value--received">{{
receivedAmount ? `¥${receivedAmount}` : '—'
fmtMoney(receivedAmount)
}}</div></div
>
<template v-if="payment?.payMode === 'dj'">
@@ -775,7 +775,7 @@
class="pdc-header-amount"
:class="payDetailColorClass(String(detail.payStatus || ''))"
>
{{ detail.dueAmount ? `¥${detail.dueAmount}` : '—' }}
{{ fmtMoney(detail.dueAmount) }}
</span>
</div>
<el-tag :type="payStatusTagType(String(detail.payStatus || ''))" size="small">
@@ -788,7 +788,7 @@
<div class="pdc-info-item">
<span class="info-label">应缴费金额(元)</span>
<span class="info-value">{{
detail.dueAmount ? `¥${detail.dueAmount}` : '—'
fmtMoney(detail.dueAmount)
}}</span>
</div>
<div class="pdc-info-item">
@@ -800,7 +800,7 @@
<div class="pdc-info-item">
<span class="info-label">转账金额(元)</span>
<span class="info-value">{{
detail.transferAmount ? `¥${detail.transferAmount}` : '—'
fmtMoney(detail.transferAmount)
}}</span>
</div>
<div class="pdc-info-item">
@@ -951,7 +951,7 @@
<span
class="flow-detail-card__value"
:class="payDetailColorClass(String(detail.payStatus || ''))"
>{{ detail.refundAmount ? `¥${detail.refundAmount}` : '—' }}</span
>{{ fmtMoney(detail.refundAmount) }}</span
>
</div>
<div
@@ -1172,6 +1172,7 @@
fetchUserList
} from '@/api/admin'
import { downloadAttachmentFile } from '@/utils/download-attachment'
import { formatMoneyDisplay } from '@/utils/money-format'
import {
protocolStatusLabel,
protocolStatusTagType,
@@ -1358,11 +1359,10 @@
return val === '1' ? 'success' : 'info'
}
function formatMoney(val: unknown) {
if (val === null || val === undefined || val === '') return '—'
const n = Number(val)
if (Number.isNaN(n)) return String(val)
return `¥${n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
/** 金额只读展示:千分位 + ¥ 前缀,null 显示 — */
function fmtMoney(v: unknown): string {
if (v == null || v === '') return '—'
return '¥' + formatMoneyDisplay(v)
}
function storageCertMakeStatusLabel(makeStatus: string) {
@@ -302,16 +302,21 @@
import { maskIdCard } from '@/utils/mask-sensitive'
import { downloadAttachmentFile } from '@/utils/download-attachment'
import {
formatPaymentAmount,
formatPaymentDueDate,
payModeLabel,
protocolStatusLabel,
protocolStatusTagType,
transferTypeLabel
} from '@/utils/protocol-payment-labels'
import { formatMoneyDisplay } from '@/utils/money-format'
defineOptions({ name: 'CellStorageRefundConfirm' })
function formatPaymentAmount(v: unknown): string {
if (v == null || v === '') return '-'
return '¥' + formatMoneyDisplay(v)
}
function formatLocalDate(d: Date): string {
const y = d.getFullYear()
const m = String(d.getMonth() + 1).padStart(2, '0')
@@ -221,7 +221,7 @@
</div>
</div>
</div>
<span class="upload-hint">支持图片、视频、PDF、Word、Excel等文件,单文件不超过 20MB</span>
<span class="upload-hint">支持图片、视频、PDF、Word、Excel等文件</span>
</div>
</el-form-item>
<div class="form-grid-2">
@@ -504,13 +504,6 @@
const file = uploadFile.raw || uploadFile
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
certAttachmentUploadRef.value?.clearFiles()
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
certAttachments.value.push({
id: tempId,
@@ -74,7 +74,7 @@
<el-table-column prop="specText" label="规格" min-width="120" align="center" header-align="center" />
<el-table-column prop="unitPrice" label="单价" min-width="100" align="center" header-align="center">
<template #default="{ row }">
{{ row.unitPrice != null ? `${row.unitPrice} 元` : '-' }}
{{ row.unitPrice != null ? `${formatMoneyDisplay(row.unitPrice)} 元` : '-' }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" min-width="150" align="center" header-align="center" />
@@ -164,13 +164,10 @@
</el-select>
</el-form-item>
<el-form-item label="单价(元)" prop="unitPrice">
<el-input-number
<AmountInput
v-model="formData.unitPrice"
:precision="2"
:min="0"
:controls="false"
placeholder="请输入单价"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="备注">
@@ -207,6 +204,8 @@
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Close, Check, View, Edit, Delete, ScaleToOriginal, RefreshLeft, Search } from '@element-plus/icons-vue'
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
import AmountInput from '@/components/common/amount-input/index.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
import { withFullscreenLoading, fullscreenLoadingText } from '@/utils/fullscreen-loading'
import {
fetchCellProductPriceList,
@@ -279,7 +278,7 @@
{ label: '项目编码', value: row.projectCode },
{ label: '细胞类型名称', value: row.cellTypeName },
{ label: '规格', value: row.specText },
{ label: '单价(元)', value: row.unitPrice != null ? row.unitPrice : '-' },
{ label: '单价(元)', value: row.unitPrice != null ? `${formatMoneyDisplay(row.unitPrice)} 元` : '-' },
{ label: '备注', value: row.remark, span: true }
]
}
@@ -19,7 +19,11 @@
<div class="filter-block">
<el-form :model="searchForm" class="filter-form" label-position="top" @submit.prevent>
<p class="filter-hint">
{{ activeTab === 'pending' ? '展示待确认的流水记录。' : '展示已确认的流水记录。' }}
{{
activeTab === 'pending'
? '展示待确认的流水记录。'
: '展示财务已确认或财务作废的流水记录。'
}}
</p>
<div class="filter-grid">
<el-form-item label="渠道名称">
@@ -99,21 +103,61 @@
</template>
</el-table-column>
<el-table-column prop="channelName" label="渠道名称" min-width="160" show-overflow-tooltip />
<el-table-column prop="remark" label="备注" min-width="180" show-overflow-tooltip />
<el-table-column prop="remark" label="备注" min-width="160" show-overflow-tooltip />
<el-table-column prop="createTime" label="创建时间" min-width="170" align="center" />
<el-table-column label="操作" min-width="200" fixed="right" align="center" header-align="center">
<template v-if="activeTab === 'done'">
<el-table-column label="财务操作" min-width="110" align="center">
<template #default="{ row }">
<el-tag
v-if="row.financeOperateTypeLabel"
:type="row.financeOperateType === 'void' ? 'info' : 'success'"
size="small"
>
{{ row.financeOperateTypeLabel }}
</el-tag>
<span v-else class="text-muted">—</span>
</template>
</el-table-column>
<el-table-column label="操作人" min-width="120" show-overflow-tooltip>
<template #default="{ row }">
{{ row.financeOperateByName || '—' }}
</template>
</el-table-column>
<el-table-column label="操作时间" min-width="170" align="center">
<template #default="{ row }">
{{ row.financeOperateTime || '—' }}
</template>
</el-table-column>
</template>
<el-table-column label="操作" min-width="300" fixed="right" align="center" header-align="center">
<template #default="{ row }">
<el-button class="btn-op-item" @click="handleView(row)">
<el-icon><View /></el-icon>查看
</el-button>
<el-button
v-if="row.txnStatus === 'dqr'"
class="btn-op-item primary"
type="primary"
@click="openConfirmDialog(row)"
>
确认
</el-button>
<template v-if="row.txnStatus === 'dqr'">
<el-button
class="btn-op-item primary"
type="primary"
@click="openConfirmDialog(row)"
>
<el-icon><Check /></el-icon>确认
</el-button>
<el-popconfirm
title="确定作废该流水吗?作废后不可恢复,业务需重新发起。"
confirm-button-text="确定"
cancel-button-text="取消"
@confirm="handleVoidTxn(row)"
>
<template #reference>
<el-button
class="btn-op-item op-warn"
:loading="voidTxnId === row.id"
>
<el-icon><Delete /></el-icon>作废
</el-button>
</template>
</el-popconfirm>
</template>
</template>
</el-table-column>
</el-table>
@@ -215,7 +259,7 @@
</el-tag>
</div>
<div class="view-field-row">
<span class="view-field-label">金额:</span>
<span class="view-field-label">{{ txnAmountLabel(currentRow.txnType) }}:</span>
<span class="amount-text">¥{{ formatAmount(currentRow.amount) }}</span>
</div>
<div class="view-field-row" v-if="currentRow.financeSubmitByName || currentRow.financeSubmitBy">
@@ -226,9 +270,9 @@
<span class="view-field-label">提交时间:</span>
<span class="view-field-text">{{ currentRow.financeSubmitTime }}</span>
</div>
<div class="view-field-row" v-if="currentRow.financeSubmitRemark">
<div class="view-field-row" v-if="financeSubmitRemarkDisplay(currentRow)">
<span class="view-field-label">备注:</span>
<span class="view-field-text">{{ currentRow.financeSubmitRemark }}</span>
<span class="view-field-text">{{ financeSubmitRemarkDisplay(currentRow) }}</span>
</div>
</div>
@@ -240,61 +284,124 @@
<el-form-item label="财务备注">
<el-input v-model="confirmForm.remark" type="textarea" :rows="3" placeholder="请输入备注" />
</el-form-item>
<el-form-item label="确认凭证">
<el-form-item label="确认凭证" class="form-col-span-2">
<div class="attachment-upload">
<div class="upload-cards-row">
<div
v-for="(file, index) in confirmForm.attachments"
:key="file.id"
class="upload-card uploaded"
>
<img
v-if="isImageFile(file) && file.fileUrl"
:src="fullFileUrl(file.fileUrl)"
class="upload-card-preview"
@click="handlePreviewAttachment(file)"
/>
<div v-else class="upload-card-file">
<el-icon size="24"><Document /></el-icon>
<span class="upload-card-filename">{{ file.fileName }}</span>
</div>
<div class="upload-card-actions">
<el-button size="small" link @click="handlePreviewAttachment(file)">
<el-icon><View /></el-icon>
</el-button>
<el-button size="small" link @click="handleDownloadAttachment(file)">
<el-icon><Download /></el-icon>
</el-button>
<el-button
size="small"
link
type="danger"
@click="confirmForm.attachments.splice(index, 1)"
>
<el-icon><Delete /></el-icon>
</el-button>
</div>
</div>
<div class="attachment-list">
<el-upload
ref="confirmUploadRef"
:auto-upload="false"
:show-file-list="false"
accept="image/*,.pdf,.doc,.docx"
:multiple="true"
accept="image/*,video/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.zip,.rar"
@change="handleConfirmAttachmentChange"
>
<div class="upload-card trigger">
<el-icon size="24" color="#10b981"><Plus /></el-icon>
<span>上传凭证</span>
<div class="upload-card">
<el-icon :size="28" color="#10b981"><Plus /></el-icon>
<span class="upload-card-text">上传附件</span>
</div>
</el-upload>
<div
v-for="(file, index) in confirmForm.attachments"
:key="file.id || index"
class="attachment-item"
:class="{ 'is-uploading': file._uploading }"
>
<div
class="attachment-preview"
@click="
isImageFile(file) && file.fileUrl ? handlePreviewAttachment(file) : undefined
"
>
<template v-if="isImageFile(file) && file.fileUrl">
<img :src="fullFileUrl(file.fileUrl)" :alt="file.fileName" />
</template>
<template v-else-if="isImageFile(file) && !file.fileUrl">
<el-icon :size="24" color="#94a3b8"><Loading /></el-icon>
</template>
<template v-else-if="isVideoFile(file)">
<div class="attachment-preview__icon attachment-preview__icon--video">
<el-icon :size="28"><VideoPlay /></el-icon>
</div>
</template>
<template v-else>
<div class="attachment-preview__icon attachment-preview__icon--doc">
<el-icon :size="28"><Document /></el-icon>
</div>
</template>
</div>
<div class="attachment-footer">
<span class="attachment-name" :title="file.fileName">{{ file.fileName }}</span>
<div class="attachment-actions">
<el-icon
v-if="isImageFile(file) || isVideoFile(file)"
class="action-btn"
title="预览"
@click="handlePreviewAttachment(file)"
><View
/></el-icon>
<el-icon class="action-btn" title="下载" @click="handleDownloadAttachment(file)"
><Download
/></el-icon>
<el-icon
class="action-btn action-btn--danger"
title="删除"
@click="confirmForm.attachments.splice(index, 1)"
><Delete
/></el-icon>
</div>
</div>
</div>
</div>
<span class="upload-hint">支持图片、视频、PDF、Word、Excel等文件</span>
</div>
</el-form-item>
</el-form>
</div>
<template #footer>
<el-button @click="confirmVisible = false">取消</el-button>
<el-button type="primary" :loading="submitLoading" @click="submitConfirm">确认</el-button>
<el-button class="btn-ghost" @click="confirmVisible = false">
<el-icon><Close /></el-icon>取消
</el-button>
<el-popconfirm
v-if="currentRow?.txnStatus === 'dqr'"
title="确定作废该流水吗?作废后不可恢复,业务需重新发起。"
confirm-button-text="确定"
cancel-button-text="取消"
@confirm="handleVoidTxn(currentRow)"
>
<template #reference>
<el-button class="btn-op-item op-warn" :loading="voidTxnId === currentRow?.id">
<el-icon><Delete /></el-icon>作废
</el-button>
</template>
</el-popconfirm>
<el-button class="btn-main" type="primary" :loading="submitLoading" @click="submitConfirm">
<el-icon><Check /></el-icon>确认
</el-button>
</template>
</el-dialog>
<!-- 提交前金额二次确认 -->
<el-dialog
v-model="amountConfirmVisible"
title="确认操作"
width="480px"
destroy-on-close
append-to-body
align-center
:close-on-click-modal="false"
class="finance-amount-confirm-dialog"
style="backdrop-filter: none"
>
<p v-if="currentRow" class="amount-confirm-text">
确认该笔操作 ¥{{ formatAmount(currentRow.amount) }}?
</p>
<template #footer>
<el-button class="btn-ghost" @click="amountConfirmVisible = false">
<el-icon><Close /></el-icon>取消
</el-button>
<el-button class="btn-main" type="primary" :loading="submitLoading" @click="executeSubmitConfirm">
<el-icon><Check /></el-icon>确认
</el-button>
</template>
</el-dialog>
@@ -320,7 +427,7 @@
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ElMessage } from 'element-plus'
import {
Plus,
Search,
@@ -328,7 +435,11 @@
RefreshLeft,
Download,
Delete,
Document
Document,
Loading,
VideoPlay,
Close,
Check
} from '@element-plus/icons-vue'
import SystemViewDialog, {
type ViewField,
@@ -338,10 +449,12 @@
import {
fetchServiceOrderTxnList,
fetchServiceOrderTxnDetail,
fetchConfirmTxn
fetchConfirmTxn,
fetchVoidTxn
} from '@/api/admin'
import { fetchUploadAttachment } from '@/api/business'
import { downloadAttachmentFile } from '@/utils/download-attachment'
import { formatMoneyDisplay } from '@/utils/money-format'
import {
txnTypeLabel,
txnTypeTagType,
@@ -356,11 +469,18 @@
return val ?? '-'
}
function formatAmount(val: any): string {
if (val == null || val === '') return '0.00'
const num = Number(val)
if (isNaN(num)) return '0.00'
return num.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
const formatAmount = (v: any): string => formatMoneyDisplay(v, 2)
function txnAmountLabel(txnType?: string) {
if (txnType === 'recharge') return '充值金额(元)'
if (txnType === 'refund') return '退款金额(元)'
if (txnType === 'purchase') return '购买金额(元)'
if (txnType === 'unsubscribe') return '退订金额(元)'
return '金额(元)'
}
function financeSubmitRemarkDisplay(d: Record<string, any>) {
return (d.financeSubmitRemark || d.remark || '').trim()
}
const minioBaseUrl = (import.meta.env.VITE_MINIO_BASE_URL || '').replace(/\/$/, '')
@@ -396,10 +516,10 @@
// 搜索与列表
// ---------------------------------------------------------------------------
/** Tab 对应的流水状态列表 */
/** Tab 对应的流水状态列表(已处理 Tab 走后端 financeDoneOnly) */
const TAB_STATUS_MAP: Record<string, string[]> = {
pending: ['dqr'],
done: ['yqr']
done: []
}
function formatLocalDate(d: Date): string {
@@ -426,6 +546,7 @@
const tableData = ref<any[]>([])
const loading = ref(false)
const voidTxnId = ref('')
const pagination = reactive({
page: 1,
pageSize: 20,
@@ -440,7 +561,9 @@
pageSize: pagination.pageSize
}
if (searchForm.txnType) params.txnType = searchForm.txnType
if (searchForm.txnStatus.length > 0) {
if (activeTab.value === 'done') {
params.financeDoneOnly = true
} else if (searchForm.txnStatus.length > 0) {
params.txnStatus = searchForm.txnStatus.join(',')
}
if (searchForm.keyword.trim()) params.keyword = searchForm.keyword.trim()
@@ -514,8 +637,12 @@
}
]
// 余额变动
if (d.balanceBefore != null || d.balanceAfter != null) {
// 余额变动(待处理不展示;已处理中已作废的充值不展示)
const showBalanceSection =
activeTab.value !== 'pending' &&
!(d.txnStatus === 'yzf' && d.txnType === 'recharge') &&
(d.balanceBefore != null || d.balanceAfter != null)
if (showBalanceSection) {
sections.push({
title: '余额变动',
fields: [
@@ -539,9 +666,10 @@
const submitSection: ViewSection = {
title: '发起确认',
fields: [
{ label: txnAmountLabel(d.txnType), value: `¥${formatAmount(d.amount)}` },
{ label: '提交人', value: d.financeSubmitByName || d.financeSubmitBy },
{ label: '提交时间', value: d.financeSubmitTime },
{ label: '备注', value: d.financeSubmitRemark, span: true }
{ label: '备注', value: financeSubmitRemarkDisplay(d), span: true }
]
}
if (d.financeSubmitAttachmentFiles?.length) {
@@ -552,11 +680,31 @@
sections.push(submitSection)
}
// 财务作废信息
if (d.txnStatus === 'yzf' && (d.voidTime || d.voidByName)) {
sections.push({
title: '财务作废',
fields: [
{
label: '作废人',
value: d.voidByName || d.voidBy,
tagType: 'info'
},
{ label: '作废时间', value: d.voidTime }
]
})
}
// 确认信息
if (d.financeConfirmTime) {
const confirmSection: ViewSection = {
title: '确认信息',
title: '财务确认',
fields: [
{
label: '确认人',
value: d.financeConfirmByName || d.financeConfirmBy,
tagType: 'success'
},
{ label: '确认时间', value: d.financeConfirmTime },
{ label: '财务备注', value: d.financeRemark, span: true }
]
@@ -594,6 +742,7 @@
// 统一确认弹窗
// ---------------------------------------------------------------------------
const confirmVisible = ref(false)
const amountConfirmVisible = ref(false)
const confirmUploadRef = ref()
const confirmForm = reactive({
remark: '',
@@ -607,22 +756,35 @@
confirmVisible.value = true
}
async function submitConfirm() {
async function handleVoidTxn(row: any) {
voidTxnId.value = row.id
try {
await fetchVoidTxn(row.id)
ElMessage.success('流水已作废')
if (currentRow.value?.id === row.id) {
confirmVisible.value = false
amountConfirmVisible.value = false
currentRow.value = null
}
await loadData()
} catch (e: any) {
ElMessage.error(e?.message || '作废失败')
} finally {
voidTxnId.value = ''
}
}
function submitConfirm() {
if (!currentRow.value) return
if (hasUploadingAttachments(confirmForm.attachments)) {
ElMessage.warning('附件上传中,请稍候')
return
}
try {
await ElMessageBox.confirm(
`确认该笔操作 ¥${formatAmount(currentRow.value.amount)}?`,
'确认操作',
{ confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }
)
} catch {
return
}
amountConfirmVisible.value = true
}
async function executeSubmitConfirm() {
if (!currentRow.value) return
submitLoading.value = true
try {
const data: Record<string, any> = {
@@ -634,6 +796,7 @@
}
await fetchConfirmTxn(currentRow.value.id, data)
ElMessage.success('确认成功')
amountConfirmVisible.value = false
confirmVisible.value = false
loadData()
} catch {
@@ -647,12 +810,6 @@
const file = uploadFile.raw || uploadFile
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
confirmForm.attachments.push({
id: tempId,
@@ -746,6 +903,13 @@
}
}
.amount-confirm-text {
margin: 0;
font-size: 14px;
line-height: 1.5;
color: var(--mint-text, #334155);
}
.form-section-divider {
height: 1px;
margin: 20px 0;
@@ -800,236 +964,180 @@
min-width: 80px;
}
/* 附件上传卡片化布局 */
.attachment-upload {
width: 100%;
}
.upload-cards-row {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.upload-card {
width: 140px;
height: 96px;
border: 1px dashed #a7f3d0;
border-radius: 8px;
background: #f0fdf4;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
cursor: pointer;
transition:
border-color 0.15s,
background 0.15s;
&:hover {
border-color: #10b981;
border-style: solid;
background: #ecfdf5;
/* 附件上传卡片化布局(对齐 ProtocolFormDialog / OpenSpec) */
.attachment-upload {
width: 100%;
}
&.uploaded {
border-style: solid;
border-color: #e2e8f0;
.attachment-list {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.upload-card {
width: 140px;
height: 96px;
border: 1px dashed #a7f3d0;
border-radius: 8px;
background: #f0fdf4;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
cursor: pointer;
transition:
border-color 0.15s,
background 0.15s;
&:hover {
border-color: #10b981;
border-style: solid;
background: #ecfdf5;
}
}
.upload-card-text {
font-size: 12px;
color: #10b981;
font-weight: 500;
line-height: 1;
}
.upload-hint {
display: block;
font-size: 11px;
color: #94a3b8;
line-height: 1;
margin-top: 8px;
}
.attachment-item {
width: 140px;
display: flex;
flex-direction: column;
border: 1px solid #e2e8f0;
border-radius: 8px;
background: #fff;
position: relative;
overflow: hidden;
transition:
border-color 0.15s,
box-shadow 0.15s;
&:hover {
border-color: #10b981;
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.1);
}
}
&.trigger {
span {
font-size: 12px;
color: #10b981;
font-weight: 500;
line-height: 1;
&.is-uploading {
opacity: 0.6;
pointer-events: none;
}
}
}
.upload-card-preview {
width: 100%;
height: 60px;
object-fit: cover;
border-radius: 6px 6px 0 0;
}
.upload-card-file {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 60px;
gap: 4px;
color: #64748b;
}
.upload-card-filename {
font-size: 11px;
color: #334155;
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.upload-card-actions {
display: flex;
justify-content: center;
gap: 4px;
height: 28px;
align-items: center;
}
.upload-card-text {
font-size: 12px;
color: #10b981;
font-weight: 500;
line-height: 1;
}
.upload-hint {
display: block;
font-size: 11px;
color: #94a3b8;
line-height: 1;
margin-top: 8px;
}
.attachment-list {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.attachment-item {
width: 140px;
display: flex;
flex-direction: column;
border: 1px solid #e2e8f0;
border-radius: 8px;
background: #fff;
overflow: hidden;
transition:
border-color 0.15s,
box-shadow 0.15s;
&:hover {
border-color: #10b981;
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.1);
}
&.is-uploading {
opacity: 0.6;
pointer-events: none;
}
}
.attachment-preview {
width: 100%;
height: 96px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
background: #f8fafc;
overflow: hidden;
cursor: pointer;
img {
.attachment-preview {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
}
height: 96px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
background: #f8fafc;
overflow: hidden;
cursor: pointer;
.attachment-preview__icon {
width: 48px;
height: 48px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
&--video {
background: #ede9fe;
color: #7c3aed;
img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
}
&--doc {
background: #e0f2fe;
color: #0284c7;
}
}
.attachment-preview__icon {
width: 48px;
height: 48px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
.attachment-footer {
display: flex;
flex-direction: column;
flex: 1;
padding: 6px 8px;
}
&--video {
background: #ede9fe;
color: #7c3aed;
}
.attachment-name {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
font-size: 11px;
color: #334155;
line-height: 1.4;
word-break: break-all;
min-height: calc(11px * 1.4 * 2);
}
.attachment-actions {
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
margin-top: 4px;
flex-shrink: 0;
}
.action-btn {
width: 22px;
height: 22px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: #64748b;
cursor: pointer;
background: #f1f5f9;
transition:
background 0.15s,
color 0.15s;
&:hover {
background: #10b981;
color: #fff;
&--doc {
background: #e0f2fe;
color: #0284c7;
}
}
&--danger:hover {
background: #ef4444;
color: #fff;
.attachment-footer {
display: flex;
flex-direction: column;
flex: 1;
padding: 6px 8px;
}
}
.preview-container {
text-align: center;
}
.attachment-name {
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
font-size: 11px;
color: #334155;
line-height: 1.4;
word-break: break-all;
min-height: calc(11px * 1.4 * 2);
}
.attachment-actions {
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
margin-top: 4px;
flex-shrink: 0;
}
.action-btn {
width: 22px;
height: 22px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: #64748b;
cursor: pointer;
background: #f1f5f9;
transition:
background 0.15s,
color 0.15s;
&:hover {
background: #10b981;
color: #fff;
}
&--danger:hover {
background: #ef4444;
color: #fff;
}
}
.preview-container {
text-align: center;
}
.text-muted {
color: var(--mint-text-muted, #94a3b8);
font-size: 13px;
}
/* 查看详情键值对 */
.view-section {
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,94 @@
<!-- 渠道服务订单 — 操作流水标准表格(查看弹窗等只读场景) -->
<template>
<div class="list-body list-wrap service-order-txn-table-wrap">
<el-table
v-if="rows.length"
:data="rows"
stripe
class="list-table inner-table"
:max-height="maxHeight"
>
<el-table-column type="index" label="序号" min-width="68" align="center" header-align="center" />
<el-table-column label="类型" min-width="120" align="center" header-align="center">
<template #default="{ row }">
<el-tag :type="txnTypeTagType(row.txnType)" size="small">
{{ txnTypeLabel(row.txnType) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="金额(元)" min-width="130" align="right" header-align="center">
<template #default="{ row }">
<span class="amount-text">¥{{ formatAmount(row.amount) }}</span>
</template>
</el-table-column>
<el-table-column label="状态" min-width="120" align="center" header-align="center">
<template #default="{ row }">
<el-tag :type="txnStatusTagType(row.txnStatus)" size="small">
{{ txnStatusLabel(row.txnStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" min-width="160" show-overflow-tooltip />
<el-table-column prop="createTime" label="创建时间" min-width="170" align="center" header-align="center" />
<el-table-column label="作废信息" min-width="200" show-overflow-tooltip>
<template #default="{ row }">
<span v-if="row.txnStatus === 'yzf'" class="void-info">
{{ row.voidByName || '—' }} · {{ row.voidTime || '—' }}
</span>
<span v-else class="void-info muted">—</span>
</template>
</el-table-column>
</el-table>
<el-empty v-else description="暂无操作流水" :image-size="48" />
</div>
</template>
<script setup lang="ts">
import {
txnTypeLabel,
txnTypeTagType,
txnStatusLabel,
txnStatusTagType
} from '@/utils/status-tag-registry'
import { formatMoneyDisplay } from '@/utils/money-format'
defineOptions({ name: 'ServiceOrderTxnTable' })
withDefaults(
defineProps<{
rows: Record<string, any>[]
maxHeight?: number | string
}>(),
{
rows: () => [],
maxHeight: 360
}
)
const formatAmount = (v: unknown): string => {
if (v == null || v === '') return '0.00'
return formatMoneyDisplay(v)
}
</script>
<style lang="scss" scoped>
.service-order-txn-table-wrap {
margin-top: 0;
padding: 0;
border: none;
}
.amount-text {
font-weight: 600;
color: var(--mint-primary, #10b981);
}
.void-info {
font-size: 13px;
color: var(--mint-text-muted, #64748b);
&.muted {
color: #cbd5e1;
}
}
</style>
@@ -139,15 +139,24 @@
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" min-width="170" align="center" />
<el-table-column label="操作" min-width="440" fixed="right" align="center" header-align="center">
<el-table-column label="操作" min-width="520" fixed="right" align="center" header-align="center">
<template #default="{ row }">
<el-button class="btn-op-item primary" @click="handleView(row)">查看</el-button>
<el-button class="btn-op-item primary" @click="handleView(row)">
<el-icon><View /></el-icon>查看
</el-button>
<el-button
v-if="row.orderType === 'yfk' || row.orderType === 'gmcp'"
class="btn-op-item"
@click="openTxnDialog(row)"
>
<el-icon><List /></el-icon>操作流水
</el-button>
<el-button
class="btn-op-item"
v-if="(row.orderType === 'yfk' || row.orderType === 'gmcp') && row.orderStatus === 'dsx'"
@click="handleEdit(row)"
>
编辑
<el-icon><Edit /></el-icon>编辑
</el-button>
<el-popconfirm
v-if="(row.orderType === 'yfk' || row.orderType === 'gmcp') && row.orderStatus === 'dsx'"
@@ -157,7 +166,9 @@
@confirm="handleDelete(row)"
>
<template #reference>
<el-button class="btn-op-item op-warn">删除</el-button>
<el-button class="btn-op-item op-warn">
<el-icon><Delete /></el-icon>删除
</el-button>
</template>
</el-popconfirm>
<!-- yfk 充值型:发起充值 -->
@@ -167,7 +178,7 @@
type="primary"
@click="openRechargeDialog(row)"
>
发起充值
<el-icon><Wallet /></el-icon>发起充值
</el-button>
<!-- yfk 充值型:申请退款 -->
<el-button
@@ -175,7 +186,7 @@
class="btn-op-item"
@click="openRefundDialog(row)"
>
申请退款
<el-icon><Sell /></el-icon>申请退款
</el-button>
<!-- gmcp 购买型:购买产品 -->
<el-button
@@ -184,7 +195,7 @@
type="primary"
@click="openPurchaseDialog(row)"
>
购买产品
<el-icon><ShoppingCart /></el-icon>购买产品
</el-button>
<!-- gmcp 购买型:退订产品 -->
<el-button
@@ -192,7 +203,7 @@
class="btn-op-item"
@click="openUnsubscribeDialog(row)"
>
退订产品
<el-icon><Remove /></el-icon>退订产品
</el-button>
<!-- 作废 -->
<el-button
@@ -201,7 +212,7 @@
type="danger"
@click="handleVoid(row)"
>
作废
<el-icon><Delete /></el-icon>作废
</el-button>
</template>
</el-table-column>
@@ -235,58 +246,46 @@
>
<!-- Product holdings for gmcp -->
<template v-if="viewData.orderType === 'gmcp'" #order-products>
<el-table
v-if="viewData.products?.length"
:data="viewData.products"
stripe
class="list-table inner-table"
size="small"
>
<el-table-column type="index" label="序号" min-width="60" align="center" />
<el-table-column prop="projectName" label="项目名称" min-width="150" show-overflow-tooltip />
<el-table-column prop="cellType" label="细胞类型" min-width="120" show-overflow-tooltip />
<el-table-column prop="specText" label="规格文本" min-width="150" show-overflow-tooltip />
<el-table-column label="协议单价(元)" min-width="120" align="right">
<template #default="{ row }">¥{{ formatAmount(row.agreementUnitPrice) }}</template>
</el-table-column>
<el-table-column prop="currentQty" label="当前持有" min-width="100" align="center" />
<el-table-column prop="totalBuyQty" label="累计购买" min-width="100" align="center" />
<el-table-column prop="totalUnsubscribeQty" label="累计退订" min-width="100" align="center" />
</el-table>
<el-empty v-else description="暂无产品持仓" :image-size="48" />
<div class="list-body list-wrap view-inner-table-wrap">
<el-table
v-if="viewData.products?.length"
:data="viewData.products"
stripe
class="list-table inner-table"
max-height="360"
>
<el-table-column type="index" label="序号" min-width="68" align="center" header-align="center" />
<el-table-column prop="projectName" label="项目名称" min-width="150" show-overflow-tooltip />
<el-table-column prop="cellType" label="细胞类型" min-width="120" show-overflow-tooltip />
<el-table-column prop="specText" label="规格文本" min-width="150" show-overflow-tooltip />
<el-table-column label="协议单价(元)" min-width="130" align="right" header-align="center">
<template #default="{ row }">¥{{ formatAmount(row.agreementUnitPrice) }}</template>
</el-table-column>
<el-table-column prop="currentQty" label="当前持有" min-width="100" align="center" header-align="center" />
<el-table-column prop="totalBuyQty" label="累计购买" min-width="100" align="center" header-align="center" />
<el-table-column
prop="totalUnsubscribeQty"
label="累计退订"
min-width="100"
align="center"
header-align="center"
/>
</el-table>
<el-empty v-else description="暂无产品持仓" :image-size="48" />
</div>
</template>
<!-- Transaction timeline -->
<template v-if="viewData.transactions?.length" #txn-timeline>
<el-table
:data="viewData.transactions"
stripe
class="list-table inner-table"
size="small"
>
<el-table-column type="index" label="序号" min-width="60" align="center" />
<el-table-column label="类型" min-width="100" align="center">
<template #default="{ row }">
<el-tag :type="txnTypeTagType(row.txnType)" size="small">
{{ txnTypeLabel(row.txnType) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="金额(元)" min-width="120" align="right">
<template #default="{ row }">¥{{ formatAmount(row.amount) }}</template>
</el-table-column>
<el-table-column label="状态" min-width="100" align="center">
<template #default="{ row }">
<el-tag :type="txnStatusTagType(row.txnStatus)" size="small">
{{ txnStatusLabel(row.txnStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" min-width="150" show-overflow-tooltip />
<el-table-column prop="createTime" label="创建时间" min-width="170" align="center" />
</el-table>
<template #txn-timeline>
<ServiceOrderTxnTable :rows="viewData.transactions || []" />
</template>
</SystemViewDialog>
<ServiceOrderTxnDialog
ref="txnDialogRef"
v-model:visible="txnDialogVisible"
:order="txnDialogOrder"
@refreshed="onTxnDialogRefreshed"
/>
<!-- ═══════════════════════════════════════════════════════════════════ -->
<!-- 新增/编辑弹窗 -->
<!-- ═══════════════════════════════════════════════════════════════════ -->
@@ -338,17 +337,6 @@
<el-form-item label="部门名称" prop="deptName">
<el-input v-model="formData.deptName" placeholder="请输入部门名称" />
</el-form-item>
<!-- 预付款充值 - 充值金额 -->
<el-form-item v-if="formData.orderType === 'yfk'" label="充值金额(元)" prop="prepayAmount">
<el-input-number
v-model="formData.prepayAmount"
:min="0.01"
:precision="2"
:step="100"
controls-position="right"
style="width: 100%"
/>
</el-form-item>
<!-- 渠道协议(预付款充值 / 购买产品均必填,后续按协议价指导中试服务单) -->
<el-form-item label="渠道协议" prop="channelAgreementId">
<el-select
@@ -415,13 +403,10 @@
</el-table-column>
<el-table-column label="单价(元)" min-width="120" align="right">
<template #default="{ row }">
<el-input-number
<AmountInput
v-model="row.unitPrice"
class="product-detail-cell-control"
:min="0"
:precision="2"
:step="1"
controls-position="right"
class="product-detail-cell-control"
@change="calcItemAmount(row)"
/>
</template>
@@ -445,7 +430,9 @@
</el-table-column>
<el-table-column label="操作" min-width="70" align="center">
<template #default="{ $index }">
<el-button link type="danger" @click="removeFormItem($index)">删除</el-button>
<el-button link type="danger" @click="removeFormItem($index)">
<el-icon><Delete /></el-icon>删除
</el-button>
</template>
</el-table-column>
</el-table>
@@ -491,18 +478,93 @@
</el-dialog>
<!-- 发起充值弹窗 -->
<el-dialog v-model="rechargeVisible" title="发起充值" width="480px" destroy-on-close :close-on-click-modal="false">
<el-dialog v-model="rechargeVisible" title="发起充值" width="560px" destroy-on-close :close-on-click-modal="false">
<el-form label-position="top">
<el-form-item label="充值金额(元)">
<el-input-number v-model="rechargeForm.amount" :min="0.01" :precision="2" :step="100" controls-position="right" style="width: 100%" />
<AmountInput
v-model="rechargeForm.amount"
:min="0.01"
placeholder="请输入充值金额"
/>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="rechargeForm.remark" type="textarea" :rows="3" placeholder="请输入备注" />
</el-form-item>
<el-form-item label="附件">
<div class="attachment-upload">
<div class="attachment-list">
<el-upload
ref="rechargeUploadRef"
:auto-upload="false"
:show-file-list="false"
:multiple="true"
accept="image/*,video/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.zip,.rar"
@change="handleRechargeAttachmentChange"
>
<div class="upload-card">
<el-icon :size="28" color="#10b981"><Plus /></el-icon>
<span class="upload-card-text">上传附件</span>
</div>
</el-upload>
<div
v-for="(file, index) in rechargeForm.attachments"
:key="file.id || index"
class="attachment-item"
:class="{ 'is-uploading': file._uploading }"
>
<div
class="attachment-preview"
@click="
isImageFile(file) && file.fileUrl ? handlePreviewAttachment(file) : undefined
"
>
<template v-if="isImageFile(file) && file.fileUrl">
<img :src="fullFileUrl(file.fileUrl)" :alt="file.fileName" />
</template>
<template v-else-if="isImageFile(file) && !file.fileUrl">
<el-icon :size="24" color="#94a3b8"><Loading /></el-icon>
</template>
<template v-else-if="isVideoFile(file)">
<div class="attachment-preview__icon attachment-preview__icon--video">
<el-icon :size="28"><VideoPlay /></el-icon>
</div>
</template>
<template v-else>
<div class="attachment-preview__icon attachment-preview__icon--doc">
<el-icon :size="28"><Document /></el-icon>
</div>
</template>
</div>
<div class="attachment-footer">
<span class="attachment-name" :title="file.fileName">{{ file.fileName }}</span>
<div class="attachment-actions">
<el-icon class="action-btn" title="预览" @click="handlePreviewAttachment(file)"
><View
/></el-icon>
<el-icon class="action-btn" title="下载" @click="handleDownloadAttachment(file)"
><Download
/></el-icon>
<el-icon
class="action-btn action-btn--danger"
title="删除"
@click="removeRechargeAttachment(index)"
><Delete
/></el-icon>
</div>
</div>
</div>
</div>
<span class="upload-hint">支持图片、视频、PDF、Word、Excel 等,可上传多个</span>
</div>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="rechargeVisible = false">取消</el-button>
<el-button type="primary" :loading="rechargeLoading" @click="submitRecharge">确认</el-button>
<el-button class="btn-ghost" @click="rechargeVisible = false">
<el-icon><Close /></el-icon>取消
</el-button>
<el-button class="btn-main" type="primary" :loading="rechargeLoading" @click="submitRecharge">
<el-icon><Check /></el-icon>确认
</el-button>
</template>
</el-dialog>
@@ -511,15 +573,24 @@
<el-form label-position="top">
<el-form-item>
<template #label>退款金额(元)<span class="form-label-tip">当前余额:¥{{ formatAmount(currentOrderForTxn?.currentBalance) }}</span></template>
<el-input-number v-model="refundTxnForm.amount" :min="0.01" :max="Number(currentOrderForTxn?.currentBalance || 0)" :precision="2" :step="100" controls-position="right" style="width: 100%" />
<AmountInput
v-model="refundTxnForm.amount"
:min="0.01"
:max="Number(currentOrderForTxn?.currentBalance || 0)"
placeholder="请输入退款金额"
/>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="refundTxnForm.remark" type="textarea" :rows="3" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="refundTxnVisible = false">取消</el-button>
<el-button type="primary" :loading="refundTxnLoading" @click="submitRefundTxn">确认</el-button>
<el-button class="btn-ghost" @click="refundTxnVisible = false">
<el-icon><Close /></el-icon>取消
</el-button>
<el-button class="btn-main" type="primary" :loading="refundTxnLoading" @click="submitRefundTxn">
<el-icon><Check /></el-icon>确认
</el-button>
</template>
</el-dialog>
@@ -549,7 +620,9 @@
</el-table-column>
<el-table-column label="操作" min-width="60" align="center">
<template #default="{ $index }">
<el-button type="danger" link size="small" @click="removePurchaseItem($index)">删除</el-button>
<el-button type="danger" link size="small" @click="removePurchaseItem($index)">
<el-icon><Delete /></el-icon>删除
</el-button>
</template>
</el-table-column>
</el-table>
@@ -563,8 +636,12 @@
</el-form-item>
</el-form>
<template #footer>
<el-button @click="purchaseVisible = false">取消</el-button>
<el-button type="primary" :loading="purchaseLoading" @click="submitPurchase">确认</el-button>
<el-button class="btn-ghost" @click="purchaseVisible = false">
<el-icon><Close /></el-icon>取消
</el-button>
<el-button class="btn-main" type="primary" :loading="purchaseLoading" @click="submitPurchase">
<el-icon><Check /></el-icon>确认
</el-button>
</template>
</el-dialog>
@@ -597,8 +674,12 @@
</el-form-item>
</el-form>
<template #footer>
<el-button @click="unsubscribeVisible = false">取消</el-button>
<el-button type="primary" :loading="unsubscribeLoading" @click="submitUnsubscribe">确认退订</el-button>
<el-button class="btn-ghost" @click="unsubscribeVisible = false">
<el-icon><Close /></el-icon>取消
</el-button>
<el-button class="btn-main" type="primary" :loading="unsubscribeLoading" @click="submitUnsubscribe">
<el-icon><Check /></el-icon>确认退订
</el-button>
</template>
</el-dialog>
@@ -641,9 +722,18 @@ import {
Loading,
Download,
Delete,
VideoPlay
VideoPlay,
View,
List,
Edit,
Wallet,
Sell,
ShoppingCart,
Remove
} from '@element-plus/icons-vue'
import SystemViewDialog, { type ViewSection } from '@/components/business/system-view-dialog/index.vue'
import ServiceOrderTxnTable from './ServiceOrderTxnTable.vue'
import ServiceOrderTxnDialog from './ServiceOrderTxnDialog.vue'
import {
fetchChannelServiceOrderList,
fetchChannelServiceOrderDetail,
@@ -662,27 +752,20 @@ import {
} from '@/api/admin'
import { fetchUploadAttachment } from '@/api/business'
import { downloadAttachmentFile } from '@/utils/download-attachment'
import AmountInput from '@/components/common/amount-input/index.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
import {
channelServiceOrderTypeLabel,
channelServiceOrderTypeTagType,
channelServiceOrderStatusLabel,
channelServiceOrderStatusTagType,
agreementTypeLabel,
txnTypeLabel,
txnTypeTagType,
txnStatusLabel,
txnStatusTagType
agreementTypeLabel
} from '@/utils/status-tag-registry'
defineOptions({ name: 'ChannelServiceOrderManagement' })
// ── 工具函数 ──────────────────────────────────────────────────────────
const formatAmount = (v: any): string => {
if (v == null || v === '') return '0.00'
const n = Number(v)
if (Number.isNaN(n)) return '0.00'
return n.toFixed(2)
}
const formatAmount = (v: any): string => formatMoneyDisplay(v, 2)
const displayValue = (v: any): string => {
if (v == null || v === '' || v === undefined) return '-'
@@ -881,14 +964,11 @@ const viewSections = computed((): ViewSection[] => {
})
}
// Transaction timeline
if (d.transactions?.length) {
sections.push({
title: '操作记录',
fields: [],
slot: 'txn-timeline'
})
}
sections.push({
title: '操作记录',
fields: [],
slot: 'txn-timeline'
})
return sections
})
@@ -939,7 +1019,6 @@ const initFormData = () => ({
orderType: 'yfk',
channelId: '',
deptName: '',
prepayAmount: null as number | null,
channelAgreementId: '',
items: [] as any[],
remark: ''
@@ -950,22 +1029,6 @@ const formData = reactive(initFormData())
const formRules: FormRules = {
orderType: [{ required: true, message: '请选择订单类型', trigger: 'change' }],
channelId: [{ required: true, message: '请选择渠道', trigger: 'change' }],
prepayAmount: [
{
validator: (_rule, value, callback) => {
if (formData.orderType !== 'yfk') {
callback()
return
}
if (value == null || Number(value) <= 0) {
callback(new Error('请输入充值金额'))
return
}
callback()
},
trigger: 'blur'
}
],
channelAgreementId: [
{
validator: (_rule, value, callback) => {
@@ -1158,7 +1221,6 @@ const formTotalAmount = computed(() =>
)
const handleOrderTypeChange = () => {
formData.prepayAmount = null
formData.channelAgreementId = ''
formData.items = []
agreementOptions.value = []
@@ -1189,7 +1251,6 @@ const handleEdit = async (row: any) => {
formData.orderType = detail.orderType || 'yfk'
formData.channelId = detail.channelId || ''
formData.deptName = detail.deptName || ''
formData.prepayAmount = detail.prepayAmount ?? null
formData.channelAgreementId = detail.channelAgreementId || ''
formData.remark = detail.remark || ''
@@ -1267,7 +1328,6 @@ const handleFormSubmit = async () => {
}
if (formData.orderType === 'yfk') {
payload.prepayAmount = formData.prepayAmount
payload.channelAgreementId = formData.channelAgreementId
} else {
payload.channelAgreementId = formData.channelAgreementId
@@ -1322,32 +1382,67 @@ const handleDelete = async (row: any) => {
// ── 流水操作 ──────────────────────────────────────────────────────────
const currentOrderForTxn = ref<any>(null)
const txnDialogVisible = ref(false)
const txnDialogOrder = ref<Record<string, any> | null>(null)
const txnDialogRef = ref<InstanceType<typeof ServiceOrderTxnDialog> | null>(null)
const openTxnDialog = (row: any) => {
txnDialogOrder.value = row
txnDialogVisible.value = true
}
const onTxnDialogRefreshed = () => {
loadData()
if (viewVisible.value && viewData.value?.id === txnDialogOrder.value?.id) {
handleView(txnDialogOrder.value)
}
}
// ── 发起充值 ──────────────────────────────────────────────────────────
const rechargeVisible = ref(false)
const rechargeLoading = ref(false)
const rechargeUploadRef = ref<{ clearFiles?: () => void }>()
const rechargeForm = reactive({
amount: null as number | null,
remark: ''
remark: '',
attachments: [] as any[]
})
const openRechargeDialog = (row: any) => {
currentOrderForTxn.value = row
rechargeForm.amount = null
rechargeForm.remark = ''
rechargeForm.attachments = []
rechargeVisible.value = true
}
const handleRechargeAttachmentChange = (uploadFile: any) => {
const file = uploadFile.raw || uploadFile
if (!file) return
uploadAttachmentItem(file, rechargeForm.attachments, rechargeUploadRef, 'channel-service-order')
}
const removeRechargeAttachment = (index: number) => {
rechargeForm.attachments.splice(index, 1)
}
const submitRecharge = async () => {
if (!rechargeForm.amount || rechargeForm.amount <= 0) {
ElMessage.warning('请输入充值金额')
return
}
if (hasUploadingAttachments(rechargeForm.attachments)) {
ElMessage.warning('附件正在上传,请稍候')
return
}
const attachmentUrls = joinAttachmentUrls(rechargeForm.attachments)
const attachmentPayload = attachmentUrls ? { financeSubmitAttachments: attachmentUrls } : {}
rechargeLoading.value = true
try {
const res: any = await fetchCreateRechargeTxn(currentOrderForTxn.value.id, {
amount: rechargeForm.amount,
remark: rechargeForm.remark
remark: rechargeForm.remark,
...attachmentPayload
})
const txn = res?.data ?? res
rechargeVisible.value = false
@@ -1358,12 +1453,13 @@ const submitRecharge = async () => {
cancelButtonText: '稍后再说',
type: 'info'
})
await fetchSubmitTxnFinance(txn.id, {})
await fetchSubmitTxnFinance(txn.id, attachmentPayload)
ElMessage.success('充值成功,已发起财务确认')
} catch {
ElMessage.success('充值流水已创建')
}
loadData()
onTxnDialogRefreshed()
txnDialogRef.value?.reload()
} catch (e: any) {
ElMessage.error(e?.message || '操作失败')
} finally {
@@ -1410,7 +1506,8 @@ const submitRefundTxn = async () => {
} catch {
ElMessage.success('退款流水已创建')
}
loadData()
onTxnDialogRefreshed()
txnDialogRef.value?.reload()
} catch (e: any) {
ElMessage.error(e?.message || '操作失败')
} finally {
@@ -1533,7 +1630,8 @@ const submitPurchase = async () => {
} catch {
ElMessage.success('购买流水已创建')
}
loadData()
onTxnDialogRefreshed()
txnDialogRef.value?.reload()
} catch (e: any) {
ElMessage.error(e?.message || '操作失败')
} finally {
@@ -1619,7 +1717,8 @@ const submitUnsubscribe = async () => {
} catch {
ElMessage.success('退订流水已创建')
}
loadData()
onTxnDialogRefreshed()
txnDialogRef.value?.reload()
} catch (e: any) {
ElMessage.error(e?.message || '操作失败')
} finally {
@@ -1693,13 +1792,6 @@ async function uploadAttachmentItem(
uploadRef: { value?: { clearFiles?: () => void } },
folder: string
) {
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
uploadRef.value?.clearFiles?.()
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
list.push({
id: tempId,
@@ -1812,6 +1904,12 @@ onMounted(() => {
}
}
.view-inner-table-wrap {
margin-top: 0;
padding: 0;
border: none;
}
.product-detail-table-wrap {
width: 100%;
@@ -414,6 +414,7 @@
import { Calendar, Close, CollectionTag, OfficeBuilding, User } from '@element-plus/icons-vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
import { downloadAttachmentFile } from '@/utils/download-attachment'
import { formatMoneyDisplay } from '@/utils/money-format'
import {
channelTypeLabel,
channelTypeTagType,
@@ -542,12 +543,7 @@
downloadAttachmentFile(file, { fullFileUrl })
}
function formatAmount(val: unknown) {
if (val === null || val === undefined || val === '') return '0.00'
const num = Number(val)
if (isNaN(num)) return '0.00'
return num.toFixed(2)
}
const formatAmount = (v: unknown): string => formatMoneyDisplay(v as any, 2)
async function loadAccountData() {
if (!props.channelId || accountLoaded.value) return
@@ -283,7 +283,7 @@
</div>
</div>
<span class="upload-hint"
>支持图片、视频、PDF、Word、Excel等文件,单文件不超过 20MB</span
>支持图片、视频、PDF、Word、Excel等文件</span
>
</div>
</el-form-item>
@@ -632,7 +632,7 @@
</div>
<div v-if="agr.creditLimit != null" class="sub-card-field">
<span class="field-label">授信额度(元)</span>
<span class="field-value">{{ agr.creditLimit }}</span>
<span class="field-value">{{ agr.creditLimit != null ? formatMoneyDisplay(agr.creditLimit) : '-' }}</span>
</div>
<div v-if="agr.effectiveDate" class="sub-card-field">
<span class="field-label">生效日期</span>
@@ -728,7 +728,7 @@
header-align="center"
>
<template #default="{ row: priceRow }">
{{ priceRow.originalPrice != null ? `${priceRow.originalPrice}` : '-' }}
{{ priceRow.originalPrice != null ? formatMoneyDisplay(priceRow.originalPrice) : '-' }}
</template>
</el-table-column>
<el-table-column
@@ -738,15 +738,12 @@
header-align="center"
>
<template #default="{ row: priceRow }">
<el-input-number
<AmountInput
v-model="priceRow.agreementPrice"
class="protocol-price-input"
:precision="2"
:min="0"
:controls="false"
style="width: 100%"
class="protocol-price-input"
placeholder="请输入"
@blur="handleUpdatePrice(priceRow)"
@change="handleUpdatePrice(priceRow)"
/>
</template>
</el-table-column>
@@ -852,12 +849,9 @@
</el-select>
</el-form-item>
<el-form-item label="授信额度(元)" prop="creditLimit">
<el-input-number
<AmountInput
v-model="agreementFormData.creditLimit"
:precision="2"
:min="0"
:controls="false"
style="width: 100%"
placeholder="请输入授信额度(元)"
/>
</el-form-item>
@@ -965,7 +959,7 @@
<el-table-column prop="specText" label="规格" min-width="100" align="center" header-align="center" />
<el-table-column label="单价(元)" min-width="90" align="center" header-align="center">
<template #default="{ row }">
{{ row.unitPrice != null ? `${row.unitPrice}` : '-' }}
{{ row.unitPrice != null ? formatMoneyDisplay(row.unitPrice) : '-' }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" min-width="120" align="center" header-align="center" show-overflow-tooltip />
@@ -1034,6 +1028,8 @@
import { withFullscreenLoading, fullscreenLoadingText } from '@/utils/fullscreen-loading'
import { fetchUploadAttachment } from '@/api/business'
import { downloadAttachmentFile } from '@/utils/download-attachment'
import AmountInput from '@/components/common/amount-input/index.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
import {
channelType as channelTypeRegistry,
channelTypeLabel,
@@ -2239,13 +2235,6 @@
const file = uploadFile.raw || uploadFile
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
attachmentUploadRef.value?.clearFiles()
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
formData.attachments.push({
id: tempId,
@@ -29,7 +29,7 @@
<el-table-column prop="itemCount" label="项目数" min-width="80" align="center" header-align="center" />
<el-table-column label="合计费用(元)" min-width="120" align="center" header-align="center">
<template #default="{ row }">{{
row.totalFee != null ? `¥${row.totalFee}` : '—'
row.totalFee != null ? `¥${formatMoneyDisplay(row.totalFee)}` : '—'
}}</template>
</el-table-column>
<el-table-column prop="status" label="状态" min-width="90" align="center">
@@ -129,12 +129,9 @@
</el-table-column>
<el-table-column label="项目费用(元)" min-width="120" align="center" header-align="center">
<template #default="{ row }">
<el-input-number
<AmountInput
v-model="row.projectFee"
:precision="2"
:min="0"
:controls="false"
style="width: 100%"
/>
</template>
</el-table-column>
@@ -216,7 +213,7 @@
/>
<el-table-column label="项目费用(元)" min-width="120" align="center" header-align="center">
<template #default="{ row }">{{
row.projectFee != null ? `¥${row.projectFee}` : '—'
row.projectFee != null ? `¥${formatMoneyDisplay(row.projectFee)}` : '—'
}}</template>
</el-table-column>
<el-table-column prop="status" label="状态" min-width="90" align="center" header-align="center">
@@ -266,6 +263,8 @@
fetchCheckupInstitutionProjects
} from '@/api/admin'
import { withFullscreenLoading, fullscreenLoadingText } from '@/utils/fullscreen-loading'
import AmountInput from '@/components/common/amount-input/index.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
const props = defineProps<{
institutionId: string
@@ -201,7 +201,7 @@
<el-table-column type="index" label="序号" min-width="68" align="center" header-align="center" />
<el-table-column prop="projectName" label="项目名称" min-width="160" align="center" header-align="center" />
<el-table-column prop="projectFee" label="项目费用(元)" min-width="120" align="center" header-align="center">
<template #default="{ row }">{{ row.projectFee != null ? `¥${row.projectFee}` : '—' }}</template>
<template #default="{ row }">{{ row.projectFee != null ? `¥${formatMoneyDisplay(row.projectFee)}` : '—' }}</template>
</el-table-column>
<el-table-column prop="status" label="状态" min-width="90" align="center" header-align="center">
<template #default="{ row }">
@@ -255,7 +255,7 @@
<el-input v-model="itemForm.projectName" />
</el-form-item>
<el-form-item label="项目费用(元)" prop="projectFee">
<el-input-number v-model="itemForm.projectFee" :min="0" :precision="2" style="width: 100%" />
<AmountInput v-model="itemForm.projectFee" :min="0" placeholder="请输入项目费用" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="itemForm.status">
@@ -313,6 +313,8 @@
} from '@element-plus/icons-vue'
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
import CheckupPackagePanel from './CheckupPackagePanel.vue'
import AmountInput from '@/components/common/amount-input/index.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
import type { ViewSection } from '@/components/business/system-view-dialog/index.vue'
import {
fetchCheckupInstitutionList,
@@ -179,13 +179,9 @@
<el-table-column prop="specText" label="规格" min-width="100" align="center" header-align="center" />
<el-table-column label="单价(元)" min-width="100" align="center" header-align="center">
<template #default="{ row }">
<el-input-number
<AmountInput
v-model="row.unitPrice"
:precision="2"
:min="0"
:controls="false"
size="default"
style="width: 100%"
placeholder="请输入单价"
/>
</template>
@@ -249,7 +245,7 @@
<el-table-column prop="specText" label="规格" min-width="100" align="center" header-align="center" />
<el-table-column label="单价" min-width="80" align="center" header-align="center">
<template #default="{ row }">
{{ row.unitPrice != null ? `${row.unitPrice} 元` : '-' }}
{{ row.unitPrice != null ? `${formatMoneyDisplay(row.unitPrice)} 元` : '-' }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" min-width="120" align="center" header-align="center" />
@@ -283,8 +279,10 @@
import { ref, reactive, onMounted, computed, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Close, Check, View, Edit, Delete, ScaleToOriginal, RefreshLeft, Search } from '@element-plus/icons-vue'
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
import { withFullscreenLoading, fullscreenLoadingText } from '@/utils/fullscreen-loading'
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
import AmountInput from '@/components/common/amount-input/index.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
import { withFullscreenLoading, fullscreenLoadingText } from '@/utils/fullscreen-loading'
import {
fetchProjectSystemList,
fetchCreateProjectSystem,
@@ -394,7 +392,7 @@
title: '价格明细',
fields: items.map((item: any, idx: number) => ({
label: `明细 ${idx + 1}`,
value: `${item.projectName || '-'} / ${item.cellTypeName || '-'} / ${item.specText || '-'} / ${item.unitPrice != null ? item.unitPrice + ' 元' : '-'} / ${item.remark || '-'}`,
value: `${item.projectName || '-'} / ${item.cellTypeName || '-'} / ${item.specText || '-'} / ${item.unitPrice != null ? formatMoneyDisplay(item.unitPrice) + ' 元' : '-'} / ${item.remark || '-'}`,
span: true
}))
}
@@ -533,7 +533,7 @@
</div>
</div>
</div>
<span class="upload-hint">支持图片上传,单文件不超过 10MB</span>
<span class="upload-hint">支持图片上传</span>
</div>
</el-form-item>
<el-form-item label="备注" class="form-col-span-2">
@@ -1105,12 +1105,7 @@
const file = uploadFile.raw || uploadFile
if (!file) return
const maxSizeMb = 10
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`图片大小不能超过 ${maxSizeMb}MB`)
productImageUploadRef.value?.clearFiles()
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
productImageFiles.value.push({
@@ -244,7 +244,7 @@
</div>
</div>
</div>
<span class="upload-hint">支持图片上传,单文件不超过 10MB</span>
<span class="upload-hint">支持图片上传</span>
</div>
</el-form-item>
<!-- 备注 (full width) -->
@@ -625,12 +625,7 @@
async function handleProductImageChange(uploadFile: any) {
const file = uploadFile.raw || uploadFile
if (!file) return
const maxSizeMb = 10
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`图片大小不能超过 ${maxSizeMb}MB`)
productImageUploadRef.value?.clearFiles()
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
productImageFiles.value.push({
id: tempId,
+2 -7
View File
@@ -196,7 +196,7 @@
</div>
</div>
<span class="upload-hint"
>支持图片、视频、PDF、Word、Excel等文件,单文件不超过 20MB</span
>支持图片、视频、PDF、Word、Excel等文件</span
>
</div>
</el-form-item>
@@ -460,12 +460,7 @@
const file = uploadFile?.raw || uploadFile
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
attachmentUploadRef.value?.clearFiles()
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
formData.attachments.push({
@@ -382,6 +382,7 @@
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Close, Check, Search, RefreshLeft, VideoPlay, View, Tickets, EditPen, Plus } from '@element-plus/icons-vue'
import { formatMoneyDisplay } from '@/utils/money-format'
import ProtocolFinanceConfirmFields from '@/components/business/protocol-finance-confirm-fields/index.vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
import DialogFormBody from '@/components/business/dialog-form-body/index.vue'
@@ -884,7 +885,7 @@
{ label: '检测项目', value: d.itemName },
{ label: '项目编码', value: d.itemCode || '—' },
{ label: '第三方公司', value: d.companyName || '—' },
{ label: '检测费用', value: d.feeAmount != null ? `¥${d.feeAmount}` : '—' },
{ label: '检测费用', value: d.feeAmount != null ? '¥' + formatMoneyDisplay(d.feeAmount) : '—' },
{ label: '任务状态', value: taskStatusLabel(d.taskStatus), tagType: d.taskStatus === 'ywc' ? 'success' : d.taskStatus === 'jxz' ? 'warning' : 'info' },
{
label: '检测结论',
@@ -214,7 +214,7 @@
<div class="qc-company-group-title">{{ group.companyName }}</div>
<div class="qc-company-group-items">
<el-checkbox v-for="item in group.items" :key="item.id" :value="item.id">
{{ item.itemName }}({{ item.itemCode }})¥{{ item.feeAmount }}
{{ item.itemName }}({{ item.itemCode }})¥{{ formatMoneyDisplay(item.feeAmount) }}
</el-checkbox>
</div>
</div>
@@ -348,6 +348,7 @@
</template>
<script setup lang="ts">
import { formatMoneyDisplay } from '@/utils/money-format'
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Close, Check, Search, RefreshLeft, View, Setting, Document, Plus, EditPen } from '@element-plus/icons-vue'
@@ -718,7 +719,7 @@
function formatConfiguredThirdItems(d: QcWorkOrderDetail) {
return (
d.thirdPartyItems
?.map((li) => `${li.companyName || ''} — ${li.itemName || ''}(¥${li.feeAmount ?? '—'})`)
?.map((li) => `${li.companyName || ''} — ${li.itemName || ''}(${li.feeAmount != null ? '¥' + formatMoneyDisplay(li.feeAmount) : '—'})`)
.join('、') || '无'
)
}
@@ -97,7 +97,7 @@
</div>
</div>
</div>
<p class="upload-hint">支持图片、文档等,单文件不超过 20MB。</p>
<p class="upload-hint">支持图片、文档等。</p>
</div>
</el-form-item>
</el-form>
@@ -196,11 +196,7 @@
async function handleAttachmentChange(uploadFile: { raw?: File }) {
const file = uploadFile.raw
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
const uploading: AttachmentItem = {
id: tempId,
@@ -204,7 +204,7 @@
<el-table-column prop="itemCode" label="项目编码" min-width="120" align="center" />
<el-table-column prop="itemName" label="项目名称" min-width="160" align="center" />
<el-table-column prop="feeAmount" label="费用(元)" min-width="110" align="center">
<template #default="{ row }">{{ row.feeAmount != null ? `¥${row.feeAmount}` : '—' }}</template>
<template #default="{ row }">{{ row.feeAmount != null ? '¥' + formatMoneyDisplay(row.feeAmount) : '—' }}</template>
</el-table-column>
<el-table-column prop="status" label="状态" min-width="90" align="center">
<template #default="{ row }">
@@ -263,7 +263,7 @@
<el-input v-model="itemForm.itemName" />
</el-form-item>
<el-form-item label="费用(元)" prop="feeAmount">
<el-input-number v-model="itemForm.feeAmount" :min="0" :precision="2" style="width: 100%" />
<AmountInput v-model="itemForm.feeAmount" :min="0" placeholder="请输入检测费用" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="itemForm.status">
@@ -409,6 +409,8 @@
} from '@/api/qc-third-party-item'
import { fetchQcItemParams, fetchSaveQcItemParams, type QcItemParam } from '@/api/qc-item-param'
import { fetchItemUnitList } from '@/api/admin'
import AmountInput from '@/components/common/amount-input/index.vue'
import { formatMoneyDisplay } from '@/utils/money-format'
defineOptions({ name: 'QualityInspectionThirdPartyCompany' })
@@ -711,7 +711,7 @@
</div>
</div>
</div>
<span class="upload-hint">支持图片和 PDF 格式,可稍后补充,单文件不超过 20MB</span>
<span class="upload-hint">支持图片和 PDF 格式,可稍后补充</span>
</div>
<!-- 其他附件 -->
@@ -783,7 +783,7 @@
</div>
</div>
</div>
<span class="upload-hint">支持图片、PDF、Word 格式,单文件不超过 20MB</span>
<span class="upload-hint">支持图片、PDF、Word 格式</span>
</div>
</div>
</div>
@@ -2147,12 +2147,6 @@
async function handleConsentAttachmentChange(uploadFile: any) {
const file = uploadFile.raw || uploadFile
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
consentUploadRef.value?.clearFiles()
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
formData.consentAttachments.push({
id: tempId,
@@ -2197,12 +2191,6 @@
async function handleOtherAttachmentChange(uploadFile: any) {
const file = uploadFile.raw || uploadFile
if (!file) return
const maxSizeMb = 20
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`文件大小不能超过 ${maxSizeMb}MB`)
otherUploadRef.value?.clearFiles()
return
}
const tempId = `temp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
formData.otherAttachments.push({
id: tempId,
@@ -581,6 +581,7 @@
<script setup lang="ts">
import { computed, nextTick, ref, watch } from 'vue'
import { formatMoneyDisplay } from '@/utils/money-format'
import { Calendar, CircleCheck, Close, Document, User } from '@element-plus/icons-vue'
import ProtocolAttachmentReadonly from '@/views/cell-storage/protocol/ProtocolAttachmentReadonly.vue'
import SampleQcInfoCards from '@/components/business/sample-qc-info-cards/index.vue'
@@ -830,7 +831,7 @@
if (ec !== '—') parts.push(ec)
if (transport.waybillNo) parts.push(String(transport.waybillNo))
if (transport.expressFee != null && transport.expressFee !== '') {
parts.push(`¥${transport.expressFee}`)
parts.push('¥' + formatMoneyDisplay(transport.expressFee))
}
return parts.length ? parts.join(' · ') : '—'
}
@@ -802,12 +802,7 @@
}
const uploadCategoryImageFile = async (file: File) => {
const maxSizeMb = 10
if (file.size / 1024 / 1024 > maxSizeMb) {
ElMessage.error(`图片大小不能超过 ${maxSizeMb}MB`)
categoryImageUploadRef.value?.clearFiles()
return
}
try {
ElMessage.info('图片正在上传...')
+5 -4
View File
@@ -1474,7 +1474,7 @@
<el-table-column label="供货价" min-width="110" align="center">
<template #default="{ row }">
<span v-if="!orderPriceVersionDetail?.quotationId">-</span>
<span v-else>¥{{ (Number(row.supplierPrice || 0) || 0).toFixed(2) }}</span>
<span v-else>¥{{ formatAmount(row.supplierPrice || 0) }}</span>
</template>
</el-table-column>
<el-table-column label="供货金额" min-width="110" align="center">
@@ -1482,7 +1482,7 @@
</el-table-column>
<el-table-column label="商品售价" min-width="110" align="center">
<template #default="{ row }"
>¥{{ (Number(row.finalPrice ?? row.price) || 0).toFixed(2) }}</template
>¥{{ formatAmount(row.finalPrice ?? row.price) }}</template
>
</el-table-column>
<el-table-column label="商品金额" min-width="110" align="center">
@@ -1548,6 +1548,7 @@
import { useUserStore } from '@/store/modules/user'
import { fetchAllPagedRecords } from '@/utils/fetch-paged-list'
import { ensureCategoryPathDataLoaded, formatCategoryPathLabel } from '@/utils/category-path-display'
import { formatMoneyDisplay } from '@/utils/money-format'
defineOptions({ name: 'OrderManagement' })
@@ -2061,8 +2062,8 @@
}
const formatAmount = (amount: number | string) => {
const num = typeof amount === 'string' ? parseFloat(amount) : amount
return isNaN(num) ? '0.00' : num.toFixed(2)
if (amount == null || amount === '') return '0.00'
return formatMoneyDisplay(amount)
}
const displayValue = (value: any) => {
Loaded 100 of 102 files, more files were not shown because too many files have changed in this diff. Show more