chore: 批量完成项目多模块迭代优化
1. 废弃半成品库存表并统一库存主表 2. 修复列表排序与搜索大小写不敏感问题 3. 新增用户最近登录时间、工单BOM名称字段 4. 完善角色管理、工位选择器功能 5. 增加拧紧数据补录、成品自动回流WMS能力 6. 统一导出时间范围校验规则 7. 丰富物料/备料单筛选条件 8. 调整菜单与权限命名适配产品型号业务
This commit is contained in:
@@ -6,9 +6,9 @@ import (
|
||||
|
||||
"bj_power_wms/ent/inboundorder"
|
||||
"bj_power_wms/ent/inventory"
|
||||
"bj_power_wms/ent/material"
|
||||
"bj_power_wms/ent/ordermaterialledger"
|
||||
"bj_power_wms/ent/outboundorder"
|
||||
"bj_power_wms/ent/semifinished"
|
||||
"bj_power_wms/internal/svc"
|
||||
)
|
||||
|
||||
@@ -89,7 +89,10 @@ func internalDisplayHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
}
|
||||
snInStock, _ := ctx.EntClient.Inventory.Query().Where(inventory.ManageModeEQ(2), inventory.StatusIn("在库", "锁定")).Count(ctx0())
|
||||
snOut, _ := ctx.EntClient.Inventory.Query().Where(inventory.ManageModeEQ(2), inventory.StatusEQ("出库")).Count(ctx0())
|
||||
semiInStock, _ := ctx.EntClient.SemiFinished.Query().Where(semifinished.StatusEQ("在库")).Count(ctx0())
|
||||
// 半成品统计:统一库存主表 category=2(semi_finisheds 已收编废弃)
|
||||
semiInStock, _ := ctx.EntClient.Inventory.Query().Where(inventory.CategoryEQ(invCatSemi), inventory.StatusEQ("在库")).Count(ctx0())
|
||||
// 成品在库统计:category=3
|
||||
finishedInStock, _ := ctx.EntClient.Inventory.Query().Where(inventory.CategoryEQ(invCatFinished), inventory.StatusIn("在库", "锁定")).Count(ctx0())
|
||||
pkgCount, _ := ctx.EntClient.OutboundOrder.Query().Where(outboundorder.BoxNoNEQ("")).Count(ctx0())
|
||||
|
||||
dayStart := time.Now().Truncate(24 * time.Hour).Unix()
|
||||
@@ -105,6 +108,7 @@ func internalDisplayHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
"snInStock": snInStock,
|
||||
"snOut": snOut,
|
||||
"semiInStock": semiInStock,
|
||||
"finishedInStock": finishedInStock,
|
||||
"packageCount": pkgCount,
|
||||
"inToday": inToday,
|
||||
"outToday": outToday,
|
||||
@@ -113,3 +117,92 @@ func internalDisplayHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// finishedInboundRequest 成品完工回流入库请求(MES 完工后调用,X-API-TOKEN 内部接口)
|
||||
// 定稿(2026-09-07):成品 SN 由 MES 系统生成(系统必发号,实物可不贴码,允许手填覆盖),
|
||||
// SN 与实物码解耦;完工品经本接口自动回流 WMS 统一库存主表(manage_mode=2 SN单件, category=3 成品)。
|
||||
type finishedInboundRequest struct {
|
||||
ProductCode string `json:"productCode"` // 产品编码(成品物料编码)
|
||||
ProductName string `json:"productName"` // 产品名称(档案缺失时兜底展示)
|
||||
Sn string `json:"sn"` // 成品 SN(系统生成或手填,全局唯一)
|
||||
OrderNo string `json:"orderNo"` // 关联工单号
|
||||
ZoneCode string `json:"zoneCode"` // 入库区域(可空=未分区)
|
||||
QualityStatus string `json:"qualityStatus"` // 默认 合格(完工已过全工序校验)
|
||||
SnSource string `json:"snSource"` // AUTO=系统生成 / MANUAL=手填,仅记录
|
||||
Operator string `json:"operator"`
|
||||
}
|
||||
|
||||
// finishedInboundHandler 成品完工回流入库
|
||||
// 物料档案缺失时不阻塞回流(库存行 material_code 仍落产品编码,名称用请求传入兜底),
|
||||
// 记 eventlog 提示补建档——编码主数据仍以 WMS 为单一来源,产线不被档案缺失卡死。
|
||||
func finishedInboundHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req finishedInboundRequest
|
||||
if err := parseJSON(r, &req); err != nil {
|
||||
fail(w, http.StatusBadRequest, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
if req.Sn == "" || req.ProductCode == "" {
|
||||
fail(w, http.StatusBadRequest, "sn 与 productCode 必填")
|
||||
return
|
||||
}
|
||||
quality := req.QualityStatus
|
||||
if quality == "" {
|
||||
quality = "合格"
|
||||
}
|
||||
|
||||
// SN 全局防重(同品类成品 + 半成品 + 精密件 SN 都不允许撞号)
|
||||
dup, err := ctx.EntClient.Inventory.Query().
|
||||
Where(inventory.ManageModeEQ(2), inventory.SnCodeEQ(req.Sn)).Exist(ctx0())
|
||||
if err != nil {
|
||||
fail(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
if dup {
|
||||
fail(w, http.StatusConflict, "成品 SN 已存在库存: "+req.Sn)
|
||||
return
|
||||
}
|
||||
|
||||
// 物料档案补名称;缺失时记日志(不阻塞回流)
|
||||
materialName := req.ProductName
|
||||
archiveMiss := false
|
||||
if m, err := ctx.EntClient.Material.Query().Where(material.CodeEQ(req.ProductCode)).First(ctx0()); err == nil && m != nil {
|
||||
materialName = m.Name
|
||||
} else {
|
||||
archiveMiss = true
|
||||
}
|
||||
|
||||
rec, err := ctx.EntClient.Inventory.Create().
|
||||
SetManageMode(2).
|
||||
SetCategory(invCatFinished).
|
||||
SetMaterialCode(req.ProductCode).
|
||||
SetMaterialName(materialName).
|
||||
SetSnCode(req.Sn).
|
||||
SetQuantity(1).
|
||||
SetQualityStatus(quality).
|
||||
SetNillableZoneCode(strPtr(req.ZoneCode)).
|
||||
SetStatus("在库").
|
||||
SetInboundNo("MES:" + req.OrderNo).
|
||||
SetOrderNo(req.OrderNo).
|
||||
SetRemark("成品完工回流(SN来源:" + snSourceLabel(req.SnSource) + ")").
|
||||
Save(ctx0())
|
||||
if err != nil {
|
||||
fail(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
ctx.EventLog.Write(ctx0(), "finished.inbound", req.Operator, "finished", req.Sn,
|
||||
"成品完工回流入库 "+req.Sn, map[string]any{
|
||||
"productCode": req.ProductCode, "orderNo": req.OrderNo,
|
||||
"snSource": req.SnSource, "archiveMiss": archiveMiss,
|
||||
})
|
||||
ok(w, rec)
|
||||
}
|
||||
}
|
||||
|
||||
func snSourceLabel(s string) string {
|
||||
if s == "MANUAL" {
|
||||
return "手填"
|
||||
}
|
||||
return "系统生成"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user