mirror of
https://github.com/woodchen-ink/aimodels-prices.git
synced 2025-07-18 13:41:59 +08:00
添加价格列表搜索功能
- 后端 prices.go 新增搜索查询参数,支持按模型名称模糊搜索 - 更新缓存键和总数缓存键,包含搜索查询参数 - 前端 Prices.vue 添加搜索输入框和搜索处理逻辑 - 实现搜索防抖,优化用户交互体验 - 重置搜索时自动返回第一页
This commit is contained in:
parent
680d684016
commit
2b2cc35a1c
@ -19,6 +19,7 @@ func GetPrices(c *gin.Context) {
|
|||||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "20"))
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "20"))
|
||||||
channelType := c.Query("channel_type") // 厂商筛选参数
|
channelType := c.Query("channel_type") // 厂商筛选参数
|
||||||
modelType := c.Query("model_type") // 模型类型筛选参数
|
modelType := c.Query("model_type") // 模型类型筛选参数
|
||||||
|
searchQuery := c.Query("search") // 搜索查询参数
|
||||||
|
|
||||||
if page < 1 {
|
if page < 1 {
|
||||||
page = 1
|
page = 1
|
||||||
@ -30,8 +31,8 @@ func GetPrices(c *gin.Context) {
|
|||||||
offset := (page - 1) * pageSize
|
offset := (page - 1) * pageSize
|
||||||
|
|
||||||
// 构建缓存键
|
// 构建缓存键
|
||||||
cacheKey := fmt.Sprintf("prices_page_%d_size_%d_channel_%s_type_%s",
|
cacheKey := fmt.Sprintf("prices_page_%d_size_%d_channel_%s_type_%s_search_%s",
|
||||||
page, pageSize, channelType, modelType)
|
page, pageSize, channelType, modelType, searchQuery)
|
||||||
|
|
||||||
// 尝试从缓存获取
|
// 尝试从缓存获取
|
||||||
if cachedData, found := database.GlobalCache.Get(cacheKey); found {
|
if cachedData, found := database.GlobalCache.Get(cacheKey); found {
|
||||||
@ -51,10 +52,14 @@ func GetPrices(c *gin.Context) {
|
|||||||
if modelType != "" {
|
if modelType != "" {
|
||||||
query = query.Where("model_type = ?", modelType)
|
query = query.Where("model_type = ?", modelType)
|
||||||
}
|
}
|
||||||
|
// 添加搜索条件
|
||||||
|
if searchQuery != "" {
|
||||||
|
query = query.Where("model LIKE ?", "%"+searchQuery+"%")
|
||||||
|
}
|
||||||
|
|
||||||
// 获取总数 - 使用缓存优化
|
// 获取总数 - 使用缓存优化
|
||||||
var total int64
|
var total int64
|
||||||
totalCacheKey := fmt.Sprintf("prices_count_channel_%s_type_%s", channelType, modelType)
|
totalCacheKey := fmt.Sprintf("prices_count_channel_%s_type_%s_search_%s", channelType, modelType, searchQuery)
|
||||||
|
|
||||||
if cachedTotal, found := database.GlobalCache.Get(totalCacheKey); found {
|
if cachedTotal, found := database.GlobalCache.Get(totalCacheKey); found {
|
||||||
if t, ok := cachedTotal.(int64); ok {
|
if t, ok := cachedTotal.(int64); ok {
|
||||||
|
@ -22,6 +22,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 添加搜索框 -->
|
||||||
|
<div class="search-section">
|
||||||
|
<el-input
|
||||||
|
v-model="searchQuery"
|
||||||
|
placeholder="搜索模型名称"
|
||||||
|
clearable
|
||||||
|
prefix-icon="Search"
|
||||||
|
@input="handleSearch"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<el-icon><Search /></el-icon>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="filter-section">
|
<div class="filter-section">
|
||||||
<div class="filter-label">厂商筛选:</div>
|
<div class="filter-label">厂商筛选:</div>
|
||||||
<div class="provider-filters">
|
<div class="provider-filters">
|
||||||
@ -502,7 +517,7 @@ import { ref, computed, onMounted, watch } from 'vue'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { Edit, Delete, Check, Close, Document } from '@element-plus/icons-vue'
|
import { Edit, Delete, Check, Close, Document, Search } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
user: Object
|
user: Object
|
||||||
@ -524,6 +539,7 @@ const form = ref({
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const selectedProvider = ref('')
|
const selectedProvider = ref('')
|
||||||
const selectedModelType = ref('')
|
const selectedModelType = ref('')
|
||||||
|
const searchQuery = ref('')
|
||||||
|
|
||||||
const isAdmin = computed(() => props.user?.role === 'admin')
|
const isAdmin = computed(() => props.user?.role === 'admin')
|
||||||
|
|
||||||
@ -588,6 +604,10 @@ const loadPrices = async () => {
|
|||||||
if (selectedModelType.value) {
|
if (selectedModelType.value) {
|
||||||
params.model_type = selectedModelType.value
|
params.model_type = selectedModelType.value
|
||||||
}
|
}
|
||||||
|
// 添加搜索参数
|
||||||
|
if (searchQuery.value) {
|
||||||
|
params.search = searchQuery.value
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [pricesRes, providersRes] = await Promise.all([
|
const [pricesRes, providersRes] = await Promise.all([
|
||||||
@ -600,7 +620,7 @@ const loadPrices = async () => {
|
|||||||
providers.value = providersRes.data
|
providers.value = providersRes.data
|
||||||
|
|
||||||
// 缓存数据
|
// 缓存数据
|
||||||
const cacheKey = `${currentPage.value}-${pageSize.value}-${selectedProvider.value}-${selectedModelType.value}`
|
const cacheKey = `${currentPage.value}-${pageSize.value}-${selectedProvider.value}-${selectedModelType.value}-${searchQuery.value}`
|
||||||
cachedPrices.value.set(cacheKey, {
|
cachedPrices.value.set(cacheKey, {
|
||||||
prices: pricesRes.data.data,
|
prices: pricesRes.data.data,
|
||||||
total: pricesRes.data.total
|
total: pricesRes.data.total
|
||||||
@ -1058,6 +1078,19 @@ watch(selectedModelType, () => {
|
|||||||
loadPrices()
|
loadPrices()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 监听搜索查询变化
|
||||||
|
watch(searchQuery, () => {
|
||||||
|
// 使用防抖处理,避免频繁请求
|
||||||
|
if (searchDebounceTimer) clearTimeout(searchDebounceTimer)
|
||||||
|
searchDebounceTimer = setTimeout(() => {
|
||||||
|
currentPage.value = 1 // 重置到第一页
|
||||||
|
loadPrices()
|
||||||
|
}, 300)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加防抖定时器
|
||||||
|
let searchDebounceTimer = null
|
||||||
|
|
||||||
// 复制行
|
// 复制行
|
||||||
const duplicateRow = (index) => {
|
const duplicateRow = (index) => {
|
||||||
const newRow = { ...batchForms.value[index] }
|
const newRow = { ...batchForms.value[index] }
|
||||||
@ -1107,6 +1140,12 @@ const approveAllPending = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理搜索
|
||||||
|
const handleSearch = () => {
|
||||||
|
currentPage.value = 1 // 重置到第一页
|
||||||
|
loadPrices()
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadModelTypes()
|
loadModelTypes()
|
||||||
loadPrices()
|
loadPrices()
|
||||||
@ -1137,6 +1176,11 @@ onMounted(() => {
|
|||||||
color: #606266;
|
color: #606266;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-section {
|
||||||
|
margin: 16px 0;
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
.provider-filters {
|
.provider-filters {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user