feat: 五项目业务实现并对接完成
- MES(B): 工单/BOM/备料/工序字典/PLC下发/拧紧/扫码报工/半成品/AGV/追溯逻辑,WMS与海康RCS客户端,看板Redis缓存API(概览/设备/进度/报警/趋势)+SSE - WMS(C): JWT滑动续签、Excel导入、盘点、内部API、种子数据、独立Postgres配置 - WMS客户端(E): Go网关8891反向代理+内嵌Vue3十页 - 工位终端(D): SQLite本地缓存+模拟拧紧源+内嵌Vue3页面 - Dashboard(A): 看板数据改接MES内部缓存API,SSE实时刷新+vite代理 - 清理各项目球形磨遗留代码,新增部署手册.md
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
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"),
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user