feat: 完成产线与仓储系统多模块迭代升级
本次迭代覆盖MES与WMS核心业务: 1. 新增接驳台托盘传感器读取与AGV对接能力 2. 完善工单排产、备料流程与权限体系拆分 3. 优化看板接口与前端路由、样式 4. 新增操作日志、库存盘点与角色保护逻辑 5. 修复代理地址、BOM保存等已知问题
This commit is contained in:
@@ -70,6 +70,8 @@ func createMaterialHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
fail(w, http.StatusInternalServerError, "创建物料失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
ctx.EventLog.Write(ctx0(), "material.create", r.Header.Get("X-Username"), "material", req.Code,
|
||||
"新增物料 "+req.Code+" "+req.Name, map[string]any{"manageMode": manageMode})
|
||||
|
||||
ok(w, m)
|
||||
}
|
||||
@@ -91,6 +93,11 @@ func updateMaterialHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
fail(w, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
}
|
||||
cur, gerr := ctx.EntClient.Material.Get(ctx0(), req.ID)
|
||||
if gerr != nil {
|
||||
fail(w, http.StatusNotFound, "物料不存在")
|
||||
return
|
||||
}
|
||||
|
||||
upd := ctx.EntClient.Material.UpdateOneID(req.ID)
|
||||
if req.Name != "" {
|
||||
@@ -111,6 +118,8 @@ func updateMaterialHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
fail(w, http.StatusInternalServerError, "更新物料失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
ctx.EventLog.Write(ctx0(), "material.update", r.Header.Get("X-Username"), "material", cur.Code,
|
||||
"编辑物料 "+cur.Code+" "+cur.Name, nil)
|
||||
ok(w, m)
|
||||
}
|
||||
}
|
||||
@@ -213,6 +222,52 @@ func getMaterialHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// materialExistsHandler 内部接口:批量校验物料编码是否存在于物料档案。
|
||||
// body: {"codes":["A","B"]} → data: {"missing":["B"]}(不存在于档案的编码列表)。
|
||||
// 供 MES 备料单生成前防呆使用(wrapInternal + X-API-TOKEN 保护)。
|
||||
func materialExistsHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req struct {
|
||||
Codes []string `json:"codes"`
|
||||
}
|
||||
if err := parseJSON(r, &req); err != nil {
|
||||
fail(w, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
}
|
||||
// 去重并过滤空串
|
||||
seen := map[string]bool{}
|
||||
codes := []string{}
|
||||
for _, c := range req.Codes {
|
||||
c = strings.TrimSpace(c)
|
||||
if c == "" || seen[c] {
|
||||
continue
|
||||
}
|
||||
seen[c] = true
|
||||
codes = append(codes, c)
|
||||
}
|
||||
missing := []string{}
|
||||
if len(codes) > 0 {
|
||||
// 查存在的编码集合
|
||||
exist, err := ctx.EntClient.Material.Query().
|
||||
Where(material.CodeIn(codes...)).
|
||||
Select(material.FieldCode).
|
||||
All(ctx0())
|
||||
if err == nil {
|
||||
have := map[string]bool{}
|
||||
for _, m := range exist {
|
||||
have[m.Code] = true
|
||||
}
|
||||
for _, c := range codes {
|
||||
if !have[c] {
|
||||
missing = append(missing, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ok(w, map[string]any{"missing": missing})
|
||||
}
|
||||
}
|
||||
|
||||
// exportMaterialsHandler 物料档案全量导出(xlsx),按当前筛选条件导出
|
||||
func exportMaterialsHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -404,6 +459,8 @@ func excelMaterialImportHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
committed = true
|
||||
ctx.EventLog.Write(ctx0(), "material.import", r.Header.Get("X-Username"), "material", "",
|
||||
"Excel 导入物料", map[string]any{"success": len(plans)})
|
||||
ok(w, map[string]any{"success": len(plans), "failed": 0, "errors": []importErr{}})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user