fix: list query issues

This commit is contained in:
yanghao05
2025-04-09 17:25:41 +08:00
parent 1f4c05c54a
commit 05d368ef25
6 changed files with 43 additions and 17 deletions

View File

@@ -9,7 +9,7 @@ import (
)
type ListQuery struct {
Key *string `query:"key"`
Keyword *string `query:"keyword"`
}
// @provider
@@ -20,7 +20,7 @@ type posts struct{}
// @Bind pagination query
// @Bind query query
func (ctl *posts) List(ctx fiber.Ctx, pagination *requests.Pagination, query *ListQuery) (*requests.Pager, error) {
cond := models.Posts.BuildConditionWithKey(query.Key)
cond := models.Posts.BuildConditionWithKey(query.Keyword)
return models.Posts.List(ctx.Context(), pagination, cond)
}

View File

@@ -9,7 +9,7 @@ import (
)
type ListQuery struct {
Key *string `query:"key"`
keyword *string `query:"keyword"`
}
// @provider
@@ -20,7 +20,7 @@ type posts struct{}
// @Bind pagination query
// @Bind query query
func (ctl *posts) List(ctx fiber.Ctx, pagination *requests.Pagination, query *ListQuery) (*requests.Pager, error) {
cond := models.Posts.BuildConditionWithKey(query.Key)
cond := models.Posts.BuildConditionWithKey(query.keyword)
return models.Posts.List(ctx.Context(), pagination, cond)
}

View File

@@ -3,6 +3,7 @@ package models
import (
"context"
"errors"
"log"
"time"
"quyun/app/requests"
@@ -34,16 +35,19 @@ func (m *postsModel) BuildConditionWithKey(key *string) BoolExpression {
)
if key == nil || *key == "" {
log.Fatal(*key)
return cond
}
cond = tbl.Title.LIKE(String("%" + *key + "%")).
OR(
tbl.Content.LIKE(String("%" + *key + "%")),
).
OR(
tbl.Description.LIKE(String("%" + *key + "%")),
)
cond = cond.AND(
tbl.Title.LIKE(String("%" + *key + "%")).
OR(
tbl.Content.LIKE(String("%" + *key + "%")),
).
OR(
tbl.Description.LIKE(String("%" + *key + "%")),
),
)
return cond
}
@@ -135,7 +139,7 @@ func (m *postsModel) List(ctx context.Context, pagination *requests.Pagination,
OFFSET(pagination.Offset)
m.log.Infof("sql: %s", stmt.DebugSql())
var posts []model.Posts
var posts []model.Posts = make([]model.Posts, 0)
err := stmt.QueryContext(ctx, db, &posts)
if err != nil {
m.log.Errorf("error querying post items: %v", err)

View File

@@ -39,4 +39,8 @@ Content-Type: application/json
### get posts
GET {{host}}/v1/admin/posts HTTP/1.1
Content-Type: application/json
### get posts with keyword
GET {{host}}/v1/admin/posts?page=1&limit=10&keyword=99123 HTTP/1.1
Content-Type: application/json

View File

@@ -1,9 +1,13 @@
import httpClient from './httpClient';
export const postService = {
getPosts({ page = 1, limit = 10 } = {}) {
getPosts({ page = 1, limit = 10, keyword = '' } = {}) {
return httpClient.get('/admin/posts', {
params: { page, limit }
params: {
page,
limit,
keyword: keyword.trim()
}
});
},
getPost(id) {

View File

@@ -38,6 +38,7 @@ const mediaTypeOptions = ref([
const globalFilterValue = ref('');
const loading = ref(false);
const searchTimeout = ref(null);
// Sample data - in a real app, this would come from an API
const posts = ref([]);
@@ -116,7 +117,7 @@ const calculateDiscountPrice = (price, discount) => {
return price * (1 - discount / 100);
};
// Fetch posts data with pagination
// Fetch posts data with pagination and search
const fetchPosts = async () => {
loading.value = true;
try {
@@ -126,7 +127,8 @@ const fetchPosts = async () => {
const response = await postService.getPosts({
page: currentPage,
limit: rows.value
limit: rows.value,
keyword: globalFilterValue.value
});
posts.value = response.items.map(post => ({
@@ -155,6 +157,18 @@ const onPage = (event) => {
fetchPosts();
};
// Handle search with debounce
const onSearch = (event) => {
if (searchTimeout.value) {
clearTimeout(searchTimeout.value);
}
searchTimeout.value = setTimeout(() => {
first.value = 0; // Reset to first page when searching
fetchPosts();
}, 300);
};
onMounted(() => {
fetchPosts();
});
@@ -195,7 +209,7 @@ const formatMediaTypes = (mediaTypes) => {
<!-- Posts Table -->
<div class="card mt-10">
<div class="pb-10 flex">
<InputText v-model="globalFilterValue" placeholder="搜索文章..." class="flex-1" />
<InputText v-model="globalFilterValue" placeholder="搜索文章..." class="flex-1" @input="onSearch" />
</div>
<DataTable v-model:filters="filters" :value="posts" :paginator="true" :rows="rows" :totalRecords="total"