feat(mes): 添加定时同步可生产数量到WMS及BOM项相关标准字段
- 在main.go中添加定时任务每10分钟同步可生产数量到WMS系统 - 为BomItem实体添加relatedStandard字段及相关CRUD方法 - 为InspectionRecord实体添加reportNo、materialCode、materialName等字段 - 更新ent schema确保新字段的验证和默认值设置 - 添加必要的数据库迁移和字段映射逻辑
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"bj_power_wms/ent"
|
||||
"bj_power_wms/ent/inventory"
|
||||
"bj_power_wms/ent/zone"
|
||||
"bj_power_wms/internal/svc"
|
||||
)
|
||||
|
||||
// zoneLoc 库位推荐候选(历史常用位 / 空闲位共用):四级货位。
|
||||
type zoneLoc struct {
|
||||
ZoneCode string `json:"zoneCode"`
|
||||
ZoneName string `json:"zoneName"`
|
||||
ShelfNo string `json:"shelfNo"`
|
||||
LayerNo string `json:"layerNo"`
|
||||
PositionNo string `json:"positionNo"`
|
||||
}
|
||||
|
||||
// locKey 四级货位归一键(NULL/空串归一为""),与 DB 组合唯一索引 ux_zones_location 语义一致。
|
||||
func locKey(zoneCode, shelfNo, layerNo, positionNo string) string {
|
||||
return zoneCode + "\x00" + shelfNo + "\x00" + layerNo + "\x00" + positionNo
|
||||
}
|
||||
|
||||
// zoneRecommendHandler 库位推荐(客户诉求 问题记录 附二#4:拒绝全自动识别,
|
||||
// 采用「历史常用位 + 同区空位优先」推荐,由库房一键确认或手改)。
|
||||
//
|
||||
// 入参:materialCode(必填,图号)。
|
||||
// 返回(history/empty 均为四级货位对象,前端点击可一键回填区域+货架/层/位):
|
||||
// - history: 该物料历史入库使用过的货位(按最近使用排序,最多 5 个)
|
||||
// - empty: 空闲货位(zones 中启用且当前无在库/锁定库存引用,最多 10 个;同区域优先)
|
||||
func zoneRecommendHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
materialCode := r.URL.Query().Get("materialCode")
|
||||
if materialCode == "" {
|
||||
fail(w, http.StatusBadRequest, "materialCode 必填")
|
||||
return
|
||||
}
|
||||
|
||||
// 1. 历史常用货位:该物料库存行按最近更新倒序,去重取前 5 个四级货位。
|
||||
history := []zoneLoc{}
|
||||
histSet := map[string]bool{}
|
||||
preferredZone := ""
|
||||
if invs, err := ctx.EntClient.Inventory.Query().
|
||||
Where(inventory.MaterialCodeEQ(materialCode)).
|
||||
Order(ent.Desc("updated_at"), ent.Desc("id")).
|
||||
Limit(200).All(ctx0()); err == nil {
|
||||
for _, inv := range invs {
|
||||
if inv.ZoneCode == "" {
|
||||
continue
|
||||
}
|
||||
key := locKey(inv.ZoneCode, inv.ShelfNo, inv.LayerNo, inv.PositionNo)
|
||||
if histSet[key] {
|
||||
continue
|
||||
}
|
||||
histSet[key] = true
|
||||
if preferredZone == "" {
|
||||
preferredZone = inv.ZoneCode
|
||||
}
|
||||
history = append(history, zoneLoc{
|
||||
ZoneCode: inv.ZoneCode, ShelfNo: inv.ShelfNo, LayerNo: inv.LayerNo, PositionNo: inv.PositionNo,
|
||||
})
|
||||
if len(history) >= 5 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 被占用货位集合:在库/锁定库存行引用的四级货位(U18:按货位而非区域判占用)。
|
||||
occupied := map[string]bool{}
|
||||
if rows, err := ctx.EntClient.Inventory.Query().
|
||||
Where(inventory.StatusIn("在库", "锁定")).
|
||||
Select(inventory.FieldZoneCode, inventory.FieldShelfNo, inventory.FieldLayerNo, inventory.FieldPositionNo).
|
||||
All(ctx0()); err == nil {
|
||||
for _, row := range rows {
|
||||
if row.ZoneCode != "" {
|
||||
occupied[locKey(row.ZoneCode, row.ShelfNo, row.LayerNo, row.PositionNo)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 空闲货位:启用且四级货位未被占用的 zones 行;同区域(preferredZone)的排前面。
|
||||
sameArea := []zoneLoc{}
|
||||
otherArea := []zoneLoc{}
|
||||
if zones, err := ctx.EntClient.Zone.Query().
|
||||
Where(zone.StatusEQ("启用")).
|
||||
Order(ent.Asc("id")).
|
||||
All(ctx0()); err == nil {
|
||||
for _, z := range zones {
|
||||
if occupied[locKey(z.ZoneCode, z.ShelfNo, z.LayerNo, z.PositionNo)] {
|
||||
continue
|
||||
}
|
||||
zl := zoneLoc{
|
||||
ZoneCode: z.ZoneCode, ZoneName: z.ZoneName,
|
||||
ShelfNo: z.ShelfNo, LayerNo: z.LayerNo, PositionNo: z.PositionNo,
|
||||
}
|
||||
// 同区判定:区域(zone_code)相同(U18:zone_code 即区域级,不再靠前缀猜测)。
|
||||
if preferredZone != "" && z.ZoneCode == preferredZone {
|
||||
sameArea = append(sameArea, zl)
|
||||
} else {
|
||||
otherArea = append(otherArea, zl)
|
||||
}
|
||||
}
|
||||
}
|
||||
empty := append(sameArea, otherArea...)
|
||||
if len(empty) > 10 {
|
||||
empty = empty[:10]
|
||||
}
|
||||
|
||||
ok(w, map[string]any{
|
||||
"history": history,
|
||||
"empty": empty,
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user