补充tag处理

This commit is contained in:
yumaojun03 2024-12-08 16:20:18 +08:00
parent e0e7ff5b7c
commit e7ee8b3f20
9 changed files with 204 additions and 9 deletions

View File

@ -182,3 +182,64 @@ func (u *UserServiceImpl) Registry(ctx context.Context, in *user.RegistryRequest
return ins, nil return ins, nil
} }
``` ```
### 接口层
Gin
```go
package api
import (
"github.com/gin-gonic/gin"
"github.com/infraboard/mcube/v2/http/gin/response"
"gitlab.com/go-course-project/go17/vblog/apps/token"
"gitlab.com/go-course-project/go17/vblog/apps/token/impl"
)
func NewTokenApiHandler() *TokenApiHandler {
return &TokenApiHandler{
token: impl.TokenService,
}
}
type TokenApiHandler struct {
// 业务控制器
token token.UserService
}
// 提供注册功能, 提供一个Group
// book := server.Group("/api/tokens")
func (h *TokenApiHandler) Registry(r *gin.Engine) {
router := r.Group("/api/tokens")
router.POST("/issue", h.IssueToken)
router.POST("/revolk", h.RevolkToken)
}
func (h *TokenApiHandler) IssueToken(ctx *gin.Context) {
in := token.NewIssueTokenRequest("", "")
if err := ctx.BindJSON(in); err != nil {
response.Failed(ctx, err)
return
}
ins, err := h.token.IssueToken(ctx.Request.Context(), in)
if err != nil {
response.Failed(ctx, err)
return
}
response.Success(ctx, ins)
}
func (h *TokenApiHandler) RevolkToken(ctx *gin.Context) {
in := &token.RevolkTokenRequest{}
if err := ctx.BindJSON(in); err != nil {
response.Failed(ctx, err)
return
}
ins, err := h.token.RevolkToken(ctx, in)
if err != nil {
response.Failed(ctx, err)
return
}
response.Success(ctx, ins)
}
```

View File

@ -0,0 +1,2 @@
# 存放当前板块的接口的定义

View File

@ -0,0 +1,48 @@
package api
import (
"github.com/gin-gonic/gin"
"github.com/infraboard/mcube/v2/http/gin/response"
"gitlab.com/go-course-project/go17/vblog/apps/blog"
)
type BlogApiHandler struct {
blog blog.Service
}
// BODY
func (h *BlogApiHandler) CreateBlog(ctx *gin.Context) {
in := &blog.CreateBlogRequest{}
if err := ctx.BindJSON(in); err != nil {
response.Failed(ctx, err)
return
}
ins, err := h.blog.CreateBlog(ctx.Request.Context(), in)
if err != nil {
response.Failed(ctx, err)
return
}
response.Success(ctx, ins)
}
func (h *BlogApiHandler) QueryBlog(ctx *gin.Context) {
in := blog.NewQueryBlogRequest()
// GET /search?name=John&age=30&country=USA
// type SearchQuery struct {
// Name string `form:"name"`
// Age int `form:"age"`
// Country string `form:"country"`
// }
if err := ctx.BindQuery(in); err != nil {
response.Failed(ctx, err)
return
}
in.SetTag(ctx.Query("tag"))
ins, err := h.blog.QueryBlog(ctx.Request.Context(), in)
if err != nil {
response.Failed(ctx, err)
return
}
response.Success(ctx, ins)
}

View File

@ -46,7 +46,7 @@ func (b *BlogServiceImpl) QueryBlog(ctx context.Context, in *blog.QueryBlogReque
query = query.Where("category = ?", in.Category) query = query.Where("category = ?", in.Category)
} }
for k, v := range in.Tags { for k, v := range in.Tags {
query = query.Where(fmt.Sprintf("tags->>'$.%s' = '?'", k), v) query = query.Where(fmt.Sprintf("tags->>'$.%s' = ?", k), v)
} }
set := blog.NewBlogSet() set := blog.NewBlogSet()

View File

