feat: 完成客户第12条需求+多系统改造
1. 新增预警表添加工单号字段,支持按工单号检索预警 2. 添加工单过滤在制品/绩效报表/预警中心查询 3. 补全WMS台账字段口径与权限配置 4. 修复备料单与数量不符处理流程 5. 新增配送进度/库位联动/自动出库功能 6. 修复AGV配送状态更新逻辑 7. 优化退料与库存管理细节
This commit is contained in:
@@ -75,6 +75,8 @@ func EnsureDB(c DatabaseConf) error {
|
||||
// AutoMigrate 启动时自动建表/迁移
|
||||
func AutoMigrate(client *ent.Client) error {
|
||||
ctx := contextBackdrop()
|
||||
// 迁移前补列:必须先于 ent 的 Schema.Create 执行(详见 applyPreMigratePatches 说明)。
|
||||
applyPreMigratePatches(ctx)
|
||||
if err := client.Schema.Create(ctx); err != nil {
|
||||
return fmt.Errorf("自动迁移失败: %w", err)
|
||||
}
|
||||
@@ -94,6 +96,34 @@ func AutoMigrate(client *ent.Client) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// applyPreMigratePatches 必须在 ent 的 Schema.Create 之前执行。
|
||||
//
|
||||
// 背景(2026-09-19 启动 panic 根因):ent(v0.14/Atlas) 给「已存在的表」新增「非空且无默认值」的列时,
|
||||
// 只会先 ADD COLUMN(可空)再 ALTER COLUMN SET NOT NULL;存量行填不上值即报
|
||||
// `column "xxx" of relation "yyy" contains null values (SQLSTATE 23502)`,直接 panic 打断启动。
|
||||
// 因此这类列必须先用「带默认值」的 DDL 补齐(存量行被一次填满),Schema.Create 才能顺利收紧约束;
|
||||
// 业务真实值随后由 applyColumnPatches 回填、并 DROP DEFAULT,使库内结构与 ent schema 完全一致。
|
||||
//
|
||||
// 登记口径:给「既有表」加非空且无默认值的列 → 必须登记在此;
|
||||
// 只加可空列或带默认值的列 → 无需登记(ent 自己 ADD COLUMN 即可)。
|
||||
func applyPreMigratePatches(ctx context.Context) {
|
||||
if rawDB == nil {
|
||||
return
|
||||
}
|
||||
stmts := []string{
|
||||
// 区域库位父子层级重构:存量 zones 表补 level/code(ent schema 中二者均非空且无默认值)。
|
||||
// 这里的默认值仅用于让存量行通过 NOT NULL 收紧,真实层级值由 applyColumnPatches 回填。
|
||||
`ALTER TABLE zones ADD COLUMN IF NOT EXISTS level bigint NOT NULL DEFAULT 4`,
|
||||
`ALTER TABLE zones ADD COLUMN IF NOT EXISTS code character varying NOT NULL DEFAULT ''`,
|
||||
}
|
||||
for _, s := range stmts {
|
||||
if _, err := rawDB.ExecContext(ctx, s); err != nil {
|
||||
// 全新库此时表尚未建立,Schema.Create 会按 schema 全新建表,属正常情况
|
||||
slog.Warn("迁移前补列跳过(新库属正常): " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// applyColumnPatches 幂等补齐已有表的新增列。
|
||||
// 背景:ent 的 Schema.Create 对已存在表不会 ADD COLUMN,故新增字段必须在此登记,
|
||||
// 否则新库正常、存量库缺列导致运行时 500。
|
||||
@@ -124,6 +154,10 @@ func applyColumnPatches(ctx context.Context) {
|
||||
`ALTER TABLE outbound_orders ADD COLUMN IF NOT EXISTS ownership_type text`,
|
||||
`ALTER TABLE outbound_orders ADD COLUMN IF NOT EXISTS ownership_no text`,
|
||||
`ALTER TABLE outbound_orders ADD COLUMN IF NOT EXISTS target_station text`,
|
||||
// 出库库位四级贯通(客户诉求:出库与入库同口径,2026-09-19):区域已有 zone_code,补货架/层/位置
|
||||
`ALTER TABLE outbound_orders ADD COLUMN IF NOT EXISTS shelf_no text`,
|
||||
`ALTER TABLE outbound_orders ADD COLUMN IF NOT EXISTS layer_no text`,
|
||||
`ALTER TABLE outbound_orders ADD COLUMN IF NOT EXISTS position_no text`,
|
||||
// 库存明细:库位贯通 货架/层/位置(问题记录 一.4)
|
||||
`ALTER TABLE inventories ADD COLUMN IF NOT EXISTS shelf_no text`,
|
||||
`ALTER TABLE inventories ADD COLUMN IF NOT EXISTS layer_no text`,
|
||||
@@ -183,6 +217,10 @@ func applyColumnPatches(ctx context.Context) {
|
||||
SELECT DISTINCT 3, z.layer_no, z.shelf_no, z.zone_code, z.shelf_no, z.layer_no, '启用', EXTRACT(EPOCH FROM NOW())::bigint, EXTRACT(EPOCH FROM NOW())::bigint
|
||||
FROM zones z WHERE z.layer_no IS NOT NULL AND z.layer_no <> ''
|
||||
AND NOT EXISTS (SELECT 1 FROM zones l WHERE l.level = 3 AND l.zone_code = z.zone_code AND l.shelf_no = z.shelf_no AND l.code = z.layer_no)`,
|
||||
// level/code 回填完毕,撤销 applyPreMigratePatches 补列时的临时默认值,
|
||||
// 使库内结构与 ent schema 对齐(非空、无默认值)。
|
||||
`ALTER TABLE zones ALTER COLUMN level DROP DEFAULT`,
|
||||
`ALTER TABLE zones ALTER COLUMN code DROP DEFAULT`,
|
||||
// U18 盘点四级贯通:盘点快照冻结货架/层/位置,盘点差异可精确定位到货位。
|
||||
`ALTER TABLE stocktake_items ADD COLUMN IF NOT EXISTS shelf_no text`,
|
||||
`ALTER TABLE stocktake_items ADD COLUMN IF NOT EXISTS layer_no text`,
|
||||
@@ -204,6 +242,13 @@ func applyColumnPatches(ctx context.Context) {
|
||||
`ALTER TABLE attachments ADD COLUMN IF NOT EXISTS deleted boolean NOT NULL DEFAULT false`,
|
||||
`ALTER TABLE attachments ADD COLUMN IF NOT EXISTS deleted_at bigint`,
|
||||
`ALTER TABLE attachments ADD COLUMN IF NOT EXISTS deleted_by text`,
|
||||
// 台账口径拆分(2026-09-19 出库与配送闭环):一个字段只有一个写者。
|
||||
// returned_qty = 退库收货回写;consumed_qty = 报工反冲核销。均带默认值,存量行走 ent 亦可。
|
||||
`ALTER TABLE order_material_ledgers ADD COLUMN IF NOT EXISTS returned_qty bigint NOT NULL DEFAULT 0`,
|
||||
`ALTER TABLE order_material_ledgers ADD COLUMN IF NOT EXISTS consumed_qty bigint NOT NULL DEFAULT 0`,
|
||||
// 出库单状态 + 是否叫AGV(配送进度只读展示用;「已接料」不落在本表)
|
||||
`ALTER TABLE outbound_orders ADD COLUMN IF NOT EXISTS status text NOT NULL DEFAULT '已出库'`,
|
||||
`ALTER TABLE outbound_orders ADD COLUMN IF NOT EXISTS need_agv boolean NOT NULL DEFAULT false`,
|
||||
}
|
||||
for _, s := range stmts {
|
||||
if _, err := rawDB.ExecContext(ctx, s); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user