feat: add column sorting and advanced filtering for purchase inbound
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
This commit is contained in:
@ -106,7 +106,7 @@ def search_base():
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 1. 获取列表 (修改:接收 category 和 material_type)
|
||||
# 1. 获取列表 (修改:接收 category, material_type, orderByColumn, isAsc, advancedFilters)
|
||||
# ------------------------------------------------------------------
|
||||
@inbound_buy_bp.route('/list', methods=['GET'])
|
||||
@permission_required('inbound_buy')
|
||||
@ -121,11 +121,24 @@ def get_list():
|
||||
material_type = request.args.get('material_type', '')
|
||||
company = request.args.get('company', '')
|
||||
|
||||
# 排序参数
|
||||
order_by = request.args.get('orderByColumn', '').strip()
|
||||
is_asc = request.args.get('isAsc', '').strip()
|
||||
|
||||
# 高级筛选参数
|
||||
advanced_filters_raw = request.args.get('advancedFilters', '[]')
|
||||
import json
|
||||
try:
|
||||
advanced_filters = json.loads(advanced_filters_raw) if advanced_filters_raw else []
|
||||
except json.JSONDecodeError:
|
||||
advanced_filters = []
|
||||
|
||||
# 状态参数处理
|
||||
statuses_str = request.args.get('statuses', '')
|
||||
statuses = statuses_str.split(',') if statuses_str else []
|
||||
|
||||
result = BuyInboundService.get_list(page, limit, keyword, statuses, category, material_type, company)
|
||||
result = BuyInboundService.get_list(page, limit, keyword, statuses, category, material_type, company,
|
||||
order_by, is_asc, advanced_filters)
|
||||
# 字段级脱敏
|
||||
user_permissions = get_current_user_permissions()
|
||||
if result.get('items'):
|
||||
|
||||
@ -237,11 +237,13 @@ class BuyInboundService:
|
||||
raise e
|
||||
|
||||
# ============================================================
|
||||
# 5. 获取列表
|
||||
# 5. 获取列表 (支持排序和高级筛选)
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def get_list(page, limit, keyword=None, statuses=None, category=None, material_type=None, company=None):
|
||||
def get_list(page, limit, keyword=None, statuses=None, category=None, material_type=None, company=None,
|
||||
order_by='', is_asc='', advanced_filters=None):
|
||||
try:
|
||||
from sqlalchemy import and_, or_
|
||||
query = db.session.query(StockBuy).outerjoin(MaterialBase, StockBuy.base_id == MaterialBase.id)
|
||||
|
||||
# 1. 通用关键词搜索
|
||||
@ -279,7 +281,109 @@ class BuyInboundService:
|
||||
else:
|
||||
query = query.filter(and_(StockBuy.status.in_(statuses), StockBuy.stock_quantity > 0))
|
||||
|
||||
pagination = query.order_by(StockBuy.in_date.desc()).paginate(page=page, per_page=limit, error_out=False)
|
||||
# 5. 高级动态筛选
|
||||
if advanced_filters:
|
||||
allowed_fields = {
|
||||
'company_name': MaterialBase.company_name,
|
||||
'material_name': MaterialBase.name,
|
||||
'material_type': MaterialBase.material_type,
|
||||
'category': MaterialBase.category,
|
||||
'spec_model': MaterialBase.spec_model,
|
||||
'unit': MaterialBase.unit,
|
||||
'sku': StockBuy.sku,
|
||||
'barcode': StockBuy.barcode,
|
||||
'batch_number': StockBuy.batch_number,
|
||||
'serial_number': StockBuy.serial_number,
|
||||
'warehouse_location': StockBuy.warehouse_location,
|
||||
'status': StockBuy.status,
|
||||
'inspection_status': StockBuy.inspection_status,
|
||||
'qty_inbound': StockBuy.in_quantity,
|
||||
'qty_stock': StockBuy.stock_quantity,
|
||||
'qty_available': StockBuy.available_quantity,
|
||||
'unit_price': StockBuy.pre_tax_unit_price,
|
||||
'total_price': StockBuy.total_price,
|
||||
'tax_rate': StockBuy.tax_rate,
|
||||
'currency': StockBuy.currency,
|
||||
'exchange_rate': StockBuy.exchange_rate,
|
||||
'supplier_name': StockBuy.supplier_name,
|
||||
'purchaser': StockBuy.buyer_name,
|
||||
'purchaser_email': StockBuy.buyer_email,
|
||||
'source_link': StockBuy.original_link,
|
||||
'detail_link': StockBuy.detail_link,
|
||||
}
|
||||
filter_conditions = []
|
||||
for condition in advanced_filters:
|
||||
field = condition.get('field')
|
||||
operator = condition.get('operator')
|
||||
value = condition.get('value')
|
||||
if not field or not operator or value is None:
|
||||
continue
|
||||
column = allowed_fields.get(field)
|
||||
if column is None:
|
||||
continue
|
||||
if operator == 'eq':
|
||||
filter_conditions.append(column == value)
|
||||
elif operator == 'ne':
|
||||
filter_conditions.append(column != value)
|
||||
elif operator == 'contains':
|
||||
filter_conditions.append(column.ilike(f'%{value}%'))
|
||||
elif operator == 'ge':
|
||||
try:
|
||||
num_val = float(value)
|
||||
filter_conditions.append(column >= num_val)
|
||||
except ValueError:
|
||||
continue
|
||||
elif operator == 'le':
|
||||
try:
|
||||
num_val = float(value)
|
||||
filter_conditions.append(column <= num_val)
|
||||
except ValueError:
|
||||
continue
|
||||
if filter_conditions:
|
||||
query = query.filter(and_(*filter_conditions))
|
||||
|
||||
# 6. 排序处理
|
||||
if order_by:
|
||||
sort_field_map = {
|
||||
'company_name': MaterialBase.company_name,
|
||||
'material_name': MaterialBase.name,
|
||||
'material_type': MaterialBase.material_type,
|
||||
'category': MaterialBase.category,
|
||||
'spec_model': MaterialBase.spec_model,
|
||||
'unit': MaterialBase.unit,
|
||||
'sku': StockBuy.sku,
|
||||
'barcode': StockBuy.barcode,
|
||||
'inbound_date': StockBuy.in_date,
|
||||
'serial_number': StockBuy.serial_number,
|
||||
'batch_number': StockBuy.batch_number,
|
||||
'status': StockBuy.status,
|
||||
'inspection_status': StockBuy.inspection_status,
|
||||
'qty_inbound': StockBuy.in_quantity,
|
||||
'qty_stock': StockBuy.stock_quantity,
|
||||
'qty_available': StockBuy.available_quantity,
|
||||
'warehouse_loc': StockBuy.warehouse_location,
|
||||
'unit_price': StockBuy.pre_tax_unit_price,
|
||||
'total_price': StockBuy.total_price,
|
||||
'tax_rate': StockBuy.tax_rate,
|
||||
'currency': StockBuy.currency,
|
||||
'exchange_rate': StockBuy.exchange_rate,
|
||||
'supplier_name': StockBuy.supplier_name,
|
||||
'purchaser': StockBuy.buyer_name,
|
||||
'purchaser_email': StockBuy.buyer_email,
|
||||
'source_link': StockBuy.original_link,
|
||||
'detail_link': StockBuy.detail_link,
|
||||
}
|
||||
column = sort_field_map.get(order_by)
|
||||
if column:
|
||||
if is_asc == 'asc':
|
||||
query = query.order_by(column.asc())
|
||||
elif is_asc == 'desc':
|
||||
query = query.order_by(column.desc())
|
||||
else:
|
||||
# 默认排序
|
||||
query = query.order_by(StockBuy.in_date.desc())
|
||||
|
||||
pagination = query.paginate(page=page, per_page=limit, error_out=False)
|
||||
items = []
|
||||
for item in pagination.items:
|
||||
items.append(item.to_dict()) # 直接使用 model 的 to_dict
|
||||
|
||||
Reference in New Issue
Block a user