diff --git a/backend/app/http/admin/posts.go b/backend/app/http/admin/posts.go index a8f3a42..9923db0 100644 --- a/backend/app/http/admin/posts.go +++ b/backend/app/http/admin/posts.go @@ -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) } diff --git a/backend/app/http/posts.go b/backend/app/http/posts.go index 61e2ef5..60ac8d3 100644 --- a/backend/app/http/posts.go +++ b/backend/app/http/posts.go @@ -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) } diff --git a/backend/app/models/posts.go b/backend/app/models/posts.go index 2704724..dcffa0f 100644 --- a/backend/app/models/posts.go +++ b/backend/app/models/posts.go @@ -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) diff --git a/backend/test.http b/backend/test.http index 1c04c34..3c317d8 100644 --- a/backend/test.http +++ b/backend/test.http @@ -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 \ No newline at end of file diff --git a/frontend/admin/src/api/postService.js b/frontend/admin/src/api/postService.js index 26dbaf9..e33ca39 100644 --- a/frontend/admin/src/api/postService.js +++ b/frontend/admin/src/api/postService.js @@ -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) { diff --git a/frontend/admin/src/pages/PostPage.vue b/frontend/admin/src/pages/PostPage.vue index 223d4ba..0dddcab 100644 --- a/frontend/admin/src/pages/PostPage.vue +++ b/frontend/admin/src/pages/PostPage.vue @@ -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) => {
- +