feat: 优化库位树UI层级颜色,并将入库页面库位输入升级为级联选择器
This commit is contained in:
180
inventory-backend/app/api/v1/warehouse.py
Normal file
180
inventory-backend/app/api/v1/warehouse.py
Normal file
@ -0,0 +1,180 @@
|
||||
# inventory-backend/app/api/v1/warehouse.py
|
||||
from flask import Blueprint, request, jsonify
|
||||
from app.extensions import db
|
||||
from app.models.system import SysWarehouseLocation
|
||||
|
||||
warehouse_bp = Blueprint('warehouse', __name__, url_prefix='/api/v1/warehouse')
|
||||
|
||||
|
||||
def build_tree(nodes, parent_id=None):
|
||||
"""
|
||||
将平铺的数据构建为树形结构
|
||||
"""
|
||||
tree = []
|
||||
for node in nodes:
|
||||
if node.parent_id == parent_id:
|
||||
children = build_tree(nodes, node.id)
|
||||
node_dict = node.to_dict()
|
||||
if children:
|
||||
node_dict['children'] = children
|
||||
else:
|
||||
node_dict['children'] = []
|
||||
tree.append(node_dict)
|
||||
return tree
|
||||
|
||||
|
||||
@warehouse_bp.route('/tree', methods=['GET'])
|
||||
def get_tree():
|
||||
"""
|
||||
获取库位树形结构
|
||||
"""
|
||||
try:
|
||||
# 查询所有库位
|
||||
all_locations = SysWarehouseLocation.query.order_by(SysWarehouseLocation.level, SysWarehouseLocation.id).all()
|
||||
|
||||
# 构建树形结构
|
||||
tree_data = build_tree(all_locations, parent_id=None)
|
||||
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'msg': 'success',
|
||||
'data': tree_data
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'code': 500,
|
||||
'msg': str(e),
|
||||
'data': None
|
||||
}), 500
|
||||
|
||||
|
||||
@warehouse_bp.route('', methods=['POST'])
|
||||
def create_location():
|
||||
"""
|
||||
创建库位
|
||||
"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
name = data.get('name', '').strip()
|
||||
parent_id = data.get('parent_id') # None 表示顶级
|
||||
is_enabled = data.get('is_enabled', True)
|
||||
|
||||
if not name:
|
||||
return jsonify({'code': 400, 'msg': '库位名称不能为空', 'data': None})
|
||||
|
||||
# 计算 level 和 full_path
|
||||
if parent_id is None:
|
||||
level = 0
|
||||
full_path = name
|
||||
parent_full_path = ''
|
||||
else:
|
||||
parent = SysWarehouseLocation.query.get(parent_id)
|
||||
if not parent:
|
||||
return jsonify({'code': 400, 'msg': '父级库位不存在', 'data': None})
|
||||
level = parent.level + 1
|
||||
parent_full_path = parent.full_path or ''
|
||||
full_path = f"{parent_full_path}/{name}" if parent_full_path else name
|
||||
|
||||
location = SysWarehouseLocation(
|
||||
name=name,
|
||||
parent_id=parent_id,
|
||||
full_path=full_path,
|
||||
level=level,
|
||||
is_enabled=is_enabled
|
||||
)
|
||||
db.session.add(location)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'msg': '创建成功',
|
||||
'data': location.to_dict()
|
||||
})
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return jsonify({
|
||||
'code': 500,
|
||||
'msg': str(e),
|
||||
'data': None
|
||||
}), 500
|
||||
|
||||
|
||||
@warehouse_bp.route('/<int:location_id>', methods=['PUT'])
|
||||
def update_location(location_id):
|
||||
"""
|
||||
更新库位
|
||||
"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
location = SysWarehouseLocation.query.get(location_id)
|
||||
|
||||
if not location:
|
||||
return jsonify({'code': 404, 'msg': '库位不存在', 'data': None})
|
||||
|
||||
# 更新名称
|
||||
if 'name' in data and data['name']:
|
||||
new_name = data['name'].strip()
|
||||
if new_name != location.name:
|
||||
# 需要更新 full_path
|
||||
parent = location.parent
|
||||
if parent:
|
||||
location.full_path = f"{parent.full_path}/{new_name}" if parent.full_path else new_name
|
||||
else:
|
||||
location.full_path = new_name
|
||||
location.name = new_name
|
||||
|
||||
# 更新启用状态
|
||||
if 'is_enabled' in data:
|
||||
location.is_enabled = data['is_enabled']
|
||||
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'msg': '更新成功',
|
||||
'data': location.to_dict()
|
||||
})
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return jsonify({
|
||||
'code': 500,
|
||||
'msg': str(e),
|
||||
'data': None
|
||||
}), 500
|
||||
|
||||
|
||||
@warehouse_bp.route('/<int:location_id>', methods=['DELETE'])
|
||||
def delete_location(location_id):
|
||||
"""
|
||||
删除库位(级联删除子库位)
|
||||
"""
|
||||
try:
|
||||
location = SysWarehouseLocation.query.get(location_id)
|
||||
|
||||
if not location:
|
||||
return jsonify({'code': 404, 'msg': '库位不存在', 'data': None})
|
||||
|
||||
# 递归删除所有子库位
|
||||
def delete_recursive(loc):
|
||||
# 先删除所有子节点
|
||||
children = SysWarehouseLocation.query.filter_by(parent_id=loc.id).all()
|
||||
for child in children:
|
||||
delete_recursive(child)
|
||||
# 再删除自身
|
||||
db.session.delete(loc)
|
||||
|
||||
delete_recursive(location)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'msg': '删除成功',
|
||||
'data': None
|
||||
})
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return jsonify({
|
||||
'code': 500,
|
||||
'msg': str(e),
|
||||
'data': None
|
||||
}), 500
|
||||
Reference in New Issue
Block a user