feat: 采购/半成品/成品列表拆分SKU独立搜索框

This commit is contained in:
DXC
2026-03-09 17:29:24 +08:00
parent 646baa08fe
commit 5d813c24bc
9 changed files with 74 additions and 19 deletions

View File

@ -115,6 +115,7 @@ def get_list():
page = request.args.get('page', 1, type=int) page = request.args.get('page', 1, type=int)
limit = request.args.get('pageSize', 15, type=int) limit = request.args.get('pageSize', 15, type=int)
keyword = request.args.get('keyword', '') keyword = request.args.get('keyword', '')
sku = request.args.get('sku', '')
# 新增筛选参数 # 新增筛选参数
category = request.args.get('category', '') category = request.args.get('category', '')
@ -137,7 +138,7 @@ def get_list():
statuses_str = request.args.get('statuses', '') statuses_str = request.args.get('statuses', '')
statuses = statuses_str.split(',') if statuses_str else [] 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, sku, statuses, category, material_type, company,
order_by, is_asc, advanced_filters) order_by, is_asc, advanced_filters)
# 字段级脱敏 # 字段级脱敏
user_permissions = get_current_user_permissions() user_permissions = get_current_user_permissions()

View File

@ -73,6 +73,7 @@ def get_list():
page = request.args.get('page', 1, type=int) page = request.args.get('page', 1, type=int)
limit = request.args.get('pageSize', 15, type=int) limit = request.args.get('pageSize', 15, type=int)
keyword = request.args.get('keyword', '') keyword = request.args.get('keyword', '')
sku = request.args.get('sku', '')
statuses_str = request.args.get('statuses', '') statuses_str = request.args.get('statuses', '')
statuses = statuses_str.split(',') if statuses_str else [] statuses = statuses_str.split(',') if statuses_str else []
category = request.args.get('category', '') category = request.args.get('category', '')
@ -104,7 +105,7 @@ def get_list():
# 调用服务,传入所有参数 # 调用服务,传入所有参数
result = ProductInboundService.get_list( result = ProductInboundService.get_list(
page, limit, keyword, statuses, page, limit, keyword, sku, statuses,
category=extra_filters.get('category'), category=extra_filters.get('category'),
material_type=extra_filters.get('material_type'), material_type=extra_filters.get('material_type'),
company=extra_filters.get('company'), company=extra_filters.get('company'),

View File

@ -73,6 +73,7 @@ def get_list():
page = request.args.get('page', 1, type=int) page = request.args.get('page', 1, type=int)
limit = request.args.get('pageSize', 15, type=int) limit = request.args.get('pageSize', 15, type=int)
keyword = request.args.get('keyword', '') keyword = request.args.get('keyword', '')
sku = request.args.get('sku', '')
statuses_str = request.args.get('statuses', '') statuses_str = request.args.get('statuses', '')
statuses = statuses_str.split(',') if statuses_str else [] statuses = statuses_str.split(',') if statuses_str else []
company = request.args.get('company', '') company = request.args.get('company', '')
@ -104,7 +105,7 @@ def get_list():
# 调用服务,传入所有参数 # 调用服务,传入所有参数
result = SemiInboundService.get_list( result = SemiInboundService.get_list(
page, limit, keyword, statuses, page, limit, keyword, sku, statuses,
**extra_filters **extra_filters
) )
user_permissions = get_current_user_permissions() user_permissions = get_current_user_permissions()

View File

@ -240,17 +240,16 @@ class BuyInboundService:
# 5. 获取列表 (支持排序和高级筛选) # 5. 获取列表 (支持排序和高级筛选)
# ============================================================ # ============================================================
@staticmethod @staticmethod
def get_list(page, limit, keyword=None, statuses=None, category=None, material_type=None, company=None, def get_list(page, limit, keyword=None, sku=None, statuses=None, category=None, material_type=None, company=None,
order_by='', is_asc='', advanced_filters=None): order_by='', is_asc='', advanced_filters=None):
try: try:
from sqlalchemy import and_, or_ from sqlalchemy import and_, or_
query = db.session.query(StockBuy).outerjoin(MaterialBase, StockBuy.base_id == MaterialBase.id) query = db.session.query(StockBuy).outerjoin(MaterialBase, StockBuy.base_id == MaterialBase.id)
# 1. 通用关键词搜索 # 1. 通用关键词搜索(名称、规格、公司)
if keyword: if keyword:
k_str = f'%{keyword.strip()}%' k_str = f'%{keyword.strip()}%'
conditions = [ conditions = [
StockBuy.sku.ilike(k_str),
StockBuy.barcode.ilike(k_str), StockBuy.barcode.ilike(k_str),
StockBuy.batch_number.ilike(k_str), StockBuy.batch_number.ilike(k_str),
StockBuy.serial_number.ilike(k_str), StockBuy.serial_number.ilike(k_str),
@ -262,6 +261,11 @@ class BuyInboundService:
] ]
query = query.filter(or_(*conditions)) query = query.filter(or_(*conditions))
# 1.1 SKU 独立搜索
if sku and sku.strip():
sku_str = f'%{sku.strip()}%'
query = query.filter(StockBuy.sku.ilike(sku_str))
# 2. 类别独立搜索 # 2. 类别独立搜索
if category and category.strip(): if category and category.strip():
query = query.filter(MaterialBase.category == category.strip()) query = query.filter(MaterialBase.category == category.strip())

View File

@ -270,11 +270,12 @@ class ProductInboundService:
return [] return []
@staticmethod @staticmethod
def get_list(page, limit, keyword=None, statuses=None, category=None, material_type=None, company=None, def get_list(page, limit, keyword=None, sku=None, statuses=None, category=None, material_type=None, company=None,
order_by_column=None, is_asc=None, advanced_filters=None): order_by_column=None, is_asc=None, advanced_filters=None):
from app.models.inbound.product import StockProduct from app.models.inbound.product import StockProduct
try: try:
query = db.session.query(StockProduct).outerjoin(MaterialBase, StockProduct.base_id == MaterialBase.id) query = db.session.query(StockProduct).outerjoin(MaterialBase, StockProduct.base_id == MaterialBase.id)
# 1. 通用关键词搜索(名称、规格、公司)
if keyword: if keyword:
kw = f'%{keyword}%' kw = f'%{keyword}%'
query = query.filter(or_( query = query.filter(or_(
@ -283,9 +284,12 @@ class ProductInboundService:
MaterialBase.company_name.ilike(kw), MaterialBase.company_name.ilike(kw),
StockProduct.serial_number.ilike(kw), StockProduct.serial_number.ilike(kw),
StockProduct.work_order_code.ilike(kw), StockProduct.work_order_code.ilike(kw),
StockProduct.order_id.ilike(kw), StockProduct.order_id.ilike(kw)
StockProduct.sku.ilike(kw)
)) ))
# 1.1 SKU 独立搜索
if sku and sku.strip():
sku_str = f'%{sku.strip()}%'
query = query.filter(StockProduct.sku.ilike(sku_str))
if category and category.strip(): if category and category.strip():
query = query.filter(MaterialBase.category == category.strip()) query = query.filter(MaterialBase.category == category.strip())
if material_type and material_type.strip(): if material_type and material_type.strip():

View File

@ -359,11 +359,12 @@ class SemiInboundService:
return [] return []
@staticmethod @staticmethod
def get_list(page, limit, keyword=None, statuses=None, category=None, material_type=None, company=None, def get_list(page, limit, keyword=None, sku=None, statuses=None, category=None, material_type=None, company=None,
order_by_column=None, is_asc=None, advanced_filters=None): order_by_column=None, is_asc=None, advanced_filters=None):
from app.models.inbound.semi import StockSemi from app.models.inbound.semi import StockSemi
try: try:
query = db.session.query(StockSemi).outerjoin(MaterialBase, StockSemi.base_id == MaterialBase.id) query = db.session.query(StockSemi).outerjoin(MaterialBase, StockSemi.base_id == MaterialBase.id)
# 1. 通用关键词搜索(名称、规格、公司)
if keyword: if keyword:
kw = f'%{keyword}%' kw = f'%{keyword}%'
query = query.filter( query = query.filter(
@ -373,11 +374,14 @@ class SemiInboundService:
MaterialBase.company_name.ilike(kw), MaterialBase.company_name.ilike(kw),
StockSemi.batch_number.ilike(kw), StockSemi.batch_number.ilike(kw),
StockSemi.serial_number.ilike(kw), StockSemi.serial_number.ilike(kw),
StockSemi.sku.ilike(kw),
StockSemi.work_order_code.ilike(kw), StockSemi.work_order_code.ilike(kw),
StockSemi.bom_code.ilike(kw) StockSemi.bom_code.ilike(kw)
) )
) )
# 1.1 SKU 独立搜索
if sku and sku.strip():
sku_str = f'%{sku.strip()}%'
query = query.filter(StockSemi.sku.ilike(sku_str))
if category and category.strip(): if category and category.strip():
query = query.filter(MaterialBase.category == category.strip()) query = query.filter(MaterialBase.category == category.strip())
if material_type and material_type.strip(): if material_type and material_type.strip():

