feat: 新增检测单关联、基础数据优化与入库单升级
1. 新增出库单检测单号字段并添加索引支持溯源 2. 优化基础数据页面物料类型展示与选择逻辑 3. 升级入库单导入功能,支持自动生成单号并返回导入结果 4. 优化接驳台查询排序方式 5. 修复字符串拼接空格问题
This commit is contained in:
@@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"bj_power_wms/ent"
|
||||
@@ -680,28 +681,18 @@ func inboundNosByType(ctx *svc.ServiceContext, inboundType string) ([]string, er
|
||||
return nos, nil
|
||||
}
|
||||
|
||||
// pendingInspectionItem 待检清单展开明细行
|
||||
type pendingInspectionItem struct {
|
||||
ID int `json:"id"` // inventory.id(真实主键,禁止伪 id)
|
||||
TargetId string `json:"targetId"` // 批次号或 SN
|
||||
ManageMode int `json:"manageMode"` // 1结构件/2电气件
|
||||
ItemType int `json:"itemType"` // 品类 1原材料/2半成品/3成品/4其他(§E:带入录入页判定其他类)
|
||||
Quantity int `json:"quantity"`
|
||||
ZoneCode string `json:"zoneCode"`
|
||||
}
|
||||
|
||||
// pendingInspectionRow 待检清单主行(按 入库单 + 物料 分组,§E2)
|
||||
// 详情明细改为按需分页加载(右侧抽屉),主行只带总数不塞 details 数组,避免 3000 SN 一次进内存
|
||||
type pendingInspectionRow struct {
|
||||
InboundNo string `json:"inboundNo"`
|
||||
InboundType string `json:"inboundType"`
|
||||
OwnershipType string `json:"ownershipType"`
|
||||
OwnershipNo string `json:"ownershipNo"`
|
||||
MaterialCode string `json:"materialCode"`
|
||||
MaterialName string `json:"materialName"`
|
||||
UnInspectedQty int `json:"unInspectedQty"` // 未检数量(结构件=数量求和;电气件=SN 行数)
|
||||
BatchSnCount int `json:"batchSnCount"` // 未检批次数/SN 数
|
||||
InboundTime int64 `json:"inboundTime"`
|
||||
Details []pendingInspectionItem `json:"details"`
|
||||
InboundNo string `json:"inboundNo"`
|
||||
InboundType string `json:"inboundType"`
|
||||
OwnershipType string `json:"ownershipType"`
|
||||
OwnershipNo string `json:"ownershipNo"`
|
||||
MaterialCode string `json:"materialCode"`
|
||||
MaterialName string `json:"materialName"`
|
||||
UnInspectedQty int `json:"unInspectedQty"` // 未检数量(结构件=数量求和;电气件=SN 行数)
|
||||
DetailsTotal int `json:"detailsTotal"` // 未检批次数/SN 总数(抽屉分页拉明细)
|
||||
InboundTime int64 `json:"inboundTime"`
|
||||
}
|
||||
|
||||
// pendingInspectionHandler 待检清单(来料检验问题2):列出 quality_status=未检 的库存行,
|
||||
@@ -769,9 +760,8 @@ func pendingInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// 物料名称/品类 map
|
||||
// 物料名称 map
|
||||
matName := map[string]string{}
|
||||
matItemType := map[string]int{}
|
||||
codeSet := []string{}
|
||||
seenC := map[string]bool{}
|
||||
for _, inv := range all {
|
||||
@@ -784,7 +774,6 @@ func pendingInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
if mats, e := ctx.EntClient.Material.Query().Where(material.CodeIn(codeSet...)).All(ctx0()); e == nil {
|
||||
for _, m := range mats {
|
||||
matName[m.Code] = m.Name
|
||||
matItemType[m.Code] = m.ItemType
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -818,15 +807,7 @@ func pendingInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
||||
qty = inv.Quantity
|
||||
}
|
||||
g.UnInspectedQty += qty
|
||||
g.BatchSnCount++
|
||||
tid := inv.BatchNo
|
||||
if inv.ManageMode == 2 {
|
||||
tid = inv.SnCode
|
||||
}
|
||||
g.Details = append(g.Details, pendingInspectionItem{
|
||||
ID: inv.ID, TargetId: tid, ManageMode: inv.ManageMode, ItemType: matItemType[inv.MaterialCode],
|
||||
Quantity: inv.Quantity, ZoneCode: inv.ZoneCode,
|
||||
})
|
||||
g.DetailsTotal++
|
||||
if o != nil && o.CreatedAt > g.InboundTime {
|
||||
g.InboundTime = o.CreatedAt
|
||||
}
|
||||
@@ -856,3 +837,69 @@ func strOrEmpty(o *ent.InboundOrder) string {
|
||||
}
|
||||
return o.InboundType
|
||||
}
|
||||
|
||||
// pendingDetailsInspectionHandler GET /api/inspection/pending/details
|
||||
// 待检清单主行抽屉里的明细分页(右侧抽屉懒加载,不再主行带 details 数组)。
|
||||
// 入参:inboundNo + materialCode + page + pageSize(默认 20)。
|
||||
func pendingDetailsInspectionHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
q := r.URL.Query()
|
||||
inboundNo := q.Get("inboundNo")
|
||||
materialCode := q.Get("materialCode")
|
||||
if inboundNo == "" || materialCode == "" {
|
||||
fail(w, http.StatusBadRequest, "inboundNo 和 materialCode 不能为空")
|
||||
return
|
||||
}
|
||||
page, _ := strconv.Atoi(q.Get("page"))
|
||||
pageSize, _ := strconv.Atoi(q.Get("pageSize"))
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize < 1 || pageSize > 500 {
|
||||
pageSize = 20
|
||||
}
|
||||
|
||||
qry := svcCtx.EntClient.Inventory.Query().
|
||||
Where(
|
||||
inventory.InboundNoEQ(inboundNo),
|
||||
inventory.MaterialCodeEQ(materialCode),
|
||||
inventory.QualityStatusEQ("未检"),
|
||||
)
|
||||
total, err := qry.Count(ctx0())
|
||||
if err != nil {
|
||||
fail(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
start := (page - 1) * pageSize
|
||||
list, err := qry.
|
||||
Order(inventory.ByID()).
|
||||
Offset(start).
|
||||
Limit(pageSize).
|
||||
All(ctx0())
|
||||
if err != nil {
|
||||
fail(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
// itemType 从物料档案补查(一个 materialCode 唯一)
|
||||
itemType := 0
|
||||
if m, e := svcCtx.EntClient.Material.Query().Where(material.CodeEQ(materialCode)).Only(ctx0()); e == nil {
|
||||
itemType = m.ItemType
|
||||
}
|
||||
rows := make([]map[string]any, 0, len(list))
|
||||
for _, inv := range list {
|
||||
tid := inv.BatchNo
|
||||
if inv.ManageMode == 2 {
|
||||
tid = inv.SnCode
|
||||
}
|
||||
rows = append(rows, map[string]any{
|
||||
"targetId": tid,
|
||||
"manageMode": inv.ManageMode,
|
||||
"itemType": itemType,
|
||||
"quantity": inv.Quantity,
|
||||
"zoneCode": inv.ZoneCode,
|
||||
"id": inv.ID,
|
||||
})
|
||||
}
|
||||
ok(w, map[string]any{"list": rows, "total": total, "page": page, "pageSize": pageSize})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user