1. 通用优化: - 统一系统标题为"库房客户端"/"MES产线控制",移除北自所前缀 - 调整内置账号密码为统一123456,优化密码校验逻辑 - 新增数据库自动创建逻辑,简化部署流程 - 修复日志时间格式配置,优化日志输出 - 新增纯数字密码安全提示 2. MES系统优化: - 新增日排产管理功能,支持增删改查与自动算料生成备料单 - 重构BOM模块,改为按产品编码维护而非工单维度 - 新增工艺参数模板配置与手动报工页面 - 新增产品类型自动编码功能 - 优化菜单结构,调整工单管理、扫码报工等页面名称与路由 - 新增删除日排产接口与权限保护 - 修复物料清单查询逻辑,适配新BOM结构 - 新增refreshToken支持,优化登录会话管理 3. WMS系统优化: - 新增基础数据维护页面,支持区域与物料档案管理 - 新增工单列表下拉接口,对接MES获取未完成工单优先展示 - 优化入库管理提示文案,替换英文提示为中文 - 修复精密件入库校验逻辑,优化错误提示 - 优化Excel导入功能,新增备注字段支持 - 优化登录页面与菜单文案,统一备料台账名称 - 新增自动打开浏览器功能,优化客户端启动体验 - 修复备料出库页面查询提示文案 - 新增WMS与MES对接配置,完善内部API调用逻辑 4. 其他优化: - 删除冗余的旧版静态资源文件,更新资源引用路径 - 新增帮助文档,完善基础数据模块说明 - 修复多处文案不统一、英文残留问题
133 lines
3.6 KiB
Go
133 lines
3.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"bj_power_wms/ent/inventorybatch"
|
|
"bj_power_wms/ent/material"
|
|
"bj_power_wms/internal/svc"
|
|
|
|
"github.com/xuri/excelize/v2"
|
|
)
|
|
|
|
// excelInboundHandler Excel 批量导入入库(结构件)
|
|
// 列头(第一行忽略):物料编码 | 批次号(可空,自动生成) | 数量 | 生产日期 | 供应商 | 区域 | 备注
|
|
func excelInboundHandler(ctx *svc.ServiceContext) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
if err := r.ParseMultipartForm(20 << 20); err != nil {
|
|
fail(w, http.StatusBadRequest, "文件上传失败: "+err.Error())
|
|
return
|
|
}
|
|
f, _, err := r.FormFile("file")
|
|
if err != nil {
|
|
fail(w, http.StatusBadRequest, "缺少 file 字段")
|
|
return
|
|
}
|
|
defer f.Close()
|
|
|
|
xl, err := excelize.OpenReader(f)
|
|
if err != nil {
|
|
fail(w, http.StatusBadRequest, "无法解析 Excel: "+err.Error())
|
|
return
|
|
}
|
|
defer xl.Close()
|
|
sheet := xl.GetSheetList()[0]
|
|
rows, err := xl.GetRows(sheet)
|
|
if err != nil {
|
|
fail(w, http.StatusBadRequest, "读取工作表失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
type resultRow struct {
|
|
Row int `json:"row"`
|
|
Code string `json:"materialCode"`
|
|
BatchNo string `json:"batchNo"`
|
|
Qty int `json:"quantity"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
results := []resultRow{}
|
|
success := 0
|
|
|
|
for i, row := range rows {
|
|
if i == 0 {
|
|
continue // 表头
|
|
}
|
|
cell := func(idx int) string {
|
|
if idx < len(row) {
|
|
return strings.TrimSpace(row[idx])
|
|
}
|
|
return ""
|
|
}
|
|
code := cell(0)
|
|
batchNo := cell(1)
|
|
qtyStr := cell(2)
|
|
qty := atoi(qtyStr, 0)
|
|
prodDate := cell(3)
|
|
supplier := cell(4)
|
|
zone := cell(5)
|
|
remark := cell(6)
|
|
|
|
res := resultRow{Row: i + 1, Code: code, BatchNo: batchNo, Qty: qty}
|
|
|
|
switch {
|
|
case code == "":
|
|
res.Error = "物料编码为空"
|
|
case qty <= 0:
|
|
res.Error = "数量必须大于 0"
|
|
default:
|
|
m, err := ctx.EntClient.Material.Query().
|
|
Where(material.CodeEQ(code)).Only(ctx0())
|
|
if err != nil {
|
|
res.Error = "物料不存在"
|
|
} else if m.ManageMode == 2 {
|
|
res.Error = "精密件请使用 SN 扫码入库,不支持 Excel 导入"
|
|
} else {
|
|
if batchNo == "" {
|
|
batchNo = genBatchNo(code)
|
|
}
|
|
// 同批次追加或新建
|
|
existing, err := ctx.EntClient.InventoryBatch.Query().
|
|
Where(inventorybatch.BatchNoEQ(batchNo)).Only(ctx0())
|
|
if err == nil {
|
|
ctx.EntClient.InventoryBatch.UpdateOneID(existing.ID).
|
|
SetQuantity(existing.Quantity + qty).
|
|
SetNillableSupplier(strPtr(supplier)).
|
|
ExecX(ctx0())
|
|
} else {
|
|
ctx.EntClient.InventoryBatch.Create().
|
|
SetBatchNo(batchNo).
|
|
SetMaterialCode(code).
|
|
SetNillableMaterialName(strPtr(m.Name)).
|
|
SetQuantity(qty).
|
|
SetLockedQty(0).
|
|
SetNillableProductionDate(strPtr(prodDate)).
|
|
SetNillableSupplier(strPtr(supplier)).
|
|
SetQualityStatus("未检").
|
|
SetNillableZoneCode(strPtr(zone)).
|
|
SaveX(ctx0())
|
|
}
|
|
inboundNo := "IB" + nowStr() + fmt.Sprintf("%03d", i)
|
|
ctx.EntClient.InboundOrder.Create().
|
|
SetInboundNo(inboundNo).
|
|
SetNillableInboundType(strPtr("purchase")).
|
|
SetMaterialCode(code).
|
|
SetNillableMaterialName(strPtr(m.Name)).
|
|
SetManageMode(1).
|
|
SetNillableZoneCode(strPtr(zone)).
|
|
SetQuantity(qty).
|
|
SetNillableRemark(strPtr(remark)).
|
|
SetOperator("excel-import").
|
|
SaveX(ctx0())
|
|
res.BatchNo = batchNo
|
|
success++
|
|
}
|
|
}
|
|
results = append(results, res)
|
|
}
|
|
|
|
ok(w, map[string]any{"total": len(results), "success": success, "rows": results})
|
|
}
|
|
}
|