1. 合并inventory_batch与serial_number为统一inventory表,用manage_mode区分结构件批次/精密件SN 2. 移除冗余的material_type字段与相关逻辑 3. 重构库存查询、检验、入库出库等业务逻辑适配新表结构 4. 调整前端路由与菜单,拆分基础数据为区域维护和物料档案 5. 优化入库校验逻辑,避免空单问题 6. 调整Vite构建配置,关闭自动清空输出目录 7. 为各模块添加详细中文注释,统一业务术语 8. 生成并更新Ent自动代码文件
116 lines
3.7 KiB
Go
116 lines
3.7 KiB
Go
package handler
|
||
|
||
import (
|
||
"net/http"
|
||
"time"
|
||
|
||
"bj_power_wms/ent/inboundorder"
|
||
"bj_power_wms/ent/inventory"
|
||
"bj_power_wms/ent/ordermaterialledger"
|
||
"bj_power_wms/ent/outboundorder"
|
||
"bj_power_wms/ent/semifinished"
|
||
"bj_power_wms/internal/svc"
|
||
)
|
||
|
||
// ledgerSyncRequest MES 下发工单 BOM 后同步台账
|
||
type ledgerSyncRequest struct {
|
||
OrderNo string `json:"orderNo"`
|
||
ProductCode string `json:"productCode"`
|
||
Operator string `json:"operator"`
|
||
Items []struct {
|
||
MaterialCode string `json:"materialCode"`
|
||
MaterialName string `json:"materialName"`
|
||
TotalQty int `json:"totalQty"`
|
||
} `json:"items"`
|
||
}
|
||
|
||
// ledgerSyncHandler 同步/更新工单物料台账(幂等:按 orderNo+materialCode upsert)
|
||
func ledgerSyncHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||
return func(w http.ResponseWriter, r *http.Request) {
|
||
var req ledgerSyncRequest
|
||
if err := parseJSON(r, &req); err != nil {
|
||
fail(w, http.StatusBadRequest, "参数错误: "+err.Error())
|
||
return
|
||
}
|
||
if req.OrderNo == "" || len(req.Items) == 0 {
|
||
fail(w, http.StatusBadRequest, "orderNo 和 items 必填")
|
||
return
|
||
}
|
||
saved := 0
|
||
for _, it := range req.Items {
|
||
existing, err := ctx.EntClient.OrderMaterialLedger.Query().
|
||
Where(
|
||
ordermaterialledger.OrderNoEQ(req.OrderNo),
|
||
ordermaterialledger.MaterialCodeEQ(it.MaterialCode),
|
||
).Only(ctx0())
|
||
if err == nil {
|
||
ctx.EntClient.OrderMaterialLedger.UpdateOneID(existing.ID).
|
||
SetTotalQty(it.TotalQty).
|
||
SetStatus("进行中").
|
||
SetUpdatedAt(time.Now().Unix()).
|
||
ExecX(ctx0())
|
||
} else {
|
||
ctx.EntClient.OrderMaterialLedger.Create().
|
||
SetOrderNo(req.OrderNo).
|
||
SetMaterialCode(it.MaterialCode).
|
||
SetNillableMaterialName(strPtr(it.MaterialName)).
|
||
SetTotalQty(it.TotalQty).
|
||
SetOutQty(0).
|
||
SetStatus("进行中").
|
||
SaveX(ctx0())
|
||
}
|
||
saved++
|
||
}
|
||
ok(w, map[string]any{"orderNo": req.OrderNo, "synced": saved})
|
||
}
|
||
}
|
||
|
||
// internalDisplayHandler 库存总览(55寸大屏免登录用)
|
||
func internalDisplayHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||
return func(w http.ResponseWriter, r *http.Request) {
|
||
// 批次库存(结构件)总量(按质量状态)
|
||
batches, _ := ctx.EntClient.Inventory.Query().Where(inventory.ManageModeEQ(1)).All(ctx0())
|
||
totalQty := 0
|
||
lockedQty := 0
|
||
type zoneRow struct {
|
||
Zone, Quality string
|
||
Qty int
|
||
}
|
||
zones := map[string]int{}
|
||
batchCount := len(batches)
|
||
for _, b := range batches {
|
||
totalQty += b.Quantity
|
||
lockedQty += b.LockedQty
|
||
zc := b.ZoneCode
|
||
if zc == "" {
|
||
zc = "未分区"
|
||
}
|
||
zones[zc+"/"+b.QualityStatus] += b.Quantity
|
||
}
|
||
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())
|
||
pkgCount, _ := ctx.EntClient.PackageBox.Query().Count(ctx0())
|
||
|
||
dayStart := time.Now().Truncate(24 * time.Hour).Unix()
|
||
inToday, _ := ctx.EntClient.InboundOrder.Query().
|
||
Where(inboundorder.CreatedAtGTE(dayStart)).Count(ctx0())
|
||
outToday, _ := ctx.EntClient.OutboundOrder.Query().
|
||
Where(outboundorder.CreatedAtGTE(dayStart)).Count(ctx0())
|
||
|
||
ok(w, map[string]any{
|
||
"batchCount": batchCount,
|
||
"totalQty": totalQty,
|
||
"lockedQty": lockedQty,
|
||
"snInStock": snInStock,
|
||
"snOut": snOut,
|
||
"semiInStock": semiInStock,
|
||
"packageCount": pkgCount,
|
||
"inToday": inToday,
|
||
"outToday": outToday,
|
||
"zoneDetail": zones,
|
||
"time": time.Now().Format("2006-01-02 15:04:05"),
|
||
})
|
||
}
|
||
}
|