1. 合并inventory_batch与serial_number为统一inventory表,用manage_mode区分结构件批次/精密件SN 2. 移除冗余的material_type字段与相关逻辑 3. 重构库存查询、检验、入库出库等业务逻辑适配新表结构 4. 调整前端路由与菜单,拆分基础数据为区域维护和物料档案 5. 优化入库校验逻辑,避免空单问题 6. 调整Vite构建配置,关闭自动清空输出目录 7. 为各模块添加详细中文注释,统一业务术语 8. 生成并更新Ent自动代码文件
207 lines
6.1 KiB
Go
207 lines
6.1 KiB
Go
package handler
|
||
|
||
import (
|
||
"net/http"
|
||
|
||
"bj_power_wms/ent"
|
||
"bj_power_wms/ent/inspectionrecord"
|
||
"bj_power_wms/ent/inventory"
|
||
"bj_power_wms/internal/svc"
|
||
|
||
"github.com/zeromicro/go-zero/core/logx"
|
||
)
|
||
|
||
// createInspectionHandler 创建检验记录
|
||
// body: { targetType: BATCH/SN, targetId, materialCode, inspectionType, status, resultValue, inspector }
|
||
// 同步库存检验状态:BATCH → inventory(manage_mode=1, batch_no);SN → inventory(manage_mode=2, sn_code)
|
||
func createInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||
return func(w http.ResponseWriter, r *http.Request) {
|
||
var req struct {
|
||
TargetType string `json:"targetType"`
|
||
TargetId string `json:"targetId"`
|
||
MaterialCode string `json:"materialCode"`
|
||
InspectionType string `json:"inspectionType"`
|
||
Status string `json:"status"` // 合格/不合格
|
||
ResultValue string `json:"resultValue"`
|
||
Inspector string `json:"inspector"`
|
||
Remark string `json:"remark"`
|
||
}
|
||
if err := parseJSON(r, &req); err != nil {
|
||
fail(w, http.StatusBadRequest, "参数错误")
|
||
return
|
||
}
|
||
if req.TargetId == "" || req.Status == "" {
|
||
fail(w, http.StatusBadRequest, "targetId 和 status 必填")
|
||
return
|
||
}
|
||
if req.Status != "合格" && req.Status != "不合格" {
|
||
fail(w, http.StatusBadRequest, "status 只能为 合格/不合格")
|
||
return
|
||
}
|
||
|
||
tx, err := ctx.EntClient.Tx(ctx0())
|
||
if err != nil {
|
||
fail(w, http.StatusInternalServerError, "开启事务失败: "+err.Error())
|
||
return
|
||
}
|
||
committed := false
|
||
defer func() {
|
||
if !committed {
|
||
_ = tx.Rollback()
|
||
}
|
||
}()
|
||
|
||
rec, err := tx.InspectionRecord.Create().
|
||
SetTargetType(req.TargetType).
|
||
SetTargetID(req.TargetId).
|
||
SetMaterialCode(req.MaterialCode).
|
||
SetInspectionType(req.InspectionType).
|
||
SetStatus(req.Status).
|
||
SetNillableResultValue(strPtr(req.ResultValue)).
|
||
SetNillableInspector(strPtr(req.Inspector)).
|
||
SetNillableRemark(strPtr(req.Remark)).
|
||
Save(ctx0())
|
||
if err != nil {
|
||
fail(w, http.StatusInternalServerError, err.Error())
|
||
return
|
||
}
|
||
|
||
// 同步库存检验状态
|
||
q := tx.Inventory.Update()
|
||
if req.TargetType == "BATCH" {
|
||
q = q.Where(inventory.ManageModeEQ(1), inventory.BatchNoEQ(req.TargetId))
|
||
} else if req.TargetType == "SN" {
|
||
q = q.Where(inventory.ManageModeEQ(2), inventory.SnCodeEQ(req.TargetId))
|
||
} else {
|
||
fail(w, http.StatusBadRequest, "targetType 只支持 BATCH/SN")
|
||
return
|
||
}
|
||
if _, err = q.SetQualityStatus(req.Status).Save(ctx0()); err != nil {
|
||
fail(w, http.StatusInternalServerError, "同步库存检验状态失败: "+err.Error())
|
||
return
|
||
}
|
||
|
||
if err = tx.Commit(); err != nil {
|
||
fail(w, http.StatusInternalServerError, "提交事务失败: "+err.Error())
|
||
return
|
||
}
|
||
committed = true
|
||
|
||
logx.Infof("inspection: %s %s -> %s by %s", req.TargetType, req.TargetId, req.Status, req.Inspector)
|
||
ok(w, rec)
|
||
}
|
||
}
|
||
|
||
// batchFlipInspectionHandler 批量翻转检验状态
|
||
// body: { targetType: BATCH/SN, targetIds: [], status, inspector }
|
||
func batchFlipInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||
return func(w http.ResponseWriter, r *http.Request) {
|
||
var req struct {
|
||
TargetType string `json:"targetType"`
|
||
TargetIds []string `json:"targetIds"`
|
||
Status string `json:"status"`
|
||
Inspector string `json:"inspector"`
|
||
}
|
||
if err := parseJSON(r, &req); err != nil {
|
||
fail(w, http.StatusBadRequest, "参数错误")
|
||
return
|
||
}
|
||
if len(req.TargetIds) == 0 || (req.Status != "合格" && req.Status != "不合格") {
|
||
fail(w, http.StatusBadRequest, "targetIds 和 status(合格/不合格) 必填")
|
||
return
|
||
}
|
||
|
||
tx, err := ctx.EntClient.Tx(ctx0())
|
||
if err != nil {
|
||
fail(w, http.StatusInternalServerError, "开启事务失败: "+err.Error())
|
||
return
|
||
}
|
||
committed := false
|
||
defer func() {
|
||
if !committed {
|
||
_ = tx.Rollback()
|
||
}
|
||
}()
|
||
|
||
flipped := 0
|
||
for _, id := range req.TargetIds {
|
||
if _, err = tx.InspectionRecord.Create().
|
||
SetTargetType(req.TargetType).
|
||
SetTargetID(id).
|
||
SetStatus(req.Status).
|
||
SetNillableInspector(strPtr(req.Inspector)).
|
||
Save(ctx0()); err != nil {
|
||
fail(w, http.StatusInternalServerError, "创建检验记录失败: "+err.Error())
|
||
return
|
||
}
|
||
q := tx.Inventory.Update()
|
||
if req.TargetType == "BATCH" {
|
||
q = q.Where(inventory.ManageModeEQ(1), inventory.BatchNoEQ(id))
|
||
} else if req.TargetType == "SN" {
|
||
q = q.Where(inventory.ManageModeEQ(2), inventory.SnCodeEQ(id))
|
||
} else {
|
||
fail(w, http.StatusBadRequest, "targetType 只支持 BATCH/SN")
|
||
return
|
||
}
|
||
if _, err = q.SetQualityStatus(req.Status).Save(ctx0()); err != nil {
|
||
fail(w, http.StatusInternalServerError, "同步库存检验状态失败: "+err.Error())
|
||
return
|
||
}
|
||
flipped++
|
||
}
|
||
|
||
if err = tx.Commit(); err != nil {
|
||
fail(w, http.StatusInternalServerError, "提交事务失败: "+err.Error())
|
||
return
|
||
}
|
||
committed = true
|
||
|
||
ok(w, map[string]any{"flipped": flipped})
|
||
}
|
||
}
|
||
|
||
// queryInspectionHandler 检验记录查询
|
||
func queryInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||
return func(w http.ResponseWriter, r *http.Request) {
|
||
page := atoi(r.URL.Query().Get("page"), 1)
|
||
pageSize := atoi(r.URL.Query().Get("pageSize"), 20)
|
||
targetId := r.URL.Query().Get("targetId")
|
||
materialCode := r.URL.Query().Get("materialCode")
|
||
inspectionType := r.URL.Query().Get("inspectionType")
|
||
status := r.URL.Query().Get("status")
|
||
|
||
q := ctx.EntClient.InspectionRecord.Query()
|
||
if targetId != "" {
|
||
q = q.Where(inspectionrecord.TargetIDContains(targetId))
|
||
}
|
||
if materialCode != "" {
|
||
q = q.Where(inspectionrecord.MaterialCodeEQ(materialCode))
|
||
}
|
||
if inspectionType != "" {
|
||
q = q.Where(inspectionrecord.InspectionTypeEQ(inspectionType))
|
||
}
|
||
if status != "" {
|
||
q = q.Where(inspectionrecord.StatusEQ(status))
|
||
}
|
||
|
||
total, err := q.Count(ctx0())
|
||
if err != nil {
|
||
fail(w, http.StatusInternalServerError, err.Error())
|
||
return
|
||
}
|
||
list, err := q.Order(ent.Desc("id")).
|
||
Offset((page - 1) * pageSize).Limit(pageSize).All(ctx0())
|
||
if err != nil {
|
||
fail(w, http.StatusInternalServerError, err.Error())
|
||
return
|
||
}
|
||
|
||
ok(w, map[string]any{
|
||
"total": total,
|
||
"list": list,
|
||
"page": page,
|
||
"pageSize": pageSize,
|
||
})
|
||
}
|
||
}
|