feat: add advanced filtering and full-field sorting to material list
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
This commit is contained in:
@ -5,6 +5,7 @@ from app.services.inbound.base_service import MaterialBaseService
|
|||||||
from app.utils.decorators import login_required, permission_required
|
from app.utils.decorators import login_required, permission_required
|
||||||
import traceback
|
import traceback
|
||||||
import datetime
|
import datetime
|
||||||
|
import json
|
||||||
|
|
||||||
inbound_base_bp = Blueprint('stock_base', __name__)
|
inbound_base_bp = Blueprint('stock_base', __name__)
|
||||||
|
|
||||||
@ -105,6 +106,13 @@ def get_list():
|
|||||||
page = request.args.get('pageNum', 1, type=int)
|
page = request.args.get('pageNum', 1, type=int)
|
||||||
limit = request.args.get('pageSize', 10, type=int)
|
limit = request.args.get('pageSize', 10, type=int)
|
||||||
|
|
||||||
|
# 解析高级筛选条件
|
||||||
|
advanced_filters_raw = request.args.get('advancedFilters', '[]')
|
||||||
|
try:
|
||||||
|
advanced_filters_list = json.loads(advanced_filters_raw)
|
||||||
|
except:
|
||||||
|
advanced_filters_list = []
|
||||||
|
|
||||||
# 构造筛选条件
|
# 构造筛选条件
|
||||||
filters = {
|
filters = {
|
||||||
'keyword': request.args.get('keyword', ''),
|
'keyword': request.args.get('keyword', ''),
|
||||||
@ -113,7 +121,8 @@ def get_list():
|
|||||||
'type': request.args.get('type', ''),
|
'type': request.args.get('type', ''),
|
||||||
'isEnabled': request.args.get('isEnabled', None),
|
'isEnabled': request.args.get('isEnabled', None),
|
||||||
'orderByColumn': request.args.get('orderByColumn', ''),
|
'orderByColumn': request.args.get('orderByColumn', ''),
|
||||||
'isAsc': request.args.get('isAsc', None)
|
'isAsc': request.args.get('isAsc', None),
|
||||||
|
'advancedFilters': advanced_filters_list
|
||||||
}
|
}
|
||||||
|
|
||||||
result = MaterialBaseService.get_list(page, limit, filters)
|
result = MaterialBaseService.get_list(page, limit, filters)
|
||||||
|
|||||||
@ -112,7 +112,7 @@ class MaterialBaseService:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_list(page, limit, filters=None):
|
def get_list(page, limit, filters=None):
|
||||||
"""
|
"""
|
||||||
获取基础信息列表 (带分页和筛选)
|
获取基础信息列表 (带分页、高级筛选和全字段排序)
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 构建聚合子查询
|
# 构建聚合子查询
|
||||||
@ -178,19 +178,80 @@ class MaterialBaseService:
|
|||||||
is_active = bool(int(filters['isEnabled']))
|
is_active = bool(int(filters['isEnabled']))
|
||||||
query = query.filter_by(is_enabled=is_active)
|
query = query.filter_by(is_enabled=is_active)
|
||||||
|
|
||||||
# 排序处理
|
# 3. 高级动态筛选
|
||||||
|
advanced_filters = filters.get('advancedFilters', [])
|
||||||
|
if advanced_filters:
|
||||||
|
allowed_fields = {
|
||||||
|
'companyName': 'company_name',
|
||||||
|
'name': 'name',
|
||||||
|
'commonName': 'common_name',
|
||||||
|
'category': 'category',
|
||||||
|
'type': 'material_type',
|
||||||
|
'spec': 'spec_model',
|
||||||
|
'unit': 'unit',
|
||||||
|
'inventoryCount': total_inv,
|
||||||
|
'availableCount': total_avail
|
||||||
|
}
|
||||||
|
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
|
||||||
|
db_field = allowed_fields.get(field)
|
||||||
|
if not db_field:
|
||||||
|
continue
|
||||||
|
# 对于聚合字段 (inventoryCount, availableCount),需要使用子查询别名
|
||||||
|
if isinstance(db_field, type(total_inv)):
|
||||||
|
column = db_field
|
||||||
|
else:
|
||||||
|
column = getattr(MaterialBase, db_field, None)
|
||||||
|
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))
|
||||||
|
|
||||||
|
# 排序处理(支持全字段)
|
||||||
order_by_column = filters.get('orderByColumn', '')
|
order_by_column = filters.get('orderByColumn', '')
|
||||||
is_asc = filters.get('isAsc', None)
|
is_asc = filters.get('isAsc', None)
|
||||||
if order_by_column == 'inventoryCount':
|
if order_by_column:
|
||||||
|
# 字段映射
|
||||||
|
sort_field_map = {
|
||||||
|
'companyName': MaterialBase.company_name,
|
||||||
|
'name': MaterialBase.name,
|
||||||
|
'commonName': MaterialBase.common_name,
|
||||||
|
'category': MaterialBase.category,
|
||||||
|
'type': MaterialBase.material_type,
|
||||||
|
'spec': MaterialBase.spec_model,
|
||||||
|
'unit': MaterialBase.unit,
|
||||||
|
'inventoryCount': total_inv,
|
||||||
|
'availableCount': total_avail
|
||||||
|
}
|
||||||
|
sort_column = sort_field_map.get(order_by_column)
|
||||||
|
if sort_column is not None:
|
||||||
if is_asc == 'asc':
|
if is_asc == 'asc':
|
||||||
query = query.order_by(total_inv.asc())
|
query = query.order_by(sort_column.asc())
|
||||||
else:
|
elif is_asc == 'desc':
|
||||||
query = query.order_by(total_inv.desc())
|
query = query.order_by(sort_column.desc())
|
||||||
elif order_by_column == 'availableCount':
|
|
||||||
if is_asc == 'asc':
|
|
||||||
query = query.order_by(total_avail.asc())
|
|
||||||
else:
|
|
||||||
query = query.order_by(total_avail.desc())
|
|
||||||
else:
|
else:
|
||||||
# 默认排序:优先按总库存数降序,当库存相同时,再按规格型号升序
|
# 默认排序:优先按总库存数降序,当库存相同时,再按规格型号升序
|
||||||
query = query.order_by(total_inv.desc(), MaterialBase.spec_model.asc())
|
query = query.order_by(total_inv.desc(), MaterialBase.spec_model.asc())
|
||||||
|
|||||||
Reference in New Issue
Block a user