refactor: 重构工艺工序相关命名与数据模型

1.  全局替换"工序"为"工艺"统一术语,包括页面文案、枚举、注释
2.  重构工单与工件工艺数据模型:
    - 新增工艺组合表flow_material作为备料/齐套唯一源头
    - 新增工位状态表station_state支持自主停单/恢复接单
    - 移除station_process派工表,改用工单工艺组合作为路线唯一源头
    - 替换processCode为flowId作为工艺关联标识
    - 重构工件当前进度字段为currentStationNo
3.  删除冗余的静态备份资源文件
4.  调整物料选择组件默认启用仅显示激活物料
5.  优化工单创建/编辑逻辑,新增工艺组合校验与保存
This commit is contained in:
SunYF
2026-09-22 11:32:29 +08:00
parent 932700ca65
commit d609ff8a9e
185 changed files with 8623 additions and 4501 deletions
@@ -12,6 +12,7 @@ const props = defineProps({
manageMode: { type: Number, default: 0 }, // 0=全部 1=结构件 2=电气件
itemType: { type: Number, default: 0 }, // 0=全部 1原材料 2半成品 3成品 4其他
excludeItemType: { type: Number, default: 0 }, // 排除指定品类,如结构件/电气件入库排除「其他」(4)
onlyActive: { type: Boolean, default: true }, // 下拉默认仅显示启用物料(停用物料不在新建入库/备料等下拉出现)
placeholder: { type: String, default: '选择物料' },
clearable: { type: Boolean, default: true },
width: { type: String, default: '100%' }
@@ -50,7 +51,8 @@ async function load(kw = '') {
page: 1, pageSize: 100, keyword: kw || '',
manageMode: props.manageMode || '',
itemType: props.itemType || '',
excludeItemType: props.excludeItemType || ''
excludeItemType: props.excludeItemType || '',
isActive: props.onlyActive ? 'true' : ''
}
})
options.value = data?.list || []
+13 -4
View File
@@ -301,7 +301,7 @@ const mEditingId = ref(0)
const mForm = reactive({
code: '', name: '', spec: '', unit: '',
manageMode: 1, templateCode: '', description: '',
itemType: 1, safetyStock: 0
itemType: 1, safetyStock: 0, isActive: true
})
const mSaving = ref(false)
@@ -338,7 +338,7 @@ function resetMForm() {
Object.assign(mForm, {
code: '', name: '', spec: '', unit: '',
manageMode: 1, templateCode: '', description: '',
itemType: 1, safetyStock: 0
itemType: 1, safetyStock: 0, isActive: true
})
}
@@ -355,7 +355,8 @@ function openMatEdit(row) {
templateCode: row.templateCode || '',
itemType: row.itemType || 1,
safetyStock: row.safetyStock || 0,
description: row.description || ''
description: row.description || '',
isActive: row.isActive !== false
})
matDialog.value = true
}
@@ -402,7 +403,8 @@ async function saveMaterial() {
description: mForm.description,
itemType: Number(mForm.itemType),
manageMode,
safetyStock: Number(mForm.safetyStock) || 0
safetyStock: Number(mForm.safetyStock) || 0,
isActive: !!mForm.isActive
}
if (mEditingId.value) {
await request.post('/material/update', { id: mEditingId.value, ...base })
@@ -922,6 +924,9 @@ async function onMaterialFile(e) {
<el-table-column label="安全库存" width="100" align="center">
<template #default="{ row }">{{ row.safetyStock || 0 }}</template>
</el-table-column>
<el-table-column label="启用" width="80" align="center">
<template #default="{ row }"><el-tag :type="row.isActive !== false ? 'success' : 'info'" size="small">{{ row.isActive !== false ? '启用' : '停用' }}</el-tag></template>
</el-table-column>
<el-table-column label="创建时间" width="155" align="center">
<template #default="{ row }">{{ fmtTime(row.createdAt) }}</template>
</el-table-column>
@@ -976,6 +981,10 @@ async function onMaterialFile(e) {
<el-form-item label="说明">
<el-input v-model="mForm.description" type="textarea" :rows="2" placeholder="备注可空" />
</el-form-item>
<el-form-item label="启用">
<el-switch v-model="mForm.isActive" />
<span style="color:#909399;font-size:12px;margin-left:8px">停用后不在新建入库 / 备料下拉出现</span>
</el-form-item>
</el-form>
<AttachmentPanel v-if="mEditingId" biz-type="material" :biz-id="mForm.code" title="附件零件图纸 / 资料" />
<template #footer>
-1
View File
@@ -251,7 +251,6 @@ func applyColumnPatches(ctx context.Context) {
`CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_outbound_orders_material_code ON outbound_orders (material_code)`,
`CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_outbound_orders_inspection_no ON outbound_orders (inspection_no)`,
`CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_inventories_inbound_no ON inventories (inbound_no)`,
`CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_inventories_outbound_no ON inventories (outbound_no)`,
`CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_inventories_material_code ON inventories (material_code)`,
`CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_inventories_quality_status ON inventories (quality_status)`,
`CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_inventories_manage_mode ON inventories (manage_mode)`,
@@ -62,6 +62,7 @@ func createMaterialHandler(ctx *svc.ServiceContext) http.HandlerFunc {
TemplateCode string `json:"templateCode"`
ItemType int `json:"itemType"` // 1原材料/2半成品/3成品/4其他
SafetyStock int `json:"safetyStock"` // 安全库存(低于触发缺货预警)
IsActive *bool `json:"isActive"` // 启用状态(nil 视为启用)
}
if err := parseJSON(r, &req); err != nil {
fail(w, http.StatusBadRequest, "参数错误")
@@ -106,6 +107,7 @@ func createMaterialHandler(ctx *svc.ServiceContext) http.HandlerFunc {
SetNillableTemplateCode(strPtr(req.TemplateCode)).
SetItemType(itemType).
SetSafetyStock(req.SafetyStock).
SetIsActive(req.IsActive == nil || *req.IsActive).
Save(ctx0())
if err != nil {
logx.Errorf("create material failed: %v", err)
@@ -131,6 +133,7 @@ func updateMaterialHandler(ctx *svc.ServiceContext) http.HandlerFunc {
ManageMode int `json:"manageMode"`
ItemType int `json:"itemType"`
SafetyStock int `json:"safetyStock"`
IsActive *bool `json:"isActive"`
}
if err := parseJSON(r, &req); err != nil || req.ID <= 0 {
fail(w, http.StatusBadRequest, "参数错误")
@@ -155,6 +158,7 @@ func updateMaterialHandler(ctx *svc.ServiceContext) http.HandlerFunc {
SetDescription(req.Description).
SetItemType(req.ItemType).
SetSafetyStock(req.SafetyStock).
SetIsActive(req.IsActive == nil || *req.IsActive).
SetManageMode(manageMode).
SetIsBatchManaged(manageMode == 1 || manageMode == invManageOther).
SetIsSerialManaged(manageMode == 2).
@@ -243,6 +247,11 @@ func queryMaterialsHandler(ctx *svc.ServiceContext) http.HandlerFunc {
),
)
}
// 启用过滤:下拉选择(新建入库/备料等)传 isActive=true 仅显示启用物料;
// 物料档案管理页不传,显示全部以便重新启用。
if isActiveStr := r.URL.Query().Get("isActive"); isActiveStr != "" {
q = q.Where(material.IsActiveEQ(isActiveStr == "true" || isActiveStr == "1"))
}
if startDate != "" {
if t, err := time.ParseInLocation("2006-01-02", startDate, time.Local); err == nil {
q = q.Where(material.CreatedAtGTE(t.Unix()))
+22 -19
View File
@@ -85,15 +85,16 @@ func listProductTypesInternalHandler(ctx *svc.ServiceContext) http.HandlerFunc {
}
type productTypeRow struct {
ID int `json:"id"`
Code string `json:"code"`
Name string `json:"name"`
Spec string `json:"spec"`
Unit string `json:"unit"`
Category string `json:"category"`
IsActive bool `json:"isActive"`
CreatedAt int64 `json:"createdAt"`
UpdatedAt int64 `json:"updatedAt"`
ID int `json:"id"`
Code string `json:"code"`
Name string `json:"name"`
Spec string `json:"spec"`
Unit string `json:"unit"`
Category string `json:"category"`
ManageMode int `json:"manageMode"` // 1结构件(批次)/2电气件(SN)
IsActive bool `json:"isActive"`
CreatedAt int64 `json:"createdAt"`
UpdatedAt int64 `json:"updatedAt"`
}
func productTypeRows(list []*ent.Material) []*productTypeRow {
@@ -105,8 +106,9 @@ func productTypeRows(list []*ent.Material) []*productTypeRow {
Name: m.Name,
Spec: m.Spec,
Unit: m.Unit,
Category: m.Description, // MES 迁移时 category 存于 description
IsActive: m.IsActive,
Category: m.Description, // MES 迁移时 category 存于 description
ManageMode: m.ManageMode,
IsActive: m.IsActive,
CreatedAt: m.CreatedAt,
UpdatedAt: m.UpdatedAt,
})
@@ -140,14 +142,15 @@ func genProductTypeCode(ctx *svc.ServiceContext) (string, error) {
// WMS 物料档案共用一张表,必填口径一致(图号/名称/规格/单位/品类/类型)。
func createProductTypeInternalHandler(ctx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req struct {
Code string `json:"code"`
Name string `json:"name"`
Spec string `json:"spec"`
Unit string `json:"unit"`
Category string `json:"category"`
IsActive *bool `json:"isActive"`
}
var req struct {
Code string `json:"code"`
Name string `json:"name"`
Spec string `json:"spec"`
Unit string `json:"unit"`
Category string `json:"category"`
ManageMode int `json:"manageMode"` // 1结构件批次/2电气件SN,0=默认电气件
IsActive *bool `json:"isActive"`
}
if err := parseJSON(r, &req); err != nil {
fail(w, http.StatusBadRequest, "参数错误")
return
+1 -1
View File
@@ -6,7 +6,7 @@
<title>WMS库房管理</title>
<!-- 系统图标:库房箱体(内联 SVG,避免依赖外部文件) -->
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' rx='6' fill='%231668dc'/><path d='M16 7l9 4.5v9L16 25l-9-4.5v-9L16 7z' fill='none' stroke='%23fff' stroke-width='2' stroke-linejoin='round'/><path d='M7 11.5L16 16l9-4.5M16 16v9' fill='none' stroke='%23fff' stroke-width='2' stroke-linejoin='round'/></svg>">
<script type="module" crossorigin src="/assets/index-BXnme_NE.js"></script>
<script type="module" crossorigin src="/assets/index-CaL-0-_E.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-hzpIaM_X.css">
</head>
<body>
@@ -1 +0,0 @@
.toolbar[data-v-e7da9fc8]{display:flex;align-items:center;gap:8px;margin-bottom:12px;flex-wrap:wrap}.tip[data-v-e7da9fc8]{color:#909399;font-size:12px;margin-left:4px}.dock-grid[data-v-e7da9fc8]{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}.dock-card[data-v-e7da9fc8]{border:1px solid #e4e7ed;border-radius:8px;padding:12px;text-align:center;transition:all .2s}.dock-card.busy[data-v-e7da9fc8]{background:#fdf6ec;border-color:#e6a23c}.dock-card.line[data-v-e7da9fc8]{border-left:4px solid #409eff}.dock-card.wh[data-v-e7da9fc8]{border-left:4px solid #67c23a}.dock-code[data-v-e7da9fc8]{font-size:18px;font-weight:700}.dock-name[data-v-e7da9fc8]{font-size:12px;color:#909399;margin:4px 0}.dock-status[data-v-e7da9fc8]{font-size:13px;font-weight:600;color:#67c23a}.dock-card.busy .dock-status[data-v-e7da9fc8]{color:#e6a23c}.dock-ref[data-v-e7da9fc8]{font-size:12px;color:#e6a23c;margin-top:2px}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.mb12[data-v-699f5561]{margin-bottom:12px}.pager[data-v-699f5561]{display:flex;justify-content:flex-end;margin-top:10px}.tip[data-v-699f5561]{color:#909399;font-size:12px;line-height:1.6;margin:0 0 10px}.preview[data-v-699f5561]{margin-top:10px;font-size:13px;color:#e6a23c}
@@ -1 +0,0 @@
.attachment-panel[data-v-466f8936]{margin-top:6px}.ap-head[data-v-466f8936]{display:flex;align-items:center;gap:12px;margin-bottom:8px}.ap-title[data-v-466f8936]{font-weight:600;color:#303133}.ap-tip[data-v-466f8936]{color:#909399;font-size:12px}
@@ -1 +0,0 @@
import{_ as E,L as P,r as c,N as S,o as w,c as $,d as v,t as r,a as i,w as l,f as n,P as q,q as F,v as M,g,i as _,E as h,Q as j}from"./index-Bbn7KMl5.js";import{a as V}from"./format-CikLbX2T.js";const O={class:"attachment-panel"},K={class:"ap-head"},L={class:"ap-title"},Q=Object.assign({name:"AttachmentPanel"},{__name:"AttachmentPanel",props:{bizType:{type:String,required:!0},bizId:{type:String,default:""},title:{type:String,default:"附件"},disabled:{type:Boolean,default:!1}},setup(s,{expose:k}){const d=s,u=_([]),m=_(!1),b=_(!1);async function p(){if(!d.bizId){u.value=[];return}m.value=!0;try{const e=await g.get("/attachments",{params:{bizType:d.bizType,bizId:d.bizId}});u.value=(e==null?void 0:e.list)||[]}catch{u.value=[]}finally{m.value=!1}}async function x(e){const t=new FormData;t.append("file",e.file),t.append("bizType",d.bizType),t.append("bizId",d.bizId),b.value=!0;try{await g.post("/attachments/upload",t),h.success("上传成功"),await p()}finally{b.value=!1}}function B(e){window.open(e.url,"_blank")}function z(e){const t=document.createElement("a");t.href=e.url+"?dl=1",t.download=e.fileName||"",document.body.appendChild(t),t.click(),document.body.removeChild(t)}async function C(e){try{await j.confirm(`确认删除附件「${e.fileName}」?`,"删除确认",{type:"warning"})}catch{return}await g.post("/attachments/delete",{id:e.id}),h.success("已删除"),await p()}function I(e){return e?e<1024?e+" B":e<1024*1024?(e/1024).toFixed(1)+" KB":(e/1024/1024).toFixed(2)+" MB":"-"}return P(()=>[d.bizType,d.bizId],p,{immediate:!0}),k({load:p}),(e,t)=>{const f=c("el-button"),T=c("el-upload"),N=c("el-link"),o=c("el-table-column"),A=c("el-table"),D=S("loading");return w(),$("div",O,[v("div",K,[v("span",L,r(s.title),1),i(T,{"auto-upload":!0,"show-file-list":!1,"http-request":x,accept:".pdf,.png,.jpg,.jpeg,.gif,.xlsx,.xls,.doc,.docx,.dwg,.dxf,.zip,.txt,.csv",disabled:!s.bizId||s.disabled},{default:l(()=>[i(f,{type:"primary",plain:"",size:"small",loading:b.value,disabled:!s.bizId||s.disabled},{default:l(()=>[...t[0]||(t[0]=[n(" 上传附件 ",-1)])]),_:1},8,["loading","disabled"])]),_:1},8,["disabled"]),t[1]||(t[1]=v("span",{class:"ap-tip"},"支持 PDF / 图纸 / 图片 / Office,单个不超过 20MB;点文件名或「下载」下载,点「查看」新窗口预览",-1))]),q((w(),F(A,{data:u.value,size:"small",border:"","empty-text":"暂无附件"},{default:l(()=>[i(o,{label:"文件名","min-width":"200","show-overflow-tooltip":""},{default:l(({row:a})=>[i(N,{type:"primary",underline:!1,onClick:y=>z(a)},{default:l(()=>[n(r(a.fileName),1)]),_:2},1032,["onClick"])]),_:1}),i(o,{label:"大小",width:"100",align:"center"},{default:l(({row:a})=>[n(r(I(a.fileSize)),1)]),_:1}),i(o,{prop:"uploadedBy",label:"上传人",width:"110",align:"center"},{default:l(({row:a})=>[n(r(a.uploadedBy||"-"),1)]),_:1}),i(o,{label:"上传时间",width:"165",align:"center"},{default:l(({row:a})=>[n(r(M(V)(a.createdAt)),1)]),_:1}),i(o,{label:"操作",width:"180",align:"center"},{default:l(({row:a})=>[i(f,{link:"",type:"primary",size:"small",onClick:y=>B(a)},{default:l(()=>[...t[2]||(t[2]=[n("查看",-1)])]),_:1},8,["onClick"]),i(f,{link:"",type:"primary",size:"small",onClick:y=>z(a)},{default:l(()=>[...t[3]||(t[3]=[n("下载",-1)])]),_:1},8,["onClick"]),i(f,{link:"",type:"danger",size:"small",disabled:s.disabled,onClick:y=>C(a)},{default:l(()=>[...t[4]||(t[4]=[n("删除",-1)])]),_:1},8,["disabled","onClick"])]),_:1})]),_:1},8,["data"])),[[D,m.value]])])}}}),H=E(Q,[["__scopeId","data-v-466f8936"]]);export{H as A};
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.pager[data-v-530bad98]{display:flex;justify-content:flex-end;margin-top:10px}
@@ -1 +0,0 @@
import{q as p,w as a,r as l,u as x,o as i,a as s,O as v,m as C,f,d as h,h as k,n as N,E as r,g as U,U as B,i as q}from"./index-Bbn7KMl5.js";const A={__name:"ChangePassword",setup(E){const c=x(),d=q(!1),e=k({oldPassword:"",newPassword:"",confirmPassword:""}),P=N(()=>e.newPassword.length>0&&/^[\d]+$/.test(e.newPassword));async function _(){if(!e.oldPassword||!e.newPassword)return r.warning("请填写旧密码和新密码");if(e.newPassword!==e.confirmPassword)return r.warning("两次输入的新密码不一致");if(e.newPassword.length<6)return r.warning("新密码长度至少 6 位");d.value=!0;try{await U.post("/user/change-password",{oldPassword:e.oldPassword,newPassword:e.newPassword}),r.success("密码修改成功,请重新登录"),B(),c.replace("/login")}catch{}finally{d.value=!1}}function g(){e.oldPassword="",e.newPassword="",e.confirmPassword=""}return(y,o)=>{const u=l("el-alert"),w=l("el-input"),n=l("el-form-item"),m=l("el-button"),V=l("el-form"),b=l("el-card");return i(),p(b,{style:{"max-width":"480px","margin-top":"20px"}},{header:a(()=>[...o[4]||(o[4]=[h("b",null,"修改我的密码",-1)])]),default:a(()=>[s(u,{type:"warning",closable:!1,style:{"margin-bottom":"16px"},title:"密码修改成功后需重新登录"}),s(V,{model:e,"label-width":"100px",onSubmit:o[3]||(o[3]=v(()=>{},["prevent"]))},{default:a(()=>[s(n,{label:"旧密码"},{default:a(()=>[s(w,{modelValue:e.oldPassword,"onUpdate:modelValue":o[0]||(o[0]=t=>e.oldPassword=t),type:"password","show-password":"",placeholder:"请输入当前密码"},null,8,["modelValue"])]),_:1}),s(n,{label:"新密码"},{default:a(()=>[s(w,{modelValue:e.newPassword,"onUpdate:modelValue":o[1]||(o[1]=t=>e.newPassword=t),type:"password","show-password":"",placeholder:"至少 6 位"},null,8,["modelValue"]),P.value?(i(),p(u,{key:0,type:"warning",closable:!1,style:{"margin-top":"6px",width:"100%"},title:"密码为纯数字,安全性较低,建议包含字母与数字组合"})):C("",!0)]),_:1}),s(n,{label:"确认新密码"},{default:a(()=>[s(w,{modelValue:e.confirmPassword,"onUpdate:modelValue":o[2]||(o[2]=t=>e.confirmPassword=t),type:"password","show-password":"",placeholder:"请再次输入新密码"},null,8,["modelValue"])]),_:1}),s(n,null,{default:a(()=>[s(m,{type:"primary",loading:d.value,onClick:_},{default:a(()=>[...o[5]||(o[5]=[f("保存",-1)])]),_:1},8,["loading"]),s(m,{onClick:g},{default:a(()=>[...o[6]||(o[6]=[f("重置",-1)])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1})}}};export{A as default};
@@ -1 +0,0 @@
import{_ as Q,j as V,c as _,a as e,w as a,q as m,m as T,g as f,r as o,i as u,u as j,o as i,F as y,l as b,d as r,t as n,v as k,f as v,x as q,y as F,z as A,A as E,B as G,C as H,D as J,G as L,H as M,I as O,J as R}from"./index-Bbn7KMl5.js";import{f as $}from"./format-CikLbX2T.js";const K={class:"kpi-label"},P={class:"kpi-value"},U={style:{color:"#f56c6c","font-weight":"600"}},W={style:{color:"#f56c6c","font-weight":"600"}},X={class:"entries"},Y=Object.assign({name:"Dashboard"},{__name:"Dashboard",setup(Z){const g=j(),p=u({}),h=u(!1),s=u([]);async function w(){p.value=await f.get("/display/overview"),h.value=!0}async function x(){try{const c=await f.get("/stock/shortage");s.value=(c==null?void 0:c.list)||[]}catch{s.value=[]}}V(()=>{w(),x()});const C=[{key:"totalQty",label:"在库总量"},{key:"lockedQty",label:"锁定量"},{key:"snInStock",label:"SN 在库数"},{key:"semiInStock",label:"半成品在库"},{key:"packageCount",label:"装箱出库"},{key:"batchCount",label:"批次数"},{key:"inToday",label:"今日入库单"},{key:"outToday",label:"今日出库单"}],N=[{path:"/inbound",title:"入库管理",icon:q},{path:"/outbound",title:"备料出库",icon:F},{path:"/inventory",title:"库存查询",icon:A},{path:"/inspection",title:"质量检验",icon:E},{path:"/stocktake",title:"库存盘点",icon:G},{path:"/semi",title:"半成品管理",icon:H},{path:"/ledger",title:"工单备料台账",icon:J},{path:"/zone",title:"区域维护",icon:L},{path:"/material",title:"物料档案",icon:M},{path:"/display",title:"免登录大屏",icon:O}];return(c,ee)=>{const d=o("el-card"),D=o("el-col"),S=o("el-row"),l=o("el-table-column"),B=o("el-table"),z=o("el-icon"),I=o("el-button");return i(),_("div",null,[e(S,{gutter:12},{default:a(()=>[(i(),_(y,null,b(C,t=>e(D,{key:t.key,xs:12,sm:8,md:6,style:{"margin-bottom":"12px"}},{default:a(()=>[e(d,{shadow:"hover"},{default:a(()=>[r("div",K,n(t.label),1),r("div",P,n(h.value?k($)(p.value[t.key]):"—"),1)]),_:2},1024)]),_:2},1024)),64))]),_:1}),s.value.length?(i(),m(d,{key:0,shadow:"never",class:"mb12",style:{"margin-top":"12px"}},{header:a(()=>[r("span",U,"缺货预警("+n(s.value.length)+" 项物料可用量低于安全库存)",1)]),default:a(()=>[e(B,{data:s.value,border:"",size:"small","empty-text":"暂无缺货物料"},{default:a(()=>[e(l,{prop:"materialCode",label:"图号","min-width":"140"}),e(l,{prop:"materialName",label:"物料名称","min-width":"150"}),e(l,{prop:"spec",label:"规格","min-width":"110"},{default:a(({row:t})=>[v(n(t.spec||"-"),1)]),_:1}),e(l,{prop:"safetyStock",label:"安全库存",width:"100",align:"center"}),e(l,{prop:"availQty",label:"可用量",width:"90",align:"center"}),e(l,{label:"缺口",width:"90",align:"center"},{default:a(({row:t})=>[r("span",W,n(t.shortQty),1)]),_:1})]),_:1},8,["data"])]),_:1})):T("",!0),e(d,{shadow:"never",header:"快捷入口"},{default:a(()=>[r("div",X,[(i(),_(y,null,b(N,t=>e(I,{key:t.path,size:"large",onClick:te=>k(g).push(t.path)},{default:a(()=>[e(z,{style:{"margin-right":"6px"}},{default:a(()=>[(i(),m(R(t.icon)))]),_:2},1024),v(n(t.title),1)]),_:2},1032,["onClick"])),64))])]),_:1})])}}}),le=Q(Y,[["__scopeId","data-v-58fedaa4"]]);export{le as default};
@@ -1 +0,0 @@
.kpi-label[data-v-58fedaa4]{color:#909399;font-size:13px}.kpi-value[data-v-58fedaa4]{font-size:26px;font-weight:700;margin-top:4px;color:#303133}.entries[data-v-58fedaa4]{display:flex;flex-wrap:wrap;gap:10px}
@@ -1 +0,0 @@
import{_ as w,j as S,k as z,c as i,d as t,t as o,F as m,l as k,m as I,i as g,g as q,n as r,o as c,p as D}from"./index-Bbn7KMl5.js";import{f as n}from"./format-CikLbX2T.js";const $={class:"screen"},N={class:"head"},T={class:"side right"},x={class:"date"},M={class:"time"},Q={class:"kpi-grid"},B={class:"kpi-value"},C={class:"kpi-label"},j={class:"zones"},F={class:"zone-list"},L={class:"zone-name"},O={class:"bar-wrap"},V={class:"zone-qty"},E={key:0,class:"empty"},H={__name:"Display",setup(U){const v=g(new Date);let y=null,p=null;const l=g({}),h=r(()=>{const a=Object.values(u.value).map(e=>Number(e.qty)||0);return Math.max(...a,1)}),u=r(()=>{const a=l.value.zoneDetail||{};return Object.entries(a).map(([e,s])=>({zone:e,qty:Number(s)||0})).sort((e,s)=>s.qty-e.qty)}),b=r(()=>[{key:"totalQty",label:"在库总量",value:n(l.value.totalQty)},{key:"lockedQty",label:"锁定量",value:n(l.value.lockedQty)},{key:"snInStock",label:"SN 在库",value:n(l.value.snInStock)},{key:"semiInStock",label:"半成品在库",value:n(l.value.semiInStock)},{key:"packageCount",label:"包装箱数",value:n(l.value.packageCount)},{key:"inToday",label:"今日入库单",value:n(l.value.inToday)},{key:"outToday",label:"今日出库单",value:n(l.value.outToday)}]),f=["周日","周一","周二","周三","周四","周五","周六"],d=r(()=>{const a=v.value,e=s=>String(s).padStart(2,"0");return{date:`${a.getFullYear()}-${e(a.getMonth()+1)}-${e(a.getDate())}`,time:`${e(a.getHours())}:${e(a.getMinutes())}:${e(a.getSeconds())}`,week:`星期${f[a.getDay()].replace("周","")}`}});async function _(){try{l.value=await q.get("/display/overview")}catch{}}return S(()=>{y=setInterval(()=>{v.value=new Date},1e3),_(),p=setInterval(_,5e3)}),z(()=>{clearInterval(y),clearInterval(p)}),(a,e)=>(c(),i("div",$,[t("header",N,[e[0]||(e[0]=t("div",{class:"side left"},"库房监控",-1)),e[1]||(e[1]=t("h1",{class:"title"},"库存动态大屏",-1)),t("div",T,[t("span",x,o(d.value.date),1),t("span",M,o(d.value.time),1),t("span",null,o(d.value.week),1)])]),t("section",Q,[(c(!0),i(m,null,k(b.value,s=>(c(),i("div",{key:s.key,class:"kpi"},[t("div",B,o(s.value),1),t("div",C,o(s.label),1)]))),128))]),t("section",j,[e[2]||(e[2]=t("div",{class:"zone-title"},"区域明细(区域 / 质量状态)",-1)),t("div",F,[(c(!0),i(m,null,k(u.value,s=>(c(),i("div",{key:s.zone,class:"zone-row"},[t("div",L,o(s.zone),1),t("div",O,[t("div",{class:"bar",style:D({width:`${s.qty/h.value*100}%`})},null,4)]),t("div",V,o(s.qty.toLocaleString("zh-CN")),1)]))),128)),u.value.length?I("",!0):(c(),i("div",E,"暂无区域数据…"))])]),e[3]||(e[3]=t("footer",{class:"foot"},"数据来源:WMS 后端 · 每 5 秒自动刷新",-1))]))}},Z=w(H,[["__scopeId","data-v-e0ddabf0"]]);export{Z as default};
@@ -1 +0,0 @@
.screen[data-v-e0ddabf0]{min-height:100vh;background:radial-gradient(ellipse at 50% 0%,rgba(0,170,255,.18),transparent 55%),linear-gradient(180deg,#04102a,#071e42 60%,#04102a);color:#d7ecff;display:flex;flex-direction:column;font-family:Microsoft YaHei,PingFang SC,sans-serif}.head[data-v-e0ddabf0]{display:flex;align-items:center;justify-content:space-between;padding:18px 36px 10px;border-bottom:1px solid rgba(64,158,255,.35)}.title[data-v-e0ddabf0]{margin:0;font-size:clamp(20px,2.6vw,34px);letter-spacing:8px;color:#fff;text-shadow:0 0 14px rgba(64,190,255,.9)}.side[data-v-e0ddabf0]{font-size:13px;color:#7fb8ff}.right[data-v-e0ddabf0]{text-align:right}.date[data-v-e0ddabf0]{margin-right:12px}.time[data-v-e0ddabf0]{font-size:22px;font-weight:700;color:#4fd7ff;margin-right:8px;font-variant-numeric:tabular-nums}.kpi-grid[data-v-e0ddabf0]{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:14px;padding:22px 36px 6px}.kpi[data-v-e0ddabf0]{border:1px solid rgba(64,158,255,.45);background:linear-gradient(180deg,#0d2f60bf,#071a3ad9);border-radius:8px;padding:18px 10px;text-align:center;box-shadow:inset 0 0 24px #2382ff40}.kpi-value[data-v-e0ddabf0]{font-size:clamp(28px,3vw,46px);font-weight:800;color:#61e6ff;text-shadow:0 0 16px rgba(80,220,255,.7);font-variant-numeric:tabular-nums}.kpi-label[data-v-e0ddabf0]{margin-top:6px;font-size:14px;color:#9cc7ff;letter-spacing:2px}.zones[data-v-e0ddabf0]{flex:1;padding:16px 36px 8px;overflow:auto}.zone-title[data-v-e0ddabf0]{font-size:16px;letter-spacing:3px;color:#bfe0ff;border-left:4px solid #409eff;padding-left:10px;margin-bottom:12px}.zone-row[data-v-e0ddabf0]{display:flex;align-items:center;gap:12px;padding:7px 0;border-bottom:1px dashed rgba(64,158,255,.15)}.zone-name[data-v-e0ddabf0]{width:200px;text-align:right;color:#cfe6ff;font-size:14px}.bar-wrap[data-v-e0ddabf0]{flex:1;height:16px;background:#13386e99;border-radius:9px;overflow:hidden}.bar[data-v-e0ddabf0]{height:100%;border-radius:9px;background:linear-gradient(90deg,#1673ff,#37e2ff);box-shadow:0 0 10px #37d2ffa6;transition:width .6s ease}.zone-qty[data-v-e0ddabf0]{width:90px;color:#61e6ff;font-weight:700;font-variant-numeric:tabular-nums}.empty[data-v-e0ddabf0]{color:#5f86b8;padding:30px 0;text-align:center}.foot[data-v-e0ddabf0]{padding:12px 36px 16px;text-align:center;color:#47709f;font-size:12px}
@@ -1 +0,0 @@
import{j as G,c as L,d as H,a,w as o,v as x,F as N,g as R,r as n,i as _,h as A,N as J,o as v,l as Q,q as C,e as X,m as Z,f as p,P as $,t as f,n as ee,W as te}from"./index-Bbn7KMl5.js";import{a as le}from"./format-CikLbX2T.js";import{m as ae,P as oe}from"./help-BUa6t0xG.js";const ne={class:"evt-page"},pe=Object.assign({name:"EventLog"},{__name:"EventLog",setup(re){const g=[{label:"账号管理",value:"user."},{label:"角色管理",value:"role."},{label:"权限初始化",value:"rbac."},{label:"物料档案",value:"material."},{label:"区域维护",value:"zone."},{label:"入库",value:"inbound."},{label:"出库",value:"outbound."},{label:"质量检验",value:"inspection."},{label:"库存盘点",value:"stocktake."},{label:"半成品",value:"semi."}],y=Object.fromEntries(g.map(t=>[t.value,t.label])),w={"user.":"primary","role.":"warning","rbac.":"danger","material.":"success","zone.":"success","inbound.":"success","outbound.":"warning","inspection.":"info","stocktake.":"info","semi.":"info"},D={user:"账号",role:"角色",rbac:"权限",material:"物料",zone:"区域",inbound:"入库",outbound:"出库",inspection:"检验",stocktake:"盘点",semi:"半成品"};function I(t){const e=Object.keys(y).find(d=>t&&t.startsWith(d));return e?y[e]:t||"-"}function M(t){const e=Object.keys(w).find(d=>t&&t.startsWith(d));return e&&w[e]||"info"}function U(t){return t&&D[t]||t||"-"}const r=A({eventType:"",operator:""}),Y=ee(()=>{var t;return((t=te())==null?void 0:t.role)==="admin"}),i=_(null),k=_([]),T=_(0),b=_(!1),s=A({current:1,size:20});function h(t){const e=new Date(t+"T00:00:00");return Math.floor(e.getTime()/1e3)}async function c(){b.value=!0;try{const t={page:s.current,pageSize:s.size};r.eventType&&(t.eventType=r.eventType),r.operator&&(t.operator=r.operator),i.value&&i.value.length===2&&(t.from=h(i.value[0]),t.to=h(i.value[1])+86400-1);const e=await R.get("/event/logs",{params:t});k.value=(e==null?void 0:e.list)||[],T.value=(e==null?void 0:e.total)||0}finally{b.value=!1}}function z(){s.current=1,c()}function j(){r.eventType="",r.operator="",i.value=null,s.current=1,c()}return G(c),(t,e)=>{const d=n("el-option"),B=n("el-select"),m=n("el-form-item"),S=n("el-input"),F=n("el-date-picker"),V=n("el-button"),O=n("el-form"),E=n("el-card"),u=n("el-table-column"),P=n("el-tag"),W=n("el-table"),q=n("el-pagination"),K=J("loading");return v(),L(N,null,[H("div",ne,[a(E,{shadow:"never"},{default:o(()=>[a(O,{inline:"",model:r},{default:o(()=>[a(m,{label:"事件类型"},{default:o(()=>[a(B,{modelValue:r.eventType,"onUpdate:modelValue":e[0]||(e[0]=l=>r.eventType=l),clearable:"",style:{width:"150px"},placeholder:"全部"},{default:o(()=>[(v(),L(N,null,Q(g,l=>a(d,{key:l.value,label:l.label,value:l.value},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1}),Y.value?(v(),C(m,{key:0,label:"操作人"},{default:o(()=>[a(S,{modelValue:r.operator,"onUpdate:modelValue":e[1]||(e[1]=l=>r.operator=l),clearable:"",style:{width:"130px"},placeholder:"用户名",onKeyup:X(z,["enter"])},null,8,["modelValue"])]),_:1})):Z("",!0),a(m,{label:"时间范围"},{default:o(()=>[a(F,{modelValue:i.value,"onUpdate:modelValue":e[2]||(e[2]=l=>i.value=l),type:"daterange","value-format":"YYYY-MM-DD","range-separator":"至","start-placeholder":"开始日期","end-placeholder":"结束日期",style:{width:"260px"}},null,8,["modelValue"])]),_:1}),a(m,null,{default:o(()=>[a(V,{type:"primary",onClick:z},{default:o(()=>[...e[5]||(e[5]=[p("查询",-1)])]),_:1}),a(V,{onClick:j},{default:o(()=>[...e[6]||(e[6]=[p("重置",-1)])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1}),a(E,{shadow:"never",style:{"margin-top":"12px"}},{default:o(()=>[$((v(),C(W,{data:k.value,border:"",stripe:"",size:"small"},{default:o(()=>[a(u,{prop:"id",label:"ID",width:"70"}),a(u,{label:"事件类型","min-width":"170"},{default:o(({row:l})=>[a(P,{type:M(l.eventType),size:"small"},{default:o(()=>[p(f(I(l.eventType)),1)]),_:2},1032,["type"])]),_:1}),a(u,{prop:"description",label:"描述","min-width":"260","show-overflow-tooltip":""}),a(u,{label:"对象",width:"110"},{default:o(({row:l})=>[p(f(U(l.entityType)),1)]),_:1}),a(u,{prop:"entityId",label:"对象标识",width:"140","show-overflow-tooltip":""}),a(u,{label:"操作人",width:"110"},{default:o(({row:l})=>[p(f(l.operatorName||l.operator||"-"),1)]),_:1}),a(u,{label:"时间",width:"165"},{default:o(({row:l})=>[p(f(x(le)(l.createdAt)),1)]),_:1})]),_:1},8,["data"])),[[K,b.value]]),a(q,{"current-page":s.current,"onUpdate:currentPage":e[3]||(e[3]=l=>s.current=l),"page-size":s.size,"onUpdate:pageSize":e[4]||(e[4]=l=>s.size=l),"page-sizes":[20,50,100],total:T.value,background:"",layout:"total, sizes, prev, pager, next, jumper",style:{"margin-top":"12px"},onSizeChange:c,onCurrentChange:c},null,8,["current-page","page-size","total"])]),_:1})]),a(oe,{data:x(ae),page:"EventLog"},null,8,["data"])],64)}}});export{pe as default};
@@ -1 +0,0 @@
.dropzone[data-v-2292ea10]{padding:30px 0;color:#606266}.mb12[data-v-2292ea10]{margin-bottom:12px}.pager[data-v-2292ea10]{display:flex;justify-content:flex-end;margin-top:12px}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.mb12[data-v-7fa440a7]{margin-bottom:12px}.pager[data-v-7fa440a7]{display:flex;justify-content:flex-end;margin-top:12px}.tip[data-v-7fa440a7]{margin-left:10px;color:#909399;font-size:12px}
@@ -1 +0,0 @@
.mb12[data-v-cdb1fa3c]{margin-bottom:12px}.pager[data-v-cdb1fa3c]{display:flex;justify-content:flex-end;margin-top:12px}.link[data-v-cdb1fa3c]{color:#409eff;cursor:pointer}
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.mb12[data-v-47f50186]{margin-bottom:12px}.pager[data-v-47f50186]{display:flex;justify-content:flex-end;margin-top:10px}
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
import{_ as V,c as k,a as t,w as a,r,u as h,b as x,o as q,d as u,e as C,f as E,g as R,s as S,E as c,h as B,i as f}from"./index-Bbn7KMl5.js";const M={class:"login-page"},N={__name:"Login",setup(K){const _=h(),w=x(),d=f(),l=f(!1),s=B({username:"",password:""}),g={username:[{required:!0,message:"请输入用户名",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]};async function p(){await d.value.validate(),l.value=!0;try{const o=await R.post("/auth/login",{username:s.username,password:s.password});if(!(o!=null&&o.token))throw new Error("登录响应缺少 token");S(o.token,o.user||{}),c.success("登录成功");const e=w.query.redirect;_.push(e&&typeof e=="string"?e:"/"),o.weakPassword&&c.warning({message:"当前密码为纯数字,安全性较低,建议尽快修改密码",duration:8e3,showClose:!0})}finally{l.value=!1}}return(o,e)=>{const i=r("el-input"),m=r("el-form-item"),b=r("el-button"),y=r("el-form"),v=r("el-card");return q(),k("div",M,[t(v,{class:"card"},{default:a(()=>[e[3]||(e[3]=u("div",{class:"head"},[u("h2",null,"WMS库房管理"),u("p",null,"请使用 WMS 账号登录")],-1)),t(y,{ref_key:"formRef",ref:d,model:s,rules:g,"label-position":"top",onKeyup:C(p,["enter"])},{default:a(()=>[t(m,{label:"用户名",prop:"username"},{default:a(()=>[t(i,{modelValue:s.username,"onUpdate:modelValue":e[0]||(e[0]=n=>s.username=n),placeholder:"用户名",autofocus:""},null,8,["modelValue"])]),_:1}),t(m,{label:"密码",prop:"password"},{default:a(()=>[t(i,{modelValue:s.password,"onUpdate:modelValue":e[1]||(e[1]=n=>s.password=n),type:"password","show-password":"",placeholder:"密码"},null,8,["modelValue"])]),_:1}),t(b,{type:"primary",class:"btn",loading:l.value,onClick:p},{default:a(()=>[...e[2]||(e[2]=[E("登 录",-1)])]),_:1},8,["loading"])]),_:1},8,["model"])]),_:1})])}}},U=V(N,[["__scopeId","data-v-731bf80e"]]);export{U as default};
@@ -1 +0,0 @@
.login-page[data-v-731bf80e]{height:100vh;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#1c3faa,#0a1330)}.card[data-v-731bf80e]{width:380px}.head[data-v-731bf80e]{text-align:center;margin-bottom:14px}.head h2[data-v-731bf80e]{margin:0 0 6px}.head p[data-v-731bf80e]{margin:0;color:#909399;font-size:13px}.btn[data-v-731bf80e]{width:100%;margin-top:4px}
@@ -1 +0,0 @@
import{j as S,r as f,o as s,q as y,w as m,c as T,F as V,l as B,d as g,t as u,p as k,g as C,i as h}from"./index-Bbn7KMl5.js";const L={style:{float:"left"}},N={style:{float:"right",color:"#8492a6","font-size":"12px","margin-left":"16px"}},q={__name:"MaterialSelect",props:{modelValue:{type:[String,Array],default:""},multiple:{type:Boolean,default:!1},manageMode:{type:Number,default:0},itemType:{type:Number,default:0},excludeItemType:{type:Number,default:0},placeholder:{type:String,default:"选择物料"},clearable:{type:Boolean,default:!0},width:{type:String,default:"100%"}},emits:["update:modelValue","item-change"],setup(l,{emit:b}){const o=l,i=b,n=h([]),r=h(!1);function d(e){return(e==null?void 0:e.manageMode)===3?"其他":(e==null?void 0:e.manageMode)===2?"电气件":"结构件"}function p(e){switch(e==null?void 0:e.itemType){case 1:return"原材料";case 2:return"半成品";case 3:return"成品";case 4:return"其他";default:return"-"}}function v(e){return`${e.code} ${e.name||""} [${d(e)}·${p(e)}]`}async function c(e=""){r.value=!0;try{const t=await C.get("/material/query",{params:{page:1,pageSize:100,keyword:e||"",manageMode:o.manageMode||"",itemType:o.itemType||"",excludeItemType:o.excludeItemType||""}});n.value=(t==null?void 0:t.list)||[]}catch{n.value=[]}finally{r.value=!1}}function _(e){i("update:modelValue",e),o.multiple?i("item-change",n.value.filter(t=>e.includes(t.code))):i("item-change",n.value.find(t=>t.code===e)||null)}function w(e){e&&c("")}return S(()=>c("")),(e,t)=>{const x=f("el-option"),M=f("el-select");return s(),y(M,{"model-value":l.modelValue,multiple:l.multiple,filterable:"",remote:"",clearable:"","remote-method":c,loading:r.value,placeholder:l.placeholder,style:k({width:l.width}),onChange:_,onVisibleChange:w},{default:m(()=>[(s(!0),T(V,null,B(n.value,a=>(s(),y(x,{key:a.id,value:a.code,label:v(a)},{default:m(()=>[g("span",L,u(a.code)+" "+u(a.name||""),1),g("span",N,u(d(a))+""+u(p(a)),1)]),_:2},1032,["value","label"]))),128))]),_:1},8,["model-value","multiple","loading","placeholder","style"])}}};export{q as _};
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.mb12[data-v-75a95f95]{margin-bottom:12px}.gap[data-v-75a95f95]{color:#f56c6c;font-weight:700}.pager[data-v-75a95f95]{display:flex;justify-content:flex-end;margin-top:10px}
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.mb12[data-v-f566c430]{margin-bottom:12px}.pager[data-v-f566c430]{display:flex;justify-content:flex-end;margin-top:10px}.snbox[data-v-f566c430]{margin-top:8px;display:flex;flex-wrap:wrap;gap:6px;max-height:140px;overflow:auto}.sntag[data-v-f566c430]{font-family:monospace}
@@ -1 +0,0 @@
.mb12[data-v-4943d041]{margin-bottom:12px}.perm-tree[data-v-4943d041]{border:1px solid #ebeef5;border-radius:4px;padding:12px;max-height:340px;overflow:auto}.perm-tip[data-v-4943d041]{color:#909399;font-size:12px;margin-bottom:8px}
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.pager[data-v-dcdba065]{display:flex;justify-content:flex-end;margin-top:10px}
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.mb12[data-v-6e0ebea1]{margin-bottom:12px}.mt12[data-v-6e0ebea1]{margin-top:12px}.tip[data-v-6e0ebea1]{margin-left:10px;color:#909399;font-size:12px}.bad[data-v-6e0ebea1]{color:#f56c6c;font-weight:700}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.mb12[data-v-9d3ca88a]{margin-bottom:12px}
@@ -1 +0,0 @@
import{Q as c}from"./index-Bbn7KMl5.js";async function o(t,n="操作确认",r={}){try{return await c.confirm(t,n,{type:"warning",confirmButtonText:"确认",cancelButtonText:"取消",...r}),!0}catch{return!1}}export{o as c};
@@ -1 +0,0 @@
import{T as w,g as p}from"./index-Bbn7KMl5.js";import{c as x}from"./confirm-BZ-2P3wV.js";async function b(t,n="数据"){const e=t==null?`即将导出全部${n},是否继续?`:`即将导出 ${t}${n},是否继续?`;return x(e,"导出确认",{confirmButtonText:"确认导出",cancelButtonText:"取消"})}function m(t){const n=e=>String(e).padStart(2,"0");return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}`}function y(t){if(!t||!("startDate"in t)&&!("endDate"in t))return t;let n=t.startDate||"",e=t.endDate||"";if(n&&!e)e=m(new Date);else if(!n&&e){const o=new Date(e);o.setMonth(o.getMonth()-3),n=m(o)}return{...t,startDate:n,endDate:e}}async function D(t,n){try{const e=await p.get(t,{params:{...n,page:1,pageSize:1}}),o=e==null?void 0:e.total;return o==null?null:Number(o)}catch{return null}}async function R(t,n,e="导出.xlsx",o=!0){const s=y(n);if(o){const r=o===!0?{}:o;let u=r.count===null||r.count===void 0?null:r.count;if(u===null&&r.countUrl&&(u=await D(r.countUrl,s)),!await b(u,r.name))return null}const h=new URLSearchParams({format:"xlsx",...s}).toString(),l=await fetch(`${t}?${h}`,{headers:{Authorization:`Bearer ${w()}`}});if(!l.ok){const r=await l.json().catch(()=>({}));throw new Error(r.message||"导出失败")}let c=e;const f=l.headers.get("Content-Disposition")||"";let a=f.match(/filename\*=UTF-8''([^;]+)/i);a?c=decodeURIComponent(a[1])||c:(a=f.match(/filename="?([^";]+)"?/),a&&(c=decodeURIComponent(a[1])));const g=await l.blob(),d=URL.createObjectURL(g),i=document.createElement("a");return i.href=d,i.download=c,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(d),c}export{R as e};
@@ -1 +0,0 @@
function u(e){if(!e)return"-";const t=new Date(typeof e=="number"?e*1e3:e);if(Number.isNaN(t.getTime()))return String(e);const n=r=>String(r).padStart(2,"0");return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`}function i(e){const t=Number(e);return Number.isNaN(t)?e??"-":t.toLocaleString("zh-CN")}export{u as a,i as f};
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.page-help[data-v-4f00c6fa]{position:fixed;left:18px;bottom:18px;z-index:2050}.help-fab[data-v-4f00c6fa]{width:42px;height:42px;background:#1668dc;color:#fff;font-weight:700;font-size:20px;box-shadow:0 3px 10px #16324f4d;transition:transform .15s}.help-fab[data-v-4f00c6fa]:hover{background:#0e57c3;transform:scale(1.06)}.ph-inner[data-v-4f00c6fa]{padding:0 6px 24px}.ph-banner[data-v-4f00c6fa]{background:linear-gradient(120deg,#1668dc,#3a98f0);color:#fff;border-radius:10px;padding:16px 18px;margin-bottom:16px}.ph-banner-title[data-v-4f00c6fa]{font-size:20px;font-weight:700}.ph-banner-sub[data-v-4f00c6fa]{font-size:12px;opacity:.85;margin-top:4px}.ph-overview[data-v-4f00c6fa]{color:#3f536e;line-height:1.8;font-size:14px;margin-bottom:16px;background:#f4f7fb;border:1px solid #e4ecf5;border-radius:8px;padding:12px 14px;white-space:pre-line}.ph-legend[data-v-4f00c6fa]{display:flex;flex-wrap:wrap;gap:12px 16px;margin-bottom:16px;padding:10px 14px;background:#fafbfc;border:1px dashed #d9e0e8;border-radius:8px;font-size:12px;color:#6b7785}.ph-legend .lg[data-v-4f00c6fa]{display:inline-flex;align-items:center;gap:6px}.ph-legend .ic[data-v-4f00c6fa]{display:inline-block;width:10px;height:10px;border-radius:3px}.lg-source[data-v-4f00c6fa]{background:#8fa5f5}.lg-purpose[data-v-4f00c6fa]{background:#22b07d}.lg-fill[data-v-4f00c6fa]{background:#f5a623}.ph-section[data-v-4f00c6fa]{margin-bottom:18px}.ph-sec-title[data-v-4f00c6fa]{font-size:15px;font-weight:700;color:#1b2a3a;margin:0 0 4px;padding-left:10px;border-left:4px solid #1668dc;line-height:1.4}.ph-sec-overview[data-v-4f00c6fa]{color:#7a8694;font-size:13px;margin:4px 0 10px;line-height:1.7}.ph-field[data-v-4f00c6fa]{background:#fff;border:1px solid #eef1f6;border-radius:8px;padding:10px 14px;margin-bottom:8px}.ph-fname[data-v-4f00c6fa]{display:flex;align-items:center;gap:8px;font-weight:700;color:#1b2a3a;font-size:14px}.ph-fsource[data-v-4f00c6fa]{font-weight:400;font-size:11px;color:#1668dc;background:#e8f1ff;border-radius:4px;padding:1px 8px}.ph-fpurpose[data-v-4f00c6fa]{color:#22b07d;font-size:13px;line-height:1.6;margin-top:6px}.ph-fpurpose[data-v-4f00c6fa]:before{content:"用途:";font-weight:600;color:#1b8d63}.ph-ffill[data-v-4f00c6fa]{color:#8a5b00;font-size:13px;line-height:1.6;margin-top:4px}.ph-ffill[data-v-4f00c6fa]:before{content:"怎么填:";font-weight:600;color:#8a5b00}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
function n(e){if(!e)return!0;try{const r=JSON.parse(localStorage.getItem("user")||"null");if(!r)return!1;const t=r.permissionCodes||[];return t.includes("*")?!0:t.includes(e)}catch{return!1}}function u(){try{const e=JSON.parse(localStorage.getItem("user")||"null");return!!e&&e.role==="admin"}catch{return!1}}export{n as c,u as i};
@@ -1,15 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WMS库房管理</title>
<!-- 系统图标:库房箱体(内联 SVG,避免依赖外部文件) -->
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' rx='6' fill='%231668dc'/><path d='M16 7l9 4.5v9L16 25l-9-4.5v-9L16 7z' fill='none' stroke='%23fff' stroke-width='2' stroke-linejoin='round'/><path d='M7 11.5L16 16l9-4.5M16 16v9' fill='none' stroke='%23fff' stroke-width='2' stroke-linejoin='round'/></svg>">
<script type="module" crossorigin src="/assets/index-Bbn7KMl5.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-hzpIaM_X.css">
</head>
<body>
<div id="app"></div>
</body>
</html>