diff --git a/inventory-backend/app/api/v1/inbound/product.py b/inventory-backend/app/api/v1/inbound/product.py index 21a09b5..8f9810a 100644 --- a/inventory-backend/app/api/v1/inbound/product.py +++ b/inventory-backend/app/api/v1/inbound/product.py @@ -19,7 +19,7 @@ def search_base(): # ------------------------------------------------------------------ -# 1. 获取列表 +# 1. 获取列表 (修改:支持状态筛选) # ------------------------------------------------------------------ @inbound_product_bp.route('/list', methods=['GET']) def get_list(): @@ -27,14 +27,19 @@ def get_list(): page = request.args.get('page', 1, type=int) limit = request.args.get('pageSize', 15, type=int) keyword = request.args.get('keyword', '') - result = ProductInboundService.get_list(page, limit, keyword) + + # 获取状态列表参数 + statuses_str = request.args.get('statuses', '') + statuses = statuses_str.split(',') if statuses_str else [] + + result = ProductInboundService.get_list(page, limit, keyword, statuses) return jsonify({"code": 200, "msg": "success", "data": result}) except Exception as e: return jsonify({"code": 500, "msg": str(e)}), 500 # ------------------------------------------------------------------ -# 2. 新增入库 (修改:返回创建的对象数据,用于打印) +# 2. 新增入库 # ------------------------------------------------------------------ @inbound_product_bp.route('/submit', methods=['POST']) def submit(): diff --git a/inventory-backend/app/services/inbound/product_service.py b/inventory-backend/app/services/inbound/product_service.py index 80a3f65..0221996 100644 --- a/inventory-backend/app/services/inbound/product_service.py +++ b/inventory-backend/app/services/inbound/product_service.py @@ -2,7 +2,7 @@ from app.extensions import db from app.models.base import MaterialBase from datetime import datetime -from sqlalchemy import or_, func, text +from sqlalchemy import or_, func, text, and_ # Added and_ import traceback import json @@ -81,7 +81,7 @@ class ProductInboundService: barcode=final_barcode, serial_number=data.get('serial_number'), - status='在库', + status=data.get('status', '在库'), warehouse_location=data.get('warehouse_location'), in_quantity=in_qty, @@ -154,9 +154,8 @@ class ProductInboundService: if 'in_quantity' in data: new_qty = float(data['in_quantity']) - old_qty = float(stock.in_quantity) - if new_qty != old_qty: - diff = new_qty - old_qty + diff = new_qty - float(stock.in_quantity) + if diff != 0: stock.in_quantity = new_qty stock.stock_quantity = float(stock.stock_quantity) + diff stock.available_quantity = float(stock.available_quantity) + diff @@ -190,11 +189,12 @@ class ProductInboundService: raise e @staticmethod - def get_list(page, limit, keyword=None): + def get_list(page, limit, keyword=None, statuses=None): from app.models.inbound.product import StockProduct try: query = db.session.query(StockProduct).outerjoin(MaterialBase, StockProduct.base_id == MaterialBase.id) + # 1. 关键词搜索 if keyword: query = query.filter(or_( MaterialBase.name.ilike(f'%{keyword}%'), @@ -205,26 +205,55 @@ class ProductInboundService: StockProduct.sku.ilike(f'%{keyword}%') )) + # 2. 状态筛选与零库存隐藏逻辑 + if not statuses: + statuses = ['在库', '借库'] + + # 如果筛选包含'已出库',则显示所有数量;否则隐藏 stock_quantity <= 0 的记录 + if '已出库' in statuses: + query = query.filter(StockProduct.status.in_(statuses)) + else: + query = query.filter( + and_( + StockProduct.status.in_(statuses), + StockProduct.stock_quantity > 0 + ) + ) + pagination = query.order_by(StockProduct.id.desc()).paginate(page=page, per_page=limit, error_out=False) + # 3. 数据组装 (移除聚合逻辑,改为单行数据) current_items = pagination.items - base_ids = list(set([i.base_id for i in current_items])) - stock_map = {} - if base_ids: - aggs = db.session.query( - StockProduct.base_id, - func.sum(StockProduct.stock_quantity).label('s'), - func.sum(StockProduct.available_quantity).label('a') - ).filter(StockProduct.base_id.in_(base_ids)).group_by(StockProduct.base_id).all() - for a in aggs: - stock_map[a.base_id] = {'s': float(a.s or 0), 'a': float(a.a or 0)} + + # 移除聚合查询代码... + + def parse_img(json_str): + if not json_str: return [] + try: + return json.loads(json_str) if json_str.startswith('[') else [json_str] + except: + return [] items = [] for item in current_items: d = item.to_dict() - stats = stock_map.get(item.base_id, {'s': 0, 'a': 0}) - d['sum_stock'] = stats['s'] - d['sum_available'] = stats['a'] + + # 直接使用当前行的库存,不再聚合 + d['qty_stock'] = float(item.stock_quantity or 0) + d['qty_available'] = float(item.available_quantity or 0) + + # 兼容前端字段 key + d['sum_stock'] = d['qty_stock'] + d['sum_available'] = d['qty_available'] + + # 图片/链接解析 + d['product_photo'] = parse_img(item.product_photo) + d['quality_report_link'] = parse_img(item.quality_report_link) + d['inspection_report_link'] = parse_img(item.inspection_report_link) + + # 打印ID + d['global_print_id'] = item.global_print_id + items.append(d) return {"total": pagination.total, "items": items} diff --git a/inventory-web/src/views/stock/inbound/product.vue b/inventory-web/src/views/stock/inbound/product.vue index 341b860..4f10be1 100644 --- a/inventory-web/src/views/stock/inbound/product.vue +++ b/inventory-web/src/views/stock/inbound/product.vue @@ -2,10 +2,32 @@