feat: expand search fields and remove result limits in buy inbound service

This commit is contained in:
dxc
2026-02-11 11:28:02 +08:00
committed by dxc (aider)
parent 706476d421
commit b1e2836e4b

View File

@ -41,21 +41,36 @@ class BuyInboundService:
raise ValueError(f"该物料已存在批号【{batch_number}】,请勿重复录入,可直接在该批次下追加库存。") raise ValueError(f"该物料已存在批号【{batch_number}】,请勿重复录入,可直接在该批次下追加库存。")
# ============================================================ # ============================================================
# 1. 基础物料搜索 # 1. 基础物料搜索 (参照 Base 模块:全量模糊匹配)
# ============================================================ # ============================================================
@staticmethod @staticmethod
def search_base_material(keyword): def search_base_material(keyword):
try: try:
query = MaterialBase.query.filter(MaterialBase.is_enabled == True) query = MaterialBase.query.filter(MaterialBase.is_enabled == True)
if keyword: if keyword:
query = query.filter( # [参照 Base 逻辑] 简单直接的模糊匹配LIKE %keyword%
or_( k_str = f'%{keyword.strip()}%'
MaterialBase.name.ilike(f'%{keyword}%'),
MaterialBase.spec_model.ilike(f'%{keyword}%'), conditions = [
MaterialBase.pinyin.ilike(f'%{keyword}%') MaterialBase.name.ilike(k_str), # 名称
) MaterialBase.spec_model.ilike(k_str), # 规格
) MaterialBase.pinyin.ilike(k_str), # 拼音
query = query.order_by(MaterialBase.id.desc()).limit(20) MaterialBase.category.ilike(k_str), # 类别
MaterialBase.material_type.ilike(k_str) # 类型
]
# 安全地添加可能存在的扩展字段 (品牌/厂家)
if hasattr(MaterialBase, 'brand'):
conditions.append(MaterialBase.brand.ilike(k_str))
if hasattr(MaterialBase, 'manufacturer'):
conditions.append(MaterialBase.manufacturer.ilike(k_str))
query = query.filter(or_(*conditions))
# [参照 Base 逻辑] 移除 limit返回所有结果
query = query.order_by(MaterialBase.id.desc())
results = [] results = []
for item in query.all(): for item in query.all():
results.append({ results.append({
@ -65,6 +80,10 @@ class BuyInboundService:
'category': item.category, 'category': item.category,
'unit': item.unit, 'unit': item.unit,
'type': item.material_type, 'type': item.material_type,
# 使用 getattr 防止字段不存在报错
'brand': getattr(item, 'brand', ''),
'manufacturer': getattr(item, 'manufacturer', ''),
'pinyin': getattr(item, 'pinyin', ''),
'status': '启用' 'status': '启用'
}) })
return results return results
@ -242,7 +261,7 @@ class BuyInboundService:
raise e raise e
# ============================================================ # ============================================================
# 5. 获取列表 # 5. 获取列表 (参照 Base 逻辑:全量模糊匹配)
# ============================================================ # ============================================================
@staticmethod @staticmethod
def get_list(page, limit, keyword=None, statuses=None): def get_list(page, limit, keyword=None, statuses=None):
@ -250,17 +269,30 @@ class BuyInboundService:
query = db.session.query(StockBuy).outerjoin(MaterialBase, StockBuy.base_id == MaterialBase.id) query = db.session.query(StockBuy).outerjoin(MaterialBase, StockBuy.base_id == MaterialBase.id)
if keyword: if keyword:
kw = f'%{keyword}%' # [简单匹配] 只要任一字段包含该字符串,即匹配
query = query.filter( k_str = f'%{keyword.strip()}%'
or_(
MaterialBase.name.ilike(kw), conditions = [
MaterialBase.spec_model.ilike(kw), # 库存业务字段
StockBuy.batch_number.ilike(kw), StockBuy.sku.ilike(k_str),
StockBuy.serial_number.ilike(kw), StockBuy.barcode.ilike(k_str),
StockBuy.sku.ilike(kw), StockBuy.batch_number.ilike(k_str),
StockBuy.supplier_name.ilike(kw) 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),
MaterialBase.category.ilike(k_str)
]
if hasattr(MaterialBase, 'brand'):
conditions.append(MaterialBase.brand.ilike(k_str))
if hasattr(MaterialBase, 'manufacturer'):
conditions.append(MaterialBase.manufacturer.ilike(k_str))
query = query.filter(or_(*conditions))
if not statuses: if not statuses:
statuses = ['在库', '借库'] statuses = ['在库', '借库']
@ -300,6 +332,9 @@ class BuyInboundService:
'category': item.base.category if item.base else '', 'category': item.base.category if item.base else '',
'unit': item.base.unit if item.base else '', 'unit': item.base.unit if item.base else '',
'material_type': item.base.material_type if item.base else '', 'material_type': item.base.material_type if item.base else '',
'brand': getattr(item.base, 'brand', '') if item.base else '',
'manufacturer': getattr(item.base, 'manufacturer', '') if item.base else '',
'pinyin': getattr(item.base, 'pinyin', '') if item.base else '',
'sku': item.sku, 'sku': item.sku,
'inbound_date': date_display, 'inbound_date': date_display,
@ -333,33 +368,28 @@ class BuyInboundService:
return {"total": 0, "items": []} return {"total": 0, "items": []}
# ============================================================ # ============================================================
# 6. 供应商历史查询 (基于 base_id) # 6. 供应商历史查询 (移除限制)
# ============================================================ # ============================================================
@staticmethod @staticmethod
def get_history_suppliers(base_id): def get_history_suppliers(base_id):
"""返回该物料关联的供应商列表(去重)"""
try: try:
query = db.session.query(StockBuy.supplier_name).filter( query = db.session.query(StockBuy.supplier_name).filter(
StockBuy.base_id == base_id, StockBuy.base_id == base_id,
StockBuy.supplier_name.isnot(None), StockBuy.supplier_name.isnot(None),
StockBuy.supplier_name != '' StockBuy.supplier_name != ''
).distinct().order_by(StockBuy.supplier_name) ).distinct().order_by(StockBuy.supplier_name)
# [修改] 移除 limit
suppliers = [row[0] for row in query.all()] suppliers = [row[0] for row in query.all()]
return suppliers return suppliers
except Exception: except Exception:
return [] return []
# ============================================================ # ============================================================
# 7. 采购人建议 (全局,基于 stock_buy 表) # 7. 采购人建议 (移除限制)
# ============================================================ # ============================================================
@staticmethod @staticmethod
def get_history_purchasers(keyword): def get_history_purchasers(keyword):
"""
从 stock_buy 表中提取历史采购人和邮箱。
不绑定 base_id因为采购人通常是全局的。
"""
try: try:
# 查询 buyer_name 和 buyer_email并去重
query = db.session.query(StockBuy.buyer_name, StockBuy.buyer_email) \ query = db.session.query(StockBuy.buyer_name, StockBuy.buyer_email) \
.filter(StockBuy.buyer_name.isnot(None), StockBuy.buyer_name != '') .filter(StockBuy.buyer_name.isnot(None), StockBuy.buyer_name != '')
@ -370,13 +400,13 @@ class BuyInboundService:
StockBuy.buyer_email.ilike(kw) StockBuy.buyer_email.ilike(kw)
)) ))
# 按名字去重,取最新的记录(这里简单做 distinct # [修改] 移除 limit
results = query.distinct().limit(20).all() results = query.distinct().all()
users = [] users = []
for row in results: for row in results:
users.append({ users.append({
'value': row.buyer_name, # 前端 autocomplete 显示的值 'value': row.buyer_name,
'email': row.buyer_email or '' 'email': row.buyer_email or ''
}) })
return users return users
@ -385,38 +415,35 @@ class BuyInboundService:
return [] return []
# ============================================================ # ============================================================
# 8. 链接建议 (基于 base_id) # 8. 链接建议 (移除限制)
# ============================================================ # ============================================================
@staticmethod @staticmethod
def get_history_links(base_id, link_type='original'): def get_history_links(base_id, link_type='original'):
"""查询该物料的历史链接,方便复用"""
try: try:
target_col = StockBuy.original_link if link_type == 'original' else StockBuy.detail_link target_col = StockBuy.original_link if link_type == 'original' else StockBuy.detail_link
query = db.session.query(target_col).filter( query = db.session.query(target_col).filter(
StockBuy.base_id == base_id, StockBuy.base_id == base_id,
target_col.isnot(None), target_col.isnot(None),
target_col != '' target_col != ''
).distinct().limit(10) ).distinct()
# [修改] 移除 limit
links = [row[0] for row in query.all()] links = [row[0] for row in query.all()]
return links return links
except Exception: except Exception:
return [] return []
# ============================================================ # ============================================================
# 9. [新增] 库位建议 (基于 base_id) # 9. 库位建议 (移除限制)
# ============================================================ # ============================================================
@staticmethod @staticmethod
def get_history_locations(base_id): def get_history_locations(base_id):
"""查询该物料的历史存放库位,方便复用"""
try: try:
query = db.session.query(StockBuy.warehouse_location).filter( query = db.session.query(StockBuy.warehouse_location).filter(
StockBuy.base_id == base_id, StockBuy.base_id == base_id,
StockBuy.warehouse_location.isnot(None), StockBuy.warehouse_location.isnot(None),
StockBuy.warehouse_location != '' StockBuy.warehouse_location != ''
).distinct().limit(10) ).distinct()
# [修改] 移除 limit
# 简单去重列表
locs = [row[0] for row in query.all()] locs = [row[0] for row in query.all()]
return locs return locs
except Exception: except Exception: