feat: 新增首页全局搜索功能,支持跨模块多词搜索
This commit is contained in:
@ -18,6 +18,32 @@
|
||||
|
||||
<div class="card-body">
|
||||
<h2>IRIS 库存管理系统</h2>
|
||||
|
||||
<div style="display: flex; justify-content: center; margin: 20px 0 30px;">
|
||||
<el-autocomplete
|
||||
v-model="globalSearchText"
|
||||
:fetch-suggestions="queryGlobalSearch"
|
||||
placeholder="全局搜索:输入物料名称、规格、条码或 BOM 编号..."
|
||||
style="width: 60%; max-width: 600px;"
|
||||
size="large"
|
||||
clearable
|
||||
@select="handleSearchSelect"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><Search /></el-icon>
|
||||
</template>
|
||||
<template #default="{ item }">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; line-height: 1.5; padding: 4px 0;">
|
||||
<div>
|
||||
<div style="font-size: 14px; font-weight: bold; color: #303133;">{{ item.title }}</div>
|
||||
<div style="font-size: 12px; color: #909399;">{{ item.subtitle }}</div>
|
||||
</div>
|
||||
<el-tag size="small" :type="getBadgeType(item.type)">{{ item.badge }}</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-autocomplete>
|
||||
</div>
|
||||
|
||||
<p class="subtitle">请选择您要进行的业务操作:</p>
|
||||
|
||||
<div class="action-buttons">
|
||||
@ -215,8 +241,9 @@ import { useRouter } from 'vue-router'
|
||||
// 1. 引入 User Store
|
||||
import { useUserStore } from '@/stores/user'
|
||||
// 引入需要的图标
|
||||
import { Box, TrendCharts, ShoppingCart, Operation, Setting, Location, Plus, Edit, Delete, Close } from '@element-plus/icons-vue'
|
||||
import { Box, TrendCharts, ShoppingCart, Operation, Setting, Location, Plus, Edit, Delete, Close, Search } from '@element-plus/icons-vue'
|
||||
import { getPrinterConfig, updatePrinterConfig } from '@/api/common/print'
|
||||
import request from '@/utils/request'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getWarehouseTree, createWarehouse, updateWarehouse, deleteWarehouse, batchDeleteWarehouse, batchGenerateWarehouse } from '@/api/common/warehouse'
|
||||
|
||||
@ -234,6 +261,61 @@ const printerForm = reactive({
|
||||
})
|
||||
const loading = ref(false)
|
||||
|
||||
// 全局搜索相关
|
||||
const globalSearchText = ref('')
|
||||
|
||||
const getBadgeType = (type: string) => {
|
||||
const map: Record<string, string> = {
|
||||
'material': 'success',
|
||||
'stock_buy': 'primary',
|
||||
'bom': 'warning'
|
||||
}
|
||||
return map[type] || 'info'
|
||||
}
|
||||
|
||||
const queryGlobalSearch = async (queryString: string, cb: (data: any[]) => void) => {
|
||||
if (!queryString || queryString.trim() === '') {
|
||||
cb([])
|
||||
return
|
||||
}
|
||||
try {
|
||||
const res: any = await request({
|
||||
url: '/v1/common/global-search',
|
||||
method: 'get',
|
||||
params: { keyword: queryString.trim() }
|
||||
})
|
||||
if (res.code === 200 && res.data) {
|
||||
cb(res.data)
|
||||
} else {
|
||||
cb([])
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('全局搜索失败:', error)
|
||||
cb([])
|
||||
}
|
||||
}
|
||||
|
||||
const handleSearchSelect = (item: any) => {
|
||||
globalSearchText.value = ''
|
||||
|
||||
if (item.type === 'material') {
|
||||
router.push({
|
||||
path: '/material/index',
|
||||
query: { edit_id: item.id, keyword: item.title }
|
||||
})
|
||||
} else if (item.type === 'stock_buy') {
|
||||
router.push({
|
||||
path: '/inventory/buy',
|
||||
query: { keyword: item.title }
|
||||
})
|
||||
} else if (item.type === 'bom') {
|
||||
router.push({
|
||||
path: '/bom',
|
||||
query: { keyword: item.title }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const openPrinterDialog = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
|
||||
Reference in New Issue
Block a user