@ -15,10 +15,13 @@ var (
// Required("admin") // Required("admin")
func TestCreateBlog(t *testing.T) { func TestCreateBlog(t *testing.T) {
req := &blog.CreateBlogRequest{ req := &blog.CreateBlogRequest{
Title: "Go项目课", Title: "Go项目课1",
Summary: "全栈项目", Summary: "全栈项目",
Content: "GORM + GIN", Content: "GORM + GIN",
Category: "软件开发", Category: "软件开发",
Tags: map[string]string{
"Language": "Golang",
},
} }
ins, err := impl.BlogService.CreateBlog(ctx, req) ins, err := impl.BlogService.CreateBlog(ctx, req)
if err != nil { if err != nil {
@ -30,9 +33,18 @@ func TestCreateBlog(t *testing.T) {
// SELECT * FROM `blogs` ORDER BY created_at DESC LIMIT 20 // SELECT * FROM `blogs` ORDER BY created_at DESC LIMIT 20
func TestQueryBlog(t *testing.T) { func TestQueryBlog(t *testing.T) {
req := blog.NewQueryBlogRequest() req := blog.NewQueryBlogRequest()
req.Tags = map[string]string{
"Language": "Golang",
}
ins, err := impl.BlogService.QueryBlog(ctx, req) ins, err := impl.BlogService.QueryBlog(ctx, req)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Log(ins) t.Log(ins)
} }
func TestNewQueryBlogRequest(t *testing.T) {
req := blog.NewQueryBlogRequest()
req.SetTag("key1=value1,key2=value2")
t.Log(req.Tags)
}

View File

@ -2,6 +2,7 @@ package blog
import ( import (
"context" "context"
"strings"
"gitlab.com/go-course-project/go17/vblog/utils" "gitlab.com/go-course-project/go17/vblog/utils"
) )
@ -50,16 +51,30 @@ type QueryBlogRequest struct {
// 分页参数 // 分页参数
utils.PageRequest utils.PageRequest
// 文章标题模糊匹配, Golang // 文章标题模糊匹配, Golang
Keywords string `json:"keywords"` Keywords string `json:"keywords" form:"keywords"`
// 状态过滤参数, 作者nil, 访客: STAGE_PUBLISHED // 状态过滤参数, 作者nil, 访客: STAGE_PUBLISHED
Stage *STAGE `json:"stage"` Stage *STAGE `json:"stage" form:"stage"`
// 查询某个用户具体的文章: 给作者用的 // 查询某个用户具体的文章: 给作者用的
CreateBy string `json:"createBy"` CreateBy string `json:"create_by" form:"create_by"`
// 分类 // 分类
Category string `json:"category"` Category string `json:"category" form:"category"`
// 查询Tag相关的文章 // 查询Tag相关的文章
// SELECT * // SELECT *
// FROM my_table // FROM my_table
// WHERE data->>'$.name' = '某个名字'; // WHERE data->>'$.name' = '某个名字';
Tags map[string]string `json:"tag"` Tags map[string]string `json:"tag" form:"-"`
}
// tags=key=value,key=value
// key=value,key=value
// key=value
func (r *QueryBlogRequest) SetTag(tag string) {
kvItem := strings.Split(tag, ",")
for i := range kvItem {
kvString := kvItem[i]
kv := strings.Split(kvString, "=")
if len(kv) > 1 {
r.Tags[kv[0]] = strings.Join(kv[1:], "=")
}
}
} }

View File

@ -0,0 +1,2 @@
# 存放当前板块的接口的定义

View File

@ -0,0 +1,55 @@
package api
import (
"github.com/gin-gonic/gin"
"github.com/infraboard/mcube/v2/http/gin/response"
"gitlab.com/go-course-project/go17/vblog/apps/token"
"gitlab.com/go-course-project/go17/vblog/apps/token/impl"
)
func NewTokenApiHandler() *TokenApiHandler {
return &TokenApiHandler{
token: impl.TokenService,
}
}
type TokenApiHandler struct {
// 业务控制器
token token.UserService
}
// 提供注册功能, 提供一个Group
// book := server.Group("/api/tokens")
func (h *TokenApiHandler) Registry(r *gin.Engine) {
router := r.Group("/api/tokens")
router.POST("/issue", h.IssueToken)
router.POST("/revolk", h.RevolkToken)
}
func (h *TokenApiHandler) IssueToken(ctx *gin.Context) {
in := token.NewIssueTokenRequest("", "")
if err := ctx.BindJSON(in); err != nil {
response.Failed(ctx, err)
return
}
ins, err := h.token.IssueToken(ctx.Request.Context(), in)
if err != nil {
response.Failed(ctx, err)
return
}
response.Success(ctx, ins)
}
func (h *TokenApiHandler) RevolkToken(ctx *gin.Context) {
in := &token.RevolkTokenRequest{}
if err := ctx.BindJSON(in); err != nil {
response.Failed(ctx, err)
return
}
ins, err := h.token.RevolkToken(ctx, in)
if err != nil {
response.Failed(ctx, err)
return
}
response.Success(ctx, ins)
}

View File

@ -9,9 +9,9 @@ func NewPageRequest() *PageRequest {
type PageRequest struct { type PageRequest struct {
// 分页大小 // 分页大小
PageSize uint `json:"page_size"` PageSize uint `json:"page_size" form:"page_size"`
// 当前是多少页面 // 当前是多少页面
PageNumber uint `json:"page_number"` PageNumber uint `json:"page_number" form:"page_number"`
} }
func (r *PageRequest) Offset() uint { func (r *PageRequest) Offset() uint {