4.29扫码获取库位小工具接口
This commit is contained in:
@ -2,8 +2,10 @@ from flask import Blueprint
|
||||
from .inbound import inbound_bp
|
||||
from .bom import bom_bp
|
||||
from .common import common_bp
|
||||
from .scan import scan_bp
|
||||
|
||||
v1_bp = Blueprint('v1', __name__)
|
||||
v1_bp.register_blueprint(inbound_bp, url_prefix='/inbound')
|
||||
v1_bp.register_blueprint(bom_bp, url_prefix='/bom')
|
||||
v1_bp.register_blueprint(common_bp, url_prefix='/common')
|
||||
v1_bp.register_blueprint(scan_bp, url_prefix='/scan')
|
||||
|
||||
@ -381,6 +381,8 @@ def batch_set_warning():
|
||||
red_val = item.get('redThreshold')
|
||||
warning.yellow_threshold = float(yellow_val) if yellow_val is not None else 0
|
||||
warning.red_threshold = float(red_val) if red_val is not None else 0
|
||||
warning.yellow_emails = item.get('yellowEmails', warning.yellow_emails)
|
||||
warning.red_emails = item.get('redEmails', warning.red_emails)
|
||||
updated_count += 1
|
||||
else:
|
||||
# 创建新记录
|
||||
@ -390,7 +392,9 @@ def batch_set_warning():
|
||||
base_id=base_id,
|
||||
is_enabled=item.get('isEnabled', False),
|
||||
yellow_threshold=float(yellow_val) if yellow_val is not None else 0,
|
||||
red_threshold=float(red_val) if red_val is not None else 0
|
||||
red_threshold=float(red_val) if red_val is not None else 0,
|
||||
yellow_emails=item.get('yellowEmails', ''),
|
||||
red_emails=item.get('redEmails', '')
|
||||
)
|
||||
db.session.add(warning)
|
||||
created_count += 1
|
||||
@ -412,7 +416,48 @@ def batch_set_warning():
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# 2.6 批量设置强制质检 API (POST /api/v1/inbound/base/batch-inspection)
|
||||
# 2.6 标记已采购 API (POST /api/v1/inbound/base/warning/mark-ordered)
|
||||
# ==============================================================================
|
||||
@inbound_base_bp.route('/warning/mark-ordered', methods=['POST'])
|
||||
@permission_required('material_list:edit_warning')
|
||||
def mark_warning_ordered():
|
||||
"""
|
||||
前端标记预警物料已处理采购(标记 is_ordered)
|
||||
请求体格式: {"baseId": 123, "isOrdered": true}
|
||||
"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return jsonify({"code": 400, "msg": "No data provided"}), 400
|
||||
|
||||
base_id = data.get('baseId')
|
||||
if not base_id:
|
||||
return jsonify({"code": 400, "msg": "baseId 不能为空"}), 400
|
||||
|
||||
is_ordered = bool(data.get('isOrdered', False))
|
||||
|
||||
warning = MaterialWarningSetting.query.filter_by(base_id=base_id).first()
|
||||
if not warning:
|
||||
return jsonify({"code": 404, "msg": f"物料ID {base_id} 的预警配置不存在"}), 404
|
||||
|
||||
warning.is_ordered = is_ordered
|
||||
db.session.commit()
|
||||
|
||||
status_text = "已标记为已采购" if is_ordered else "已重置为未采购"
|
||||
return jsonify({
|
||||
"code": 200,
|
||||
"msg": status_text,
|
||||
"data": warning.to_dict()
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
current_app.logger.error(f"标记已采购失败: {str(e)}")
|
||||
return jsonify({"code": 500, "msg": f"标记已采购失败: {str(e)}"}), 500
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# 2.7 批量设置强制质检 API (POST /api/v1/inbound/base/batch-inspection)
|
||||
# ==============================================================================
|
||||
@inbound_base_bp.route('/batch-inspection', methods=['POST'])
|
||||
@permission_required('material_list:operation')
|
||||
|
||||
69
inventory-backend/app/api/v1/scan/__init__.py
Normal file
69
inventory-backend/app/api/v1/scan/__init__.py
Normal file
@ -0,0 +1,69 @@
|
||||
"""
|
||||
扫码查库存接口(移动端专用)
|
||||
GET /api/v1/scan/inventory?barcode=xxx
|
||||
"""
|
||||
from flask import Blueprint, jsonify, request
|
||||
from app.extensions import db
|
||||
from app.models.base import MaterialBase
|
||||
from app.models.inbound.buy import StockBuy
|
||||
from app.models.inbound.product import StockProduct
|
||||
from app.models.inbound.semi import StockSemi
|
||||
|
||||
scan_bp = Blueprint('scan', __name__, url_prefix='/scan')
|
||||
|
||||
|
||||
def _build_response(stock_record, stock_type: str) -> dict:
|
||||
"""联表 MaterialBase 提取物料信息并组装返回结构"""
|
||||
material = MaterialBase.query.get(stock_record.base_id)
|
||||
return {
|
||||
'code': 200,
|
||||
'data': {
|
||||
'materialName': material.name if material else '未知物料',
|
||||
'spec': material.spec_model if material else '',
|
||||
'location': stock_record.warehouse_location or '',
|
||||
'quantity': float(stock_record.available_quantity) if stock_record.available_quantity else 0.0,
|
||||
'stockType': stock_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@scan_bp.route('/inventory', methods=['GET'])
|
||||
def scan_inventory():
|
||||
"""
|
||||
扫码精确查找库存
|
||||
入参: barcode (query string)
|
||||
逻辑: 在 StockBuy / StockProduct / StockSemi 三表中精确匹配,只要命中一张即返回
|
||||
"""
|
||||
barcode = (request.args.get('barcode') or '').strip()
|
||||
if not barcode:
|
||||
return jsonify({'code': 400, 'msg': 'barcode 参数不能为空'}), 400
|
||||
|
||||
# 1. 采购库
|
||||
buy = StockBuy.query.filter(
|
||||
StockBuy.barcode == barcode,
|
||||
StockBuy.stock_quantity > 0
|
||||
).first()
|
||||
if buy:
|
||||
return jsonify(_build_response(buy, '采购库'))
|
||||
|
||||
# 2. 成品库
|
||||
product = StockProduct.query.filter(
|
||||
StockProduct.barcode == barcode,
|
||||
StockProduct.stock_quantity > 0
|
||||
).first()
|
||||
if product:
|
||||
return jsonify(_build_response(product, '成品库'))
|
||||
|
||||
# 3. 半成品库
|
||||
semi = StockSemi.query.filter(
|
||||
StockSemi.barcode == barcode,
|
||||
StockSemi.stock_quantity > 0
|
||||
).first()
|
||||
if semi:
|
||||
return jsonify(_build_response(semi, '半成品库'))
|
||||
|
||||
# 4. 全部未命中
|
||||
return jsonify({
|
||||
'code': 404,
|
||||
'msg': f'未找到条码 [{barcode}] 对应的库存记录,或该物料当前库存为零'
|
||||
}), 404
|
||||
Reference in New Issue
Block a user