View File

@ -17,12 +17,24 @@
<el-input <el-input
v-model="queryParams.keyword" v-model="queryParams.keyword"
placeholder="请输入名称、规格或SKU搜索..." placeholder="请输入名称、规格搜索..."
class="filter-item-input" class="filter-item-input"
clearable clearable
@clear="fetchData" @clear="fetchData"
@keyup.enter="fetchData" @keyup.enter="fetchData"
style="width: 240px;" style="width: 200px;"
>
<template #prefix><el-icon><Search /></el-icon></template>
</el-input>
<el-input
v-model="queryParams.sku"
placeholder="请输入SKU搜索..."
class="filter-item-input"
clearable
@clear="fetchData"
@keyup.enter="fetchData"
style="width: 160px;"
> >
<template #prefix><el-icon><Search /></el-icon></template> <template #prefix><el-icon><Search /></el-icon></template>
</el-input> </el-input>
@ -745,6 +757,7 @@ const queryParams = reactive({
page: 1, page: 1,
pageSize: 100, pageSize: 100,
keyword: '', keyword: '',
sku: '',
category: '', category: '',
material_type: '', material_type: '',
company: '', company: '',
@ -1240,6 +1253,7 @@ const loadWarehouseTree = async () => {
const resetQuery = () => { const resetQuery = () => {
queryParams.keyword = '' queryParams.keyword = ''
queryParams.sku = ''
queryParams.category = '' queryParams.category = ''
queryParams.material_type = '' queryParams.material_type = ''
queryParams.company = '' queryParams.company = ''

View File

@ -16,12 +16,24 @@
<el-input <el-input
v-model="queryParams.keyword" v-model="queryParams.keyword"
placeholder="请输入名称、规格或SKU搜索..." placeholder="请输入名称、规格搜索..."
class="filter-item-input" class="filter-item-input"
clearable clearable
@clear="fetchData" @clear="fetchData"
@keyup.enter="fetchData" @keyup.enter="fetchData"
style="width: 240px;" style="width: 200px;"
>
<template #prefix><el-icon><Search /></el-icon></template>
</el-input>
<el-input
v-model="queryParams.sku"
placeholder="请输入SKU搜索..."
class="filter-item-input"
clearable
@clear="fetchData"
@keyup.enter="fetchData"
style="width: 160px;"
> >
<template #prefix><el-icon><Search /></el-icon></template> <template #prefix><el-icon><Search /></el-icon></template>
</el-input> </el-input>
@ -555,7 +567,7 @@ const dialogStatus = ref<'create' | 'update'>('create')
const tableData = ref([]) const tableData = ref([])
const total = ref(0) const total = ref(0)
const formRef = ref() const formRef = ref()
const queryParams = reactive({ page: 1, pageSize: 100, keyword: '', category: '', material_type: '', statuses: ['在库', '借库'], company: '', orderByColumn: '', isAsc: '', advancedFilters: [] }) const queryParams = reactive({ page: 1, pageSize: 100, keyword: '', sku: '', category: '', material_type: '', statuses: ['在库', '借库'], company: '', orderByColumn: '', isAsc: '', advancedFilters: [] })
const categoryOptions = ref<string[]>([]) const categoryOptions = ref<string[]>([])
const typeOptions = ref<string[]>([]) const typeOptions = ref<string[]>([])
const companyOptions = ref<string[]>([]) // [新增] const companyOptions = ref<string[]>([]) // [新增]
@ -982,6 +994,7 @@ const loadWarehouseTree = async () => {
const resetQuery = () => { const resetQuery = () => {
queryParams.keyword = '' queryParams.keyword = ''
queryParams.sku = ''
queryParams.category = '' queryParams.category = ''
queryParams.material_type = '' queryParams.material_type = ''
queryParams.company = '' queryParams.company = ''

View File

@ -17,12 +17,24 @@
<el-input <el-input
v-model="queryParams.keyword" v-model="queryParams.keyword"
placeholder="请输入名称、规格或SKU搜索..." placeholder="请输入名称、规格搜索..."
class="filter-item-input" class="filter-item-input"
clearable clearable
@clear="fetchData" @clear="fetchData"
@keyup.enter="fetchData" @keyup.enter="fetchData"
style="width: 240px;" style="width: 200px;"
>
<template #prefix><el-icon><Search /></el-icon></template>
</el-input>
<el-input
v-model="queryParams.sku"
placeholder="请输入SKU搜索..."
class="filter-item-input"
clearable
@clear="fetchData"
@keyup.enter="fetchData"
style="width: 160px;"
> >
<template #prefix><el-icon><Search /></el-icon></template> <template #prefix><el-icon><Search /></el-icon></template>
</el-input> </el-input>
@ -621,7 +633,7 @@ const dialogStatus = ref<'create' | 'update'>('create')
const tableData = ref([]) const tableData = ref([])
const total = ref(0) const total = ref(0)
const formRef = ref() const formRef = ref()
const queryParams = reactive({ page: 1, pageSize: 100, keyword: '', category: '', material_type: '', statuses: ['在库', '借库'], company: '', orderByColumn: '', isAsc: '', advancedFilters: [] }) const queryParams = reactive({ page: 1, pageSize: 100, keyword: '', sku: '', category: '', material_type: '', statuses: ['在库', '借库'], company: '', orderByColumn: '', isAsc: '', advancedFilters: [] })
const categoryOptions = ref<string[]>([]) const categoryOptions = ref<string[]>([])
const typeOptions = ref<string[]>([]) const typeOptions = ref<string[]>([])
const companyOptions = ref<string[]>([]) // [新增] const companyOptions = ref<string[]>([]) // [新增]
@ -1116,6 +1128,7 @@ const loadWarehouseTree = async () => {
const resetQuery = () => { const resetQuery = () => {
queryParams.keyword = '' queryParams.keyword = ''
queryParams.sku = ''
queryParams.category = '' queryParams.category = ''
queryParams.material_type = '' queryParams.material_type = ''
queryParams.company = '' queryParams.company = ''