\"fix: let frontend dictate warning sort flag and add SQL numeric casting\"
This commit is contained in:
@ -6,7 +6,7 @@ from app.models.inbound.buy import StockBuy
|
|||||||
from app.models.inbound.semi import StockSemi
|
from app.models.inbound.semi import StockSemi
|
||||||
from app.models.inbound.product import StockProduct
|
from app.models.inbound.product import StockProduct
|
||||||
# from app.models.inbound.service import StockService
|
# from app.models.inbound.service import StockService
|
||||||
from sqlalchemy import or_, and_, func, case, desc, asc
|
from sqlalchemy import or_, and_, func, case, desc, asc, cast, Numeric, text
|
||||||
import traceback
|
import traceback
|
||||||
import json
|
import json
|
||||||
import io
|
import io
|
||||||
@ -309,36 +309,27 @@ class MaterialBaseService:
|
|||||||
order_by_column = filters.get('orderByColumn', '')
|
order_by_column = filters.get('orderByColumn', '')
|
||||||
is_asc = filters.get('isAsc', None)
|
is_asc = filters.get('isAsc', None)
|
||||||
|
|
||||||
# 检查是否启用了预警智能排序
|
# 信任前端传递的预警排序开关(前端已基于权限注入)
|
||||||
enable_warning_sort = has_warning_permission and filters.get('enableWarningSort', False)
|
enable_warning_sort = filters.get('enableWarningSort', False)
|
||||||
|
|
||||||
if enable_warning_sort:
|
if enable_warning_sort:
|
||||||
from sqlalchemy import text
|
print("====== [DEBUG] 成功进入预警强排逻辑 ======")
|
||||||
|
# 强制统一数据类型
|
||||||
print("====== [DEBUG] 执行虚拟列强排模式 ======")
|
red_val = cast(MaterialWarningSetting.red_threshold, Numeric)
|
||||||
|
yellow_val = cast(MaterialWarningSetting.yellow_threshold, Numeric)
|
||||||
# 1. 建立虚拟列标签 (显式暴露出计算结果)
|
inv_val = cast(total_inv, Numeric)
|
||||||
|
|
||||||
warning_level = case([
|
warning_level = case([
|
||||||
(and_(MaterialWarningSetting.is_enabled.is_(True), total_inv <= MaterialWarningSetting.red_threshold), 2),
|
(and_(MaterialWarningSetting.is_enabled.is_(True), inv_val <= red_val), 2),
|
||||||
(and_(MaterialWarningSetting.is_enabled.is_(True), total_inv <= MaterialWarningSetting.yellow_threshold), 1)
|
(and_(MaterialWarningSetting.is_enabled.is_(True), inv_val <= yellow_val), 1)
|
||||||
], else_=0).label('sort_level')
|
], else_=0).label('sort_level')
|
||||||
|
|
||||||
# 红色组内部:缺口越大越靠前 DESC
|
|
||||||
red_shortage = case([
|
red_shortage = case([
|
||||||
(and_(MaterialWarningSetting.is_enabled.is_(True), total_inv <= MaterialWarningSetting.red_threshold),
|
(and_(MaterialWarningSetting.is_enabled.is_(True), inv_val <= red_val), red_val - inv_val)
|
||||||
MaterialWarningSetting.red_threshold - total_inv)
|
|
||||||
], else_=0).label('sort_red')
|
], else_=0).label('sort_red')
|
||||||
|
|
||||||
# 黄色组内部:距离红线越近越靠前 ASC
|
|
||||||
yellow_distance = case([
|
yellow_distance = case([
|
||||||
(and_(MaterialWarningSetting.is_enabled.is_(True), total_inv > MaterialWarningSetting.red_threshold, total_inv <= MaterialWarningSetting.yellow_threshold),
|
(and_(MaterialWarningSetting.is_enabled.is_(True), inv_val > red_val, inv_val <= yellow_val), inv_val - red_val)
|
||||||
total_inv - MaterialWarningSetting.red_threshold)
|
|
||||||
], else_=999999).label('sort_yellow')
|
], else_=999999).label('sort_yellow')
|
||||||
|
|
||||||
# 2. 将虚拟列加入查询 (使其成为真实可引用的字段)
|
|
||||||
query = query.add_columns(warning_level, red_shortage, yellow_distance)
|
query = query.add_columns(warning_level, red_shortage, yellow_distance)
|
||||||
|
|
||||||
# 3. 清除任何杂乱排序,使用原生 text 强行指引数据库按虚拟列名排序
|
|
||||||
query = query.order_by(None).order_by(
|
query = query.order_by(None).order_by(
|
||||||
text("sort_level DESC"),
|
text("sort_level DESC"),
|
||||||
text("sort_red DESC"),
|
text("sort_red DESC"),
|
||||||
|
|||||||
@ -580,6 +580,7 @@ interface QueryParams {
|
|||||||
isAsc: string | undefined;
|
isAsc: string | undefined;
|
||||||
advancedFilters?: any[];
|
advancedFilters?: any[];
|
||||||
has_stock?: string;
|
has_stock?: string;
|
||||||
|
enableWarningSort?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CascaderOption {
|
interface CascaderOption {
|
||||||
@ -880,6 +881,8 @@ const querySearchType = (queryString: string, cb: any) => {
|
|||||||
|
|
||||||
const getList = () => {
|
const getList = () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
// 强制注入预警排序开关(基于权限)
|
||||||
|
queryParams.enableWarningSort = userStore.hasPermission('material_list:view_warning');
|
||||||
// Stringify advancedFilters to JSON string as backend expects
|
// Stringify advancedFilters to JSON string as backend expects
|
||||||
const params = {
|
const params = {
|
||||||
...queryParams,
|
...queryParams,
|
||||||
|
|||||||
Reference in New Issue
Block a user