diff --git a/bj_power_mes/internal/handler/production/bom_material.go b/bj_power_mes/internal/handler/production/bom_material.go index 541366f..2e71eff 100644 --- a/bj_power_mes/internal/handler/production/bom_material.go +++ b/bj_power_mes/internal/handler/production/bom_material.go @@ -66,16 +66,16 @@ func ImportBomHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { } } item := logic.BomItemReq{ - ProductCode: productCode, - BomName: bomName, - MaterialCode: materialCode, - MaterialName: trimCell(row, 3), - Spec: trimCell(row, 4), - Unit: trimCell(row, 5), - ManageMode: "2", - ProcessCode: &pc, - UnitQty: parseFloat(trimCell(row, 6)), - LossRate: parseFloat(trimCell(row, 7)), + ProductCode: productCode, + BomName: bomName, + MaterialCode: materialCode, + MaterialName: trimCell(row, 3), + Spec: trimCell(row, 4), + Unit: trimCell(row, 5), + ManageMode: "2", + ProcessCode: &pc, + UnitQty: parseFloat(trimCell(row, 6)), + LossRate: parseFloat(trimCell(row, 7)), RelatedStandard: trimCell(row, 9), } k := key{productCode, bomName} @@ -357,4 +357,4 @@ func StationReceiveMaterialInternalHandler(svcCtx *svc.ServiceContext) http.Hand } httpx.Ok(w, nil) } -} \ No newline at end of file +} diff --git a/bj_power_mes/internal/wmsclient/client.go b/bj_power_mes/internal/wmsclient/client.go index aa06b47..899c470 100644 --- a/bj_power_mes/internal/wmsclient/client.go +++ b/bj_power_mes/internal/wmsclient/client.go @@ -1,11 +1,11 @@ package wmsclient import ( - "fmt" "bytes" "context" "encoding/json" "errors" + "fmt" "net/http" "net/url" "time" @@ -186,8 +186,8 @@ func (c *Client) ProductTypePage(ctx context.Context, code, name, category, isAc q += "&isActive=" + isActive } var data struct { - Total int64 `json:"total"` - List []ProductTypeRow `json:"list"` + Total int64 `json:"total"` + List []ProductTypeRow `json:"list"` } if err := c.get(ctx, q, &data); err != nil { return 0, nil, err @@ -651,4 +651,4 @@ type RespError struct { func (e *RespError) Error() string { return "wms call failed with status " + string(rune('0'+e.Status)) -} \ No newline at end of file +} diff --git a/bj_power_wms/internal/handler/attachment.go b/bj_power_wms/internal/handler/attachment.go index 1b4899a..c99e2e4 100644 --- a/bj_power_wms/internal/handler/attachment.go +++ b/bj_power_wms/internal/handler/attachment.go @@ -435,15 +435,15 @@ func serveUploadFileHandler(ctx *svc.ServiceContext) http.HandlerFunc { // diskStatusView 磁盘状态视图(供接口/页面告警条使用)。 type diskStatusView struct { - RootDir string `json:"rootDir"` - UsedPercent int `json:"usedPercent"` - FreeBytes uint64 `json:"freeBytes"` - TotalBytes uint64 `json:"totalBytes"` - WarnPercent int `json:"warnPercent"` - CritPercent int `json:"critPercent"` - Level string `json:"level"` // ok / warn / critical - Message string `json:"message"` - CheckedUnix int64 `json:"checkedAt"` + RootDir string `json:"rootDir"` + UsedPercent int `json:"usedPercent"` + FreeBytes uint64 `json:"freeBytes"` + TotalBytes uint64 `json:"totalBytes"` + WarnPercent int `json:"warnPercent"` + CritPercent int `json:"critPercent"` + Level string `json:"level"` // ok / warn / critical + Message string `json:"message"` + CheckedUnix int64 `json:"checkedAt"` } // diskStatus 读取附件根目录所在磁盘剩余空间并给出告警级别。 diff --git a/bj_power_wms/internal/handler/inbound.go b/bj_power_wms/internal/handler/inbound.go index 7c289c8..e49c635 100644 --- a/bj_power_wms/internal/handler/inbound.go +++ b/bj_power_wms/internal/handler/inbound.go @@ -84,12 +84,12 @@ func createInboundHandler(ctx *svc.ServiceContext) http.HandlerFunc { return } if req.ZoneCode == "" { - fail(w, http.StatusBadRequest, "区域必填,请先选择入库区域") - return + fail(w, http.StatusBadRequest, "区域必填,请先选择入库区域") + return } if req.InspectionNo == "" { - fail(w, http.StatusBadRequest, "检测单号必填,请填写入库检报告单号") - return + fail(w, http.StatusBadRequest, "检测单号必填,请填写入库检报告单号") + return } // 物料档案 diff --git a/bj_power_wms/internal/handler/misc.go b/bj_power_wms/internal/handler/misc.go index 13545a1..e4780d5 100644 --- a/bj_power_wms/internal/handler/misc.go +++ b/bj_power_wms/internal/handler/misc.go @@ -44,11 +44,11 @@ func semiInboundHandler(ctx *svc.ServiceContext) http.HandlerFunc { Category int `json:"category"` // 2=半成品 3=成品(默认 2) OwnershipType string `json:"ownershipType"` OwnershipNo string `json:"ownershipNo"` - ProductStatus string `json:"productStatus"` // 已通过/部分通过/返修(成品用) - RelatedStandard string `json:"relatedStandard"` // 相关标准(试验方案号) - TestRecordNo string `json:"testRecordNo"` // 试验记录单号 - RecordedBy string `json:"recordedBy"` // 记录员 - RecordedAt int64 `json:"recordedAt"` // 记录日期(unix 秒) + ProductStatus string `json:"productStatus"` // 已通过/部分通过/返修(成品用) + RelatedStandard string `json:"relatedStandard"` // 相关标准(试验方案号) + TestRecordNo string `json:"testRecordNo"` // 试验记录单号 + RecordedBy string `json:"recordedBy"` // 记录员 + RecordedAt int64 `json:"recordedAt"` // 记录日期(unix 秒) } if err := parseJSON(r, &req); err != nil { fail(w, http.StatusBadRequest, "参数错误") @@ -119,7 +119,7 @@ func semiInboundHandler(ctx *svc.ServiceContext) http.HandlerFunc { SetNillableTestRecordNo(strPtr(req.TestRecordNo)). SetNillableRecordedBy(strPtr(req.RecordedBy)). SetNillableRecordedAt(int64Ptr(req.RecordedAt)). - SetRemark(catLabel+"完工暂存回流"). + SetRemark(catLabel + "完工暂存回流"). Save(ctx0()) if err != nil { fail(w, http.StatusInternalServerError, err.Error()) @@ -305,11 +305,12 @@ type ledgerRow struct { // ledgerState 备料四态判定(客户诉求 问题记录 L242-258 孙彦飞口径),优先级:未到货 > 预警 > 未齐套 > 齐套。 // // 状态定义(L253-256): -// 齐套 :可用库存 ≥ 需求总量 -// 未齐套:0 < 可用库存 < 需求总量 -// 未到货:可用库存 = 0 且 已出库 = 0 -// 预警 :可用库存 < 未来5天需求量(future5Qty 由 MES 按近5天日排产×单台用量推送到 material_demands; -// 无推送记录时 future5Qty=0,该档不生效,退化为三态判定) +// +// 齐套 :可用库存 ≥ 需求总量 +// 未齐套:0 < 可用库存 < 需求总量 +// 未到货:可用库存 = 0 且 已出库 = 0 +// 预警 :可用库存 < 未来5天需求量(future5Qty 由 MES 按近5天日排产×单台用量推送到 material_demands; +// 无推送记录时 future5Qty=0,该档不生效,退化为三态判定) func ledgerState(avail, need, out, future5Qty int) string { if avail <= 0 && out <= 0 { return "未到货" @@ -375,7 +376,7 @@ func queryLedgerHandler(ctx *svc.ServiceContext) http.HandlerFunc { materialCode := r.URL.Query().Get("materialCode") materialName := r.URL.Query().Get("materialName") status := r.URL.Query().Get("status") - state := r.URL.Query().Get("state") // 四态筛选:齐套/未齐套/预警/未到货 + state := r.URL.Query().Get("state") // 四态筛选:齐套/未齐套/预警/未到货 completeStart := r.URL.Query().Get("completeStart") // 完成时间起(YYYY-MM-DD) completeEnd := r.URL.Query().Get("completeEnd") // 完成时间止 page := atoi(r.URL.Query().Get("page"), 1) diff --git a/bj_power_wms/internal/handler/outbound.go b/bj_power_wms/internal/handler/outbound.go index cec83e0..bb95fd4 100644 --- a/bj_power_wms/internal/handler/outbound.go +++ b/bj_power_wms/internal/handler/outbound.go @@ -413,8 +413,8 @@ type generalOutboundRequest struct { OwnershipType string `json:"ownershipType"` // workorder/project/other OwnershipNo string `json:"ownershipNo"` TargetStation string `json:"targetStation"` - TargetDock string `json:"targetDock"` // 目标接驳台(叫AGV时必填) - NeedAgv bool `json:"needAgv"` // 是否叫AGV配送到接驳台(可选) + TargetDock string `json:"targetDock"` // 目标接驳台(叫AGV时必填) + NeedAgv bool `json:"needAgv"` // 是否叫AGV配送到接驳台(可选) } // generalOutboundHandler 通用出库(手动出库,不依赖工单) diff --git a/bj_power_wms/internal/handler/routes.go b/bj_power_wms/internal/handler/routes.go index 36c4856..7d1016b 100644 --- a/bj_power_wms/internal/handler/routes.go +++ b/bj_power_wms/internal/handler/routes.go @@ -242,12 +242,12 @@ func RegisterHandlers(server *rest.Server, ctx *svc.ServiceContext) { {Method: http.MethodPost, Path: "/api/internal/product-types", Handler: wrapInternal(ctx)(createProductTypeInternalHandler(ctx))}, {Method: http.MethodPut, Path: "/api/internal/product-types", Handler: wrapInternal(ctx)(updateProductTypeInternalHandler(ctx))}, {Method: http.MethodPost, Path: "/api/internal/product-types/delete", Handler: wrapInternal(ctx)(deleteProductTypeInternalHandler(ctx))}, - {Method: http.MethodPost, Path: "/api/internal/material/exists", Handler: wrapInternal(ctx)(materialExistsHandler(ctx))}, - {Method: http.MethodPost, Path: "/api/internal/material/types", Handler: wrapInternal(ctx)(materialTypesHandler(ctx))}, - {Method: http.MethodPost, Path: "/api/internal/dock/pallet-sync", Handler: syncDockPalletHandler(ctx)}, - {Method: http.MethodPost, Path: "/api/internal/return-order", Handler: wrapInternal(ctx)(createReturnOrderInternalHandler(ctx))}, - {Method: http.MethodGet, Path: "/api/internal/docks", Handler: wrapInternal(ctx)(listDocksInternalHandler(ctx))}, - {Method: http.MethodPost, Path: "/api/internal/material/backflush", Handler: wrapInternal(ctx)(backflushInternalHandler(ctx))}, - }, -) + {Method: http.MethodPost, Path: "/api/internal/material/exists", Handler: wrapInternal(ctx)(materialExistsHandler(ctx))}, + {Method: http.MethodPost, Path: "/api/internal/material/types", Handler: wrapInternal(ctx)(materialTypesHandler(ctx))}, + {Method: http.MethodPost, Path: "/api/internal/dock/pallet-sync", Handler: syncDockPalletHandler(ctx)}, + {Method: http.MethodPost, Path: "/api/internal/return-order", Handler: wrapInternal(ctx)(createReturnOrderInternalHandler(ctx))}, + {Method: http.MethodGet, Path: "/api/internal/docks", Handler: wrapInternal(ctx)(listDocksInternalHandler(ctx))}, + {Method: http.MethodPost, Path: "/api/internal/material/backflush", Handler: wrapInternal(ctx)(backflushInternalHandler(ctx))}, + }, + ) } diff --git a/bj_power_wms/internal/handler/stock.go b/bj_power_wms/internal/handler/stock.go index 38714e0..8e6ef8b 100644 --- a/bj_power_wms/internal/handler/stock.go +++ b/bj_power_wms/internal/handler/stock.go @@ -7,7 +7,6 @@ import ( "strings" "time" - "entgo.io/ent/dialect/sql" "bj_power_wms/ent" "bj_power_wms/ent/inventory" "bj_power_wms/ent/inventorylock" @@ -15,6 +14,8 @@ import ( "bj_power_wms/ent/predicate" "bj_power_wms/ent/zone" "bj_power_wms/internal/svc" + + "entgo.io/ent/dialect/sql" ) // stockKey 库存聚合行的唯一标识(组合键)+ 明细下钻的过滤条件 @@ -298,7 +299,7 @@ func aggregateStock(ctx *svc.ServiceContext, a aggregateStockArgs) ([]*stockAggR // 回答"这个物料总共有多少":总数/锁定/可用 + 质量分布(合格/未检/不合格) + 分布区域列表。 // ID 取物料主表(material)主键——聚合视图无自身实体,主表 ID 即行标识,禁止伪 id。 type materialAggRow struct { - ID int64 `json:"id"` // 物料主表 ID(material.id,档案缺失时为 0) + ID int64 `json:"id"` // 物料主表 ID(material.id,档案缺失时为 0) MaterialCode string `json:"materialCode"` MaterialName string `json:"materialName"` Spec string `json:"spec"` @@ -665,14 +666,15 @@ func exportStockHandler(ctx *svc.ServiceContext) http.HandlerFunc { sendExcel(w, xlsxFilename("库存汇总"), headers, matrix) } } + // zoneSummRow 区域汇总行(按 区域 + 质量状态 + 类型 聚合) // ID/ZoneCreatedAt 取区域主表(zone)主键与创建时间——聚合视图无自身实体,主表字段即行标识,禁止伪 id。 type zoneSummRow struct { - ID int64 `json:"id"` // 区域主表 ID(zone.id,未分区时为 0) + ID int64 `json:"id"` // 区域主表 ID(zone.id,未分区时为 0) ZoneCode string `json:"zoneCode"` ZoneName string `json:"zoneName"` Quality string `json:"quality"` - Type string `json:"type"` // 批次/电气件 + Type string `json:"type"` // 批次/电气件 Qty int `json:"qty"` ZoneCreatedAt int64 `json:"zoneCreatedAt"` // 区域主表创建时间(zone.created_at) LastCreatedAt int64 `json:"lastCreatedAt"` // 组内最近一次入库时间 @@ -1056,7 +1058,7 @@ func itoa(n int) string { // shortageRow 缺货预警行(安全库存 > 0 且可用量 < 安全库存) type shortageRow struct { - ID int64 `json:"id"` // 物料主表 ID + ID int64 `json:"id"` // 物料主表 ID MaterialCode string `json:"materialCode"` MaterialName string `json:"materialName"` Spec string `json:"spec"` diff --git a/bj_power_wms/internal/handler/zone.go b/bj_power_wms/internal/handler/zone.go index f2a6666..9dfa690 100644 --- a/bj_power_wms/internal/handler/zone.go +++ b/bj_power_wms/internal/handler/zone.go @@ -291,10 +291,10 @@ func createZoneNodeHandler(ctx *svc.ServiceContext) http.HandlerFunc { } type zoneNodeUpdateReq struct { - ID int `json:"id"` - Name string `json:"name"` - Remark string `json:"remark"` - Status string `json:"status"` + ID int `json:"id"` + Name string `json:"name"` + Remark string `json:"remark"` + Status string `json:"status"` } // updateZoneNodeHandler 编辑节点(四级均可改名称/备注/启用停用;区域额外同步 zone_name 冗余)。 @@ -342,6 +342,7 @@ func updateZoneNodeHandler(ctx *svc.ServiceContext) http.HandlerFunc { // listZonesForPicker 库位下拉(兼容 + 层级两用): // - 不带 level:返回所有启用位置号(level4)扁平结构(兼容 Outbound/Stocktake/Inventory 旧调用) // - 带 level:返回该层级节点(用于入库页区域→货架→层→位置 级联下拉) +// // locKey 四级货位比较键:区域/货架忽略大小写(存量数据存在 z01/Z01 混用),层/位置原样。 func locKey(zoneCode, shelfNo, layerNo, positionNo string) string { return strings.ToLower(strings.TrimSpace(zoneCode)) + "|" + diff --git a/bj_power_wms/schema/inventory.go b/bj_power_wms/schema/inventory.go index 611eb21..fa66c3d 100644 --- a/bj_power_wms/schema/inventory.go +++ b/bj_power_wms/schema/inventory.go @@ -32,9 +32,9 @@ type Inventory struct { // 品类(category):1=原材料 2=半成品 3=成品。与 manage_mode 正交: // manage_mode 管"怎么管"(批次数量 vs SN 单件),category 管"是什么"(原料/半成品/成品)。 const ( - InvCategoryRaw = 1 - InvCategorySemi = 2 - InvCategoryFinished = 3 + InvCategoryRaw = 1 + InvCategorySemi = 2 + InvCategoryFinished = 3 ) func (Inventory) Fields() []ent.Field {