diff --git a/db_migrations/add_bom_remark.sql b/db_migrations/add_bom_remark.sql new file mode 100644 index 0000000..eebda07 --- /dev/null +++ b/db_migrations/add_bom_remark.sql @@ -0,0 +1,36 @@ +-- ============================================================================= +-- 一次性迁移:BOM 级备注落库 +-- ----------------------------------------------------------------------------- +-- 背景: +-- 前端 BomManage.vue 一直有"备注"输入框(v-model="form.remark"),提交时也 +-- 确实放进了 payload(BomManage.vue:1273),但后端 BomService.save_bom() 从 +-- 未读取 data['remark'],父件级备注被**静默丢弃**——填了、保存、再打开必为空。 +-- +-- 根因是数据模型缺位:bom_table 是子件明细表(一行 = 一个子件),表里只有 +-- 子件级的 remark 列,没有任何位置存放 BOM 级备注。 +-- 连带 bug:读取侧 get_bom_detail() 用 first.BomTable.remark(第一个子件行的 +-- 备注)冒充主表备注,所以查看时会显示某个子件的备注(如"白色")或空。 +-- +-- 方案: +-- bom_table / bom_draft_table 各增加 bom_remark 列,沿用 parent_id、is_enabled +-- 既有的冗余写法:同一 BOM 版本的每一行存同一份值,读取时取首行。 +-- 与既有 remark(子件级)语义分离,互不干扰。 +-- +-- 存量数据: +-- 无法回填 —— 历史上填过的备注从未入库,任何位置都找不到,只能从本迁移 +-- 之后开始记录。这是本次修复的已知代价。 +-- +-- 执行方式: docker exec -i inventory_db psql -U test -d inventory_system < 本文件 +-- 注意: 若后端启用 Redis 缓存(bom:tree:*),部署后需清缓存或重启后端, +-- 避免 12h 内命中旧值。 +-- ============================================================================= + +BEGIN; + +ALTER TABLE bom_table ADD COLUMN IF NOT EXISTS bom_remark text; +ALTER TABLE bom_draft_table ADD COLUMN IF NOT EXISTS bom_remark text; + +COMMENT ON COLUMN bom_table.bom_remark IS 'BOM级备注(父件级,冗余存于每行,读取取首行)'; +COMMENT ON COLUMN bom_draft_table.bom_remark IS 'BOM级备注(父件级,冗余存于每行,读取取首行)'; + +COMMIT; diff --git a/inventory-backend/app/models/bom.py b/inventory-backend/app/models/bom.py index 655642e..1665826 100644 --- a/inventory-backend/app/models/bom.py +++ b/inventory-backend/app/models/bom.py @@ -25,6 +25,10 @@ class BomTable(db.Model): loss_rate = db.Column(db.Numeric(5, 2), comment='损耗率%', default=0, nullable=True) remark = db.Column(db.Text, comment='备注') + # ★ BOM 级备注(父件级):与 parent_id/is_enabled 一样冗余存于本版本每一行,读取取首行。 + # 上面的 remark 是**子件级**备注,语义不同,勿混用。 + bom_remark = db.Column(db.Text, comment='BOM级备注(父件级,冗余存于每行,读取取首行)') + # ★ 子件引用的"自制 BOM"版本:子件物料若本身是自制件(作为其它 BOM 的父件), # 此列记录该子件实际引用的配方版本((bom_no, version) 共同定位),由新建/编辑 BOM 时选版本保存。 # 外购件/无下级 BOM 的子件这两列为 NULL。 diff --git a/inventory-backend/app/models/bom_draft.py b/inventory-backend/app/models/bom_draft.py index 4ca14dd..51e4be8 100644 --- a/inventory-backend/app/models/bom_draft.py +++ b/inventory-backend/app/models/bom_draft.py @@ -23,6 +23,10 @@ class BomDraftTable(db.Model): loss_rate = db.Column(db.Numeric(5, 2), default=0, nullable=True, comment='损耗率%') remark = db.Column(db.Text, comment='备注') + # ★ BOM 级备注(父件级):与 bom_table.bom_remark 对齐,草稿暂存/发布期间不丢失。 + # 上面的 remark 是**子件级**备注。占位头行(child_id IS NULL)同样携带该值。 + bom_remark = db.Column(db.Text, comment='BOM级备注(父件级,冗余存于每行,读取取首行)') + # ★ 子件引用的"自制 BOM"版本:与 bom_table 的 child_bom_no/child_bom_version 对齐, # 保证草稿暂存/载入期间不丢失所选版本。 child_bom_no = db.Column(db.String(100), nullable=True, index=True, comment='子件引用的自制BOM编号')