package handler import ( "net/http" "time" "bj_power_wms/ent/inboundorder" "bj_power_wms/ent/ordermaterialledger" "bj_power_wms/ent/outboundorder" "bj_power_wms/ent/semifinished" "bj_power_wms/ent/serialnumber" "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.InventoryBatch.Query().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 zones[b.ZoneCode+"/"+b.QualityStatus] += b.Quantity } snInStock, _ := ctx.EntClient.SerialNumber.Query().Where(serialnumber.StatusIn("在库", "锁定")).Count(ctx0()) snOut, _ := ctx.EntClient.SerialNumber.Query().Where(serialnumber.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"), }) } }