feat: 完成产线与仓储系统多模块迭代升级

本次迭代覆盖MES与WMS核心业务:
1. 新增接驳台托盘传感器读取与AGV对接能力
2. 完善工单排产、备料流程与权限体系拆分
3. 优化看板接口与前端路由、样式
4. 新增操作日志、库存盘点与角色保护逻辑
5. 修复代理地址、BOM保存等已知问题
This commit is contained in:
SunYF
2026-09-04 14:18:53 +08:00
parent c1fc6d32b2
commit b6799c9de4
138 changed files with 20613 additions and 2220 deletions
+57
View File
@@ -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{}})
}
}