diff --git a/backend/handlers/prices.go b/backend/handlers/prices.go
index 6b49aae..c4b406e 100644
--- a/backend/handlers/prices.go
+++ b/backend/handlers/prices.go
@@ -19,6 +19,7 @@ func GetPrices(c *gin.Context) {
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "20"))
channelType := c.Query("channel_type") // 厂商筛选参数
modelType := c.Query("model_type") // 模型类型筛选参数
+ searchQuery := c.Query("search") // 搜索查询参数
if page < 1 {
page = 1
@@ -30,8 +31,8 @@ func GetPrices(c *gin.Context) {
offset := (page - 1) * pageSize
// 构建缓存键
- cacheKey := fmt.Sprintf("prices_page_%d_size_%d_channel_%s_type_%s",
- page, pageSize, channelType, modelType)
+ cacheKey := fmt.Sprintf("prices_page_%d_size_%d_channel_%s_type_%s_search_%s",
+ page, pageSize, channelType, modelType, searchQuery)
// 尝试从缓存获取
if cachedData, found := database.GlobalCache.Get(cacheKey); found {
@@ -51,10 +52,14 @@ func GetPrices(c *gin.Context) {
if modelType != "" {
query = query.Where("model_type = ?", modelType)
}
+ // 添加搜索条件
+ if searchQuery != "" {
+ query = query.Where("model LIKE ?", "%"+searchQuery+"%")
+ }
// 获取总数 - 使用缓存优化
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 t, ok := cachedTotal.(int64); ok {
diff --git a/frontend/src/views/Prices.vue b/frontend/src/views/Prices.vue
index 13e4363..404361b 100644
--- a/frontend/src/views/Prices.vue
+++ b/frontend/src/views/Prices.vue
@@ -22,6 +22,21 @@
+
+
+
+
+
+
+
+
+
厂商筛选:
@@ -502,7 +517,7 @@ import { ref, computed, onMounted, watch } from 'vue'
import axios from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
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({
user: Object
@@ -524,6 +539,7 @@ const form = ref({
const router = useRouter()
const selectedProvider = ref('')
const selectedModelType = ref('')
+const searchQuery = ref('')
const isAdmin = computed(() => props.user?.role === 'admin')
@@ -588,6 +604,10 @@ const loadPrices = async () => {
if (selectedModelType.value) {
params.model_type = selectedModelType.value
}
+ // 添加搜索参数
+ if (searchQuery.value) {
+ params.search = searchQuery.value
+ }
try {
const [pricesRes, providersRes] = await Promise.all([
@@ -600,7 +620,7 @@ const loadPrices = async () => {
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, {
prices: pricesRes.data.data,
total: pricesRes.data.total
@@ -1058,6 +1078,19 @@ watch(selectedModelType, () => {
loadPrices()
})
+// 监听搜索查询变化
+watch(searchQuery, () => {
+ // 使用防抖处理,避免频繁请求
+ if (searchDebounceTimer) clearTimeout(searchDebounceTimer)
+ searchDebounceTimer = setTimeout(() => {
+ currentPage.value = 1 // 重置到第一页
+ loadPrices()
+ }, 300)
+})
+
+// 添加防抖定时器
+let searchDebounceTimer = null
+
// 复制行
const duplicateRow = (index) => {
const newRow = { ...batchForms.value[index] }
@@ -1107,6 +1140,12 @@ const approveAllPending = async () => {
}
}
+// 处理搜索
+const handleSearch = () => {
+ currentPage.value = 1 // 重置到第一页
+ loadPrices()
+}
+
onMounted(() => {
loadModelTypes()
loadPrices()
@@ -1137,6 +1176,11 @@ onMounted(() => {
color: #606266;
}
+.search-section {
+ margin: 16px 0;
+ max-width: 400px;
+}
+
.provider-filters {
display: flex;
flex-wrap: wrap;