修改采购件对于两个搜索框的bug修复
This commit is contained in:
@ -10,7 +10,7 @@ import json
|
||||
class BuyInboundService:
|
||||
|
||||
# ============================================================
|
||||
# 0. 辅助:唯一性校验 (保持不变)
|
||||
# 0. 辅助:唯一性校验
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def _check_unique(base_id, serial_number, batch_number, exclude_id=None):
|
||||
@ -34,34 +34,24 @@ class BuyInboundService:
|
||||
raise ValueError(f"该物料已存在批号【{batch_number}】,请勿重复录入,可直接在该批次下追加库存。")
|
||||
|
||||
# ============================================================
|
||||
# 1. 基础物料搜索 (修复:逻辑优先级 & 模糊匹配)
|
||||
# 1. 基础物料搜索
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def search_base_material(keyword, page=1, limit=50):
|
||||
try:
|
||||
# 1. 基础查询:只查询启用的
|
||||
query = MaterialBase.query.filter(MaterialBase.is_enabled == True)
|
||||
|
||||
if keyword:
|
||||
k = keyword.strip()
|
||||
k_str = f'%{k}%'
|
||||
|
||||
# [核心修复] 使用 and_ 确保逻辑优先级正确
|
||||
# 生成 SQL 类似: WHERE is_enabled = true AND (name LIKE %k% OR spec LIKE %k% ...)
|
||||
query = query.filter(and_(
|
||||
or_(
|
||||
MaterialBase.name.ilike(k_str), # ilike 忽略大小写
|
||||
MaterialBase.spec_model.ilike(k_str),
|
||||
MaterialBase.pinyin.ilike(k_str),
|
||||
# 如果需要支持 ID 搜索,取消下面注释
|
||||
# func.cast(MaterialBase.id, String).ilike(k_str)
|
||||
MaterialBase.name.ilike(k_str),
|
||||
MaterialBase.spec_model.ilike(k_str)
|
||||
)
|
||||
))
|
||||
|
||||
# 2. 排序:ID 倒序
|
||||
query = query.order_by(MaterialBase.id.desc())
|
||||
|
||||
# 3. 分页
|
||||
pagination = query.paginate(page=page, per_page=limit, error_out=False)
|
||||
|
||||
items = []
|
||||
@ -90,7 +80,7 @@ class BuyInboundService:
|
||||
return {"items": [], "total": 0, "page": 1, "has_next": False}
|
||||
|
||||
# ============================================================
|
||||
# 2. 新增入库逻辑 (保持不变)
|
||||
# 2. 新增入库逻辑
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def handle_inbound(data):
|
||||
@ -157,7 +147,7 @@ class BuyInboundService:
|
||||
raise e
|
||||
|
||||
# ============================================================
|
||||
# 3. 更新入库 (保持不变)
|
||||
# 3. 更新入库
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def update_inbound(stock_id, data):
|
||||
@ -197,7 +187,7 @@ class BuyInboundService:
|
||||
raise e
|
||||
|
||||
# ============================================================
|
||||
# 4. 删除 (保持不变)
|
||||
# 4. 删除
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def delete_inbound(stock_id):
|
||||
@ -212,21 +202,37 @@ class BuyInboundService:
|
||||
raise e
|
||||
|
||||
# ============================================================
|
||||
# 5. 获取列表 (保持不变)
|
||||
# 5. 获取列表
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def get_list(page, limit, keyword=None, statuses=None):
|
||||
def get_list(page, limit, keyword=None, statuses=None, category=None, material_type=None):
|
||||
try:
|
||||
query = db.session.query(StockBuy).outerjoin(MaterialBase, StockBuy.base_id == MaterialBase.id)
|
||||
|
||||
# 1. 通用关键词搜索
|
||||
if keyword:
|
||||
k_str = f'%{keyword.strip()}%'
|
||||
conditions = [StockBuy.sku.ilike(k_str), StockBuy.barcode.ilike(k_str),
|
||||
StockBuy.batch_number.ilike(k_str), StockBuy.serial_number.ilike(k_str),
|
||||
StockBuy.supplier_name.ilike(k_str), StockBuy.buyer_name.ilike(k_str),
|
||||
MaterialBase.name.ilike(k_str), MaterialBase.spec_model.ilike(k_str),
|
||||
MaterialBase.pinyin.ilike(k_str)]
|
||||
conditions = [
|
||||
StockBuy.sku.ilike(k_str),
|
||||
StockBuy.barcode.ilike(k_str),
|
||||
StockBuy.batch_number.ilike(k_str),
|
||||
StockBuy.serial_number.ilike(k_str),
|
||||
StockBuy.supplier_name.ilike(k_str),
|
||||
StockBuy.buyer_name.ilike(k_str),
|
||||
MaterialBase.name.ilike(k_str), # 名称
|
||||
MaterialBase.spec_model.ilike(k_str), # 规格
|
||||
]
|
||||
query = query.filter(or_(*conditions))
|
||||
|
||||
# 2. 类别独立搜索
|
||||
if category and category.strip():
|
||||
query = query.filter(MaterialBase.category == category.strip()) # 下拉框通常是精确匹配
|
||||
|
||||
# 3. 类型独立搜索
|
||||
if material_type and material_type.strip():
|
||||
query = query.filter(MaterialBase.material_type == material_type.strip()) # 精确匹配
|
||||
|
||||
# 4. 状态筛选
|
||||
if not statuses: statuses = ['在库', '借库']
|
||||
if '已出库' in statuses:
|
||||
query = query.filter(StockBuy.status.in_(statuses))
|
||||
@ -259,7 +265,31 @@ class BuyInboundService:
|
||||
traceback.print_exc()
|
||||
return {"total": 0, "items": []}
|
||||
|
||||
# 6-9 建议类接口保持不变 (略以节省篇幅,原样保留即可)
|
||||
# ============================================================
|
||||
# 6. [新增] 获取筛选选项(类别、类型)
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def get_filter_options():
|
||||
try:
|
||||
# 获取所有非空的类别
|
||||
categories = db.session.query(MaterialBase.category) \
|
||||
.filter(MaterialBase.category != None, MaterialBase.category != '') \
|
||||
.distinct().all()
|
||||
|
||||
# 获取所有非空的类型
|
||||
types = db.session.query(MaterialBase.material_type) \
|
||||
.filter(MaterialBase.material_type != None, MaterialBase.material_type != '') \
|
||||
.distinct().all()
|
||||
|
||||
return {
|
||||
"categories": [r[0] for r in categories],
|
||||
"types": [r[0] for r in types]
|
||||
}
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
return {"categories": [], "types": []}
|
||||
|
||||
# 7-10 建议类接口保持不变
|
||||
@staticmethod
|
||||
def get_history_suppliers(base_id):
|
||||
return [r[0] for r in db.session.query(StockBuy.supplier_name).filter(StockBuy.base_id == base_id,
|
||||
|
||||
Reference in New Issue
Block a user