Files
KCGL/inventory-web/src/api/bom.ts

111 lines
3.2 KiB
TypeScript
Raw Normal View History

import request from '@/utils/request'
// 获取BOM列表
export function getBomList(params?: any) {
return request({
url: '/v1/bom/list',
method: 'get',
params
})
}
perf: 系统级性能优化与并发安全修复 ## 并发安全修复 (4处) - scrap.py: 报废执行添加 SELECT FOR UPDATE 悲观锁,消除 TOCTOU 竞态 - stock.py (adjust_stock): 盘点调整添加 for_update=True 行锁 - outbound_service.py: 低库存预警 SMTP 调用移到 commit 之后,避免长事务 - trans_service.py: execute_dispatch 按 (source_table, id) 排序 items,消除死锁风险 ## N+1 查询优化 (2处) - inventory_task.py: _prefetch_inventory_map 单条 UNION ALL+GROUP BY 替代循环内逐条查询(N*4次→2次) - stock.py (export_stocktake): get_borrowed_qty 批量 GROUP BY 替代逐条 TransBorrow 查询(~18000次→1次) ## BOM 列表性能重构 - bom_service.py: get_bom_list 单条 GROUP BY+string_agg+分页,消除 N+1 循环查询 - bom_service.py: 新增 get_bom_summary (轻量 GROUP BY category+COUNT) - bom.py: 新增 /api/v1/bom/summary 路由,/list 支持 category 过滤 ## Odoo 基础信息懒加载 - base_service.py: 新增 get_odoo_summary (GROUP BY category+COUNT) - base.py: 新增 /api/v1/inbound/base/odoo-summary 路由 - buyOdoo.vue: 懒加载分组架构 (fetchOdooSummary + loadGroupItems) - material_base.ts: 新增 getOdooSummary API ## 前端 Bug 修复 - BomManage.vue: 懒加载分组 (fetchBomSummary + loadGroupItems + collapse) - BomManage.vue: 适配新 API 格式 (res.data.items 替代 res.data) - buyOdoo.vue: 移除 "点击展开加载" 文字 - Selection.vue + borrow/apply/index.vue: openBomSelect 适配新 API 格式
2026-07-15 17:37:57 +08:00
// 获取BOM分组摘要(懒加载用,轻量 GROUP BY category + COUNT)
export function getBomSummary(params?: { keyword?: string }) {
return request({
url: '/v1/bom/summary',
method: 'get',
params
})
}
2026-06-25 15:21:43 +08:00
// 获取BOM详情(含库存信息)
export function getBomWithStock(bomNo: string, version?: string) {
2026-06-25 15:21:43 +08:00
const trimmed = bomNo.replace(/^\/+|\/+$/g, '');
const encoded = encodeURIComponent(trimmed);
return request({
url: `/v1/bom/stock/${encoded}`,
method: 'get',
params: version ? { version } : {}
2026-06-25 15:21:43 +08:00
})
}
// 获取某物料作为父件时的启用 BOM 版本清单(自制件子件版本下拉数据源)
export function getChildBomVersions(childId: number) {
return request({
url: '/v1/bom/self-bom-versions',
method: 'get',
params: { child_id: childId }
})
}
// 获取BOM详情
export function getBomDetail(bomNo: string, version?: string) {
// 去除首尾斜杠,保留中间斜杠并进行 URL 编码
const trimmed = bomNo.replace(/^\/+|\/+$/g, '');
const encoded = encodeURIComponent(trimmed);
const url = version
? `/v1/bom/detail/${encoded}?version=${encodeURIComponent(version)}`
: `/v1/bom/detail/${encoded}`;
return request({
url,
method: 'get'
})
}
// 仅更新 BOM 启用/停用状态(查看/只读视图的开关专用,不触发整表保存)
export function updateBomStatus(data: { bom_no: string; version: string; is_enabled: boolean }) {
return request({
url: '/v1/bom/status',
method: 'post',
data
})
}
// 归档/取消归档(仍启用可编辑,但不再作为其它 BOM 子件的引用候选)
export function updateBomArchive(data: { bom_no: string; version: string; is_archived: boolean }) {
return request({
url: '/v1/bom/archive',
method: 'post',
data
})
}
// 保存BOM
export function saveBom(data: any) {
return request({
url: '/v1/bom/save',
method: 'post',
data
})
}
// 删除BOM
export function deleteBom(bomNo: string, version: string) {
// 去除首尾斜杠,保留中间斜杠并进行 URL 编码
const trimmed = bomNo.replace(/^\/+|\/+$/g, '');
const encoded = encodeURIComponent(trimmed);
return request({
url: `/v1/bom/${encoded}?version=${encodeURIComponent(version)}`,
method: 'delete'
})
}
// ==========================================
// BOM 草稿相关接口
// ==========================================
// 1. 暂存草稿
export function saveDraft(data: any) {
return request({ url: '/v1/bom/draft/save', method: 'post', data })
}
// 2. 读取草稿详情
export function getDraftDetail(params: { bom_no: string; version?: string }) {
return request({ url: '/v1/bom/draft/detail', method: 'get', params })
}
// 3. 发布草稿
export function publishDraft(data: { bom_no: string; version: string }) {
return request({ url: '/v1/bom/draft/publish', method: 'post', data })
}