feat(mes): 添加定时同步可生产数量到WMS及BOM项相关标准字段

- 在main.go中添加定时任务每10分钟同步可生产数量到WMS系统
- 为BomItem实体添加relatedStandard字段及相关CRUD方法
- 为InspectionRecord实体添加reportNo、materialCode、materialName等字段
- 更新ent schema确保新字段的验证和默认值设置
- 添加必要的数据库迁移和字段映射逻辑
This commit is contained in:
SunYF
2026-09-17 12:49:07 +08:00
parent b4b274301d
commit 1cc93795ce
191 changed files with 24504 additions and 1250 deletions
+83 -5
View File
@@ -8,6 +8,7 @@ import (
"bj_power_wms/ent"
"bj_power_wms/ent/inspectionrecord"
"bj_power_wms/ent/inventory"
"bj_power_wms/ent/material"
"bj_power_wms/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
@@ -52,6 +53,11 @@ func createInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
DisposalType string `json:"disposalType"` // NONE/RETURN/SCRAP/PARTIAL
DisposalRemark string `json:"disposalRemark"`
ReturnTrackingNo string `json:"returnTrackingNo"`
// 归属 / 相关标准 / 生产厂家(客户诉求 问题记录 L107/L149/L494
OwnershipType string `json:"ownershipType"` // workorder/project/other
OwnershipNo string `json:"ownershipNo"`
RelatedStandard string `json:"relatedStandard"` // 相关标准(检验细则号)
Manufacturer string `json:"manufacturer"` // 生产厂家
}
if err := parseJSON(r, &req); err != nil {
fail(w, http.StatusBadRequest, "参数错误")
@@ -78,6 +84,13 @@ func createInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
if inv.ManageMode == 2 {
req.TargetType = "SN"
}
// 物料名称冗余(列表直接展示/名称模糊查询,客户诉求 L507-510 三框制)
materialName := inv.MaterialName
if materialName == "" {
if m, merr := ctx.EntClient.Material.Query().Where(material.CodeEQ(inv.MaterialCode)).First(ctx0()); merr == nil && m != nil {
materialName = m.Name
}
}
tx, err := ctx.EntClient.Tx(ctx0())
if err != nil {
@@ -95,6 +108,11 @@ func createInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
SetTargetType(req.TargetType).
SetTargetID(req.TargetId).
SetMaterialCode(req.MaterialCode).
SetNillableMaterialName(strPtr(materialName)).
SetNillableOwnershipType(strPtr(req.OwnershipType)).
SetNillableOwnershipNo(strPtr(req.OwnershipNo)).
SetNillableRelatedStandard(strPtr(req.RelatedStandard)).
SetNillableManufacturer(strPtr(req.Manufacturer)).
SetInspectionType(req.InspectionType).
SetStatus(req.Status).
SetNillableResultValue(strPtr(req.ResultValue)).
@@ -153,6 +171,10 @@ func batchFlipInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
DisposalType string `json:"disposalType"` // NONE/RETURN/SCRAP/PARTIAL
DisposalRemark string `json:"disposalRemark"` // 处置说明
ReturnTrackingNo string `json:"returnTrackingNo"` // 退货货运单号
OwnershipType string `json:"ownershipType"`
OwnershipNo string `json:"ownershipNo"`
RelatedStandard string `json:"relatedStandard"`
Manufacturer string `json:"manufacturer"`
}
if err := parseJSON(r, &req); err != nil {
fail(w, http.StatusBadRequest, "参数错误")
@@ -198,10 +220,21 @@ func batchFlipInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
flipped := 0
for _, t := range targets {
matName := t.inv.MaterialName
if matName == "" {
if m, merr := tx.Material.Query().Where(material.CodeEQ(t.material)).First(ctx0()); merr == nil && m != nil {
matName = m.Name
}
}
if _, err = tx.InspectionRecord.Create().
SetTargetType(t.targetType).
SetTargetID(t.id).
SetMaterialCode(t.material).
SetNillableMaterialName(strPtr(matName)).
SetNillableOwnershipType(strPtr(req.OwnershipType)).
SetNillableOwnershipNo(strPtr(req.OwnershipNo)).
SetNillableRelatedStandard(strPtr(req.RelatedStandard)).
SetNillableManufacturer(strPtr(req.Manufacturer)).
SetStatus(req.Status).
SetInspectQty(req.InspectQty).
SetPassQty(req.PassQty).
@@ -259,6 +292,22 @@ func queryInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
if materialCode != "" {
q = q.Where(inspectionrecord.MaterialCodeContainsFold(materialCode))
}
// 名称模糊 / 归属单号(客户诉求 L507-510 三框制:图号/名称/型号,每框内模糊、多框取交集;L149 增加归属筛选)
if v := r.URL.Query().Get("materialName"); v != "" {
q = q.Where(inspectionrecord.MaterialNameContainsFold(v))
}
if v := r.URL.Query().Get("ownershipNo"); v != "" {
q = q.Where(inspectionrecord.OwnershipNoContainsFold(v))
}
if v := r.URL.Query().Get("spec"); v != "" {
// 型号=物料档案规格型号,需 join 物料表取编码集合
codes := materialCodesBySpec(ctx, v)
if len(codes) == 0 {
ok(w, map[string]any{"total": 0, "list": []any{}, "page": page, "pageSize": pageSize})
return
}
q = q.Where(inspectionrecord.MaterialCodeIn(codes...))
}
if inspectionType != "" {
q = q.Where(inspectionrecord.InspectionTypeEQ(inspectionType))
}
@@ -325,6 +374,20 @@ func exportInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
if materialCode != "" {
q = q.Where(inspectionrecord.MaterialCodeContainsFold(materialCode))
}
if v := r.URL.Query().Get("materialName"); v != "" {
q = q.Where(inspectionrecord.MaterialNameContainsFold(v))
}
if v := r.URL.Query().Get("ownershipNo"); v != "" {
q = q.Where(inspectionrecord.OwnershipNoContainsFold(v))
}
if v := r.URL.Query().Get("spec"); v != "" {
codes := materialCodesBySpec(ctx, v)
if len(codes) == 0 {
ok(w, map[string]any{"list": []any{}})
return
}
q = q.Where(inspectionrecord.MaterialCodeIn(codes...))
}
if inspectionType != "" {
q = q.Where(inspectionrecord.InspectionTypeEQ(inspectionType))
}
@@ -352,7 +415,9 @@ func exportInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
}
// xlsx 导出
if r.URL.Query().Get("format") == "xlsx" {
headers := []string{"ID", "对象", "批次/SN", "物料编码", "检验类型", "结论", "检验数", "合格数", "检测说明", "报检单号", "检验员", "备注", "检测单号", "检验时间"}
// 列名按客户口径(问题记录 L150):检验说明→相关标准、检验员→记录人、检验日期→记录日期、增加归属;
// 图号=物料编码(L18 合并裁决)。
headers := []string{"ID", "对象", "批次/SN", "图号", "名称", "检验类型", "结论", "检验数", "合格数", "相关标准", "报检单号", "检测单号", "归属单号", "生产厂家", "记录人", "备注", "记录日期"}
matrix := make([][]any, 0, len(list))
for _, rec := range list {
obj := rec.TargetType
@@ -362,11 +427,11 @@ func exportInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
obj = "SN"
}
matrix = append(matrix, []any{
rec.ID, obj, rec.TargetID, rec.MaterialCode,
rec.ID, obj, rec.TargetID, rec.MaterialCode, rec.MaterialName,
inspectionTypeLabel(rec.InspectionType), rec.Status,
rec.InspectQty, rec.PassQty, rec.CheckDesc, rec.ReportNo,
rec.Inspector, rec.Remark, unixFmt(rec.CreatedAt),
rec.InspectionNo,
rec.InspectQty, rec.PassQty, rec.RelatedStandard, rec.ReportNo,
rec.InspectionNo, rec.OwnershipNo, rec.Manufacturer, rec.Inspector, rec.Remark,
unixFmt(rec.CreatedAt),
})
}
sendExcel(w, xlsxFilename("检验记录"), headers, matrix)
@@ -376,6 +441,19 @@ func exportInspectionHandler(ctx *svc.ServiceContext) http.HandlerFunc {
}
}
// materialCodesBySpec 按规格型号模糊匹配物料编码集合(检验查询「型号」框用,L507-510)
func materialCodesBySpec(ctx *svc.ServiceContext, spec string) []string {
mats, err := ctx.EntClient.Material.Query().Where(material.SpecContainsFold(spec)).All(ctx0())
if err != nil {
return nil
}
codes := make([]string, 0, len(mats))
for _, m := range mats {
codes = append(codes, m.Code)
}
return codes
}
// disposalTypeOrNone 处置方式归一化(客户诉求 L137-145:退货/报废/部分入库)
func disposalTypeOrNone(v string) string {
switch v {