feat: implement BOM versioning with bom_no and new management APIs

Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
This commit is contained in:
dxc
2026-02-12 09:37:27 +08:00
parent e900326571
commit 6d5d8a6aad
2 changed files with 264 additions and 40 deletions

View File

@ -8,6 +8,81 @@ from sqlalchemy import distinct
bom_bp = Blueprint('bom', __name__)
# ==================== 新版 BOM 接口(基于 bom_no ====================
@bom_bp.route('/list', methods=['GET'])
@jwt_required()
def get_bom_list():
"""获取所有 BOM 配方列表(按 bom_no 分组)"""
try:
data = BomService.get_bom_list()
return jsonify({
'code': 200,
'msg': 'success',
'data': data
})
except Exception as e:
current_app.logger.error(f'获取BOM列表失败: {str(e)}')
return jsonify({'code': 500, 'msg': '内部服务器错误'}), 500
@bom_bp.route('/detail/<bom_no>', methods=['GET'])
@jwt_required()
def get_bom_detail(bom_no):
"""根据 BOM 编号获取配方详情"""
try:
data = BomService.get_bom_detail(bom_no)
if not data:
return jsonify({'code': 404, 'msg': 'BOM 不存在'}), 404
return jsonify({
'code': 200,
'msg': 'success',
'data': data
})
except Exception as e:
current_app.logger.error(f'获取BOM详情失败: {str(e)}')
return jsonify({'code': 500, 'msg': '内部服务器错误'}), 500
@bom_bp.route('/save', methods=['POST'])
@jwt_required()
def save_bom():
"""保存或更新 BOM 配方(支持新建和另存为新版本)"""
try:
req_data = request.get_json()
# 必需字段校验
if 'parent_id' not in req_data or 'children' not in req_data:
return jsonify({'code': 400, 'msg': '缺少 parent_id 或 children 字段'}), 400
bom_no = BomService.save_bom(req_data)
return jsonify({
'code': 200,
'msg': '保存成功',
'data': {'bom_no': bom_no}
})
except ValueError as e:
return jsonify({'code': 400, 'msg': str(e)}), 400
except Exception as e:
current_app.logger.error(f'保存BOM失败: {str(e)}')
return jsonify({'code': 500, 'msg': '内部服务器错误'}), 500
@bom_bp.route('/stock/<bom_no>', methods=['GET'])
@jwt_required()
def get_bom_with_stock_by_no(bom_no):
"""根据 BOM 编号获取配方详情及库存信息"""
try:
data = BomService.get_bom_with_stock_by_bom_no(bom_no)
if not data:
return jsonify({'code': 404, 'msg': 'BOM 不存在'}), 404
return jsonify({
'code': 200,
'msg': 'success',
'data': data
})
except Exception as e:
current_app.logger.error(f'获取BOM库存信息失败: {str(e)}')
return jsonify({'code': 500, 'msg': '内部服务器错误'}), 500
# ==================== 兼容旧接口(保留不改动现有前端) ====================
@bom_bp.route('/<int:parent_id>', methods=['GET'])
@jwt_required()
def get_bom(parent_id):
@ -24,7 +99,7 @@ def get_bom(parent_id):
@bom_bp.route('', methods=['POST'])
@jwt_required()
def save_bom():
def save_bom_legacy():
try:
req_data = request.get_json()
parent_id = req_data.get('parent_id')
@ -61,7 +136,7 @@ def get_material_base_list():
@bom_bp.route('/parents', methods=['GET'])
@jwt_required()
def get_bom_parents():
"""获取所有已定义BOM的父件物料列表"""
"""获取所有已定义BOM的父件物料列表(兼容旧版)"""
try:
subq = db.session.query(BomTable.parent_id).distinct().subquery()
parents = MaterialBase.query.join(subq, MaterialBase.id == subq.c.parent_id).all()