feat: docs api design

This commit is contained in:
neo-f
2023-03-22 22:45:17 +08:00
commit 084d0de8bc
52 changed files with 3420 additions and 0 deletions

106
internal/schema/base.go Normal file
View File

@@ -0,0 +1,106 @@
package schema
const (
maxPageSize = 1000
defaultPageSize = 10
)
type PageableQuery struct {
Size *int `query:"size" oai:"description=返回数据数量;default=10;maximum=1000"`
Offset *int `query:"offset" oai:"description=数据偏移量;default=0"`
}
func (p *PageableQuery) GetLimit() int {
if p.Size == nil {
return defaultPageSize
}
if *p.Size >= maxPageSize {
return maxPageSize
}
return *p.Size
}
func (p *PageableQuery) GetOffset() int {
if p.Offset == nil {
return 0
}
return *p.Offset
}
type SortField struct {
Field string
Asc bool
}
type SortableQuery struct {
SortBy *[]string `query:"sort_by" oai:"description=排序字段, 如: +id,-created_at,test 表示依次按照id正序,created_at倒序,test正序"`
}
func (s *SortableQuery) GetOrderField() []SortField {
if s.SortBy == nil {
return nil
}
fields := make([]SortField, 0, len(*s.SortBy))
for _, v := range *s.SortBy {
if v == "" {
continue
}
switch v[0] {
case '+':
fields = append(fields, SortField{Field: v[1:], Asc: true})
case '-':
fields = append(fields, SortField{Field: v[1:], Asc: false})
default:
fields = append(fields, SortField{Field: v, Asc: true})
}
}
return fields
}
type SortableBody struct {
SortBy *[]string `json:"sort_by" oai:"description=排序字段, 如: id desc/asc"`
}
func (s *SortableBody) GetOrderField() []SortField {
if s.SortBy == nil {
return nil
}
fields := make([]SortField, 0, len(*s.SortBy))
for _, v := range *s.SortBy {
if v == "" {
continue
}
switch v[0] {
case '+':
fields = append(fields, SortField{Field: v[1:], Asc: true})
case '-':
fields = append(fields, SortField{Field: v[1:], Asc: false})
default:
fields = append(fields, SortField{Field: v, Asc: true})
}
}
return fields
}
type PageableBody struct {
Size *int `json:"size" oai:"description=返回数据数量;default=10;maximum=1000"`
Offset *int `json:"offset" oai:"description=数据偏移量;default=0"`
}
func (p *PageableBody) GetLimit() int {
if p.Size == nil {
return defaultPageSize
}
if *p.Size >= maxPageSize {
return maxPageSize
}
return *p.Size
}
func (p *PageableBody) GetOffset() int {
if p.Offset == nil {
return 0
}
return *p.Offset
}

106
internal/schema/docs.go Normal file
View File

@@ -0,0 +1,106 @@
package schema
import (
"octopus/pkg/tools"
"time"
"github.com/gofiber/fiber/v2"
)
type DocFolder struct {
ID string `json:"id" oai:"description=文件夹ID"`
IsDeletable bool `json:"is_deletable" oai:"description=文件夹是否允许被删除"`
IsEditable bool `json:"is_editable" oai:"description=文件夹是否允许被修改"`
CreatedAt time.Time `json:"created_at" oai:"description=创建时间"`
UpdatedAt time.Time `json:"updated_at" oai:"description=更新时间"`
}
type DocFolderID struct {
ID string `path:"id" oai:"description=文件夹ID"`
}
type CreateDocFolder struct {
Name string `json:"name" validate:"required" oai:"description=文件夹名称"`
ParentID string `json:"parent_id" oai:"description=父文件夹ID,空表示在根路径创建"`
}
type UpdateDocFolder struct {
Name *string `json:"name" oai:"description=修改文件夹名称"`
ParentID *string `json:"parent_id" oai:"description=修改文件夹父级ID"`
}
type GetDocFolderTree struct {
ParentID *string `query:"parent_id" oai:"description=父文件夹ID,空表示获取根路径"`
}
type DocFolderWithChildren struct {
ID string `json:"id" oai:"description=文件夹ID**根文件夹无ID**"`
IsDeletable bool `json:"is_deletable" oai:"description=文件夹是否允许被删除"`
IsEditable bool `json:"is_editable" oai:"description=文件夹是否允许被修改"`
CreatedAt time.Time `json:"created_at" oai:"description=创建时间"`
UpdatedAt time.Time `json:"updated_at" oai:"description=更新时间"`
Children []*DocFolderWithChildren `json:"children" oai:"description=子文件夹"`
}
type Doc struct {
ID string `json:"id" oai:"description=文档ID"`
Folder DocFolder `json:"folder" oai:"description=归属文件夹信息"`
PresignedURL string `json:"presigned_url" oai:"description=文档预签名下载URL(临时下载URL)"`
IsDeletable bool `json:"is_deletable" oai:"description=文件夹是否允许被删除"`
IsEditable bool `json:"is_editable" oai:"description=文件夹是否允许被修改"`
UploadedAt time.Time `json:"uploaded_at" oai:"description=上传时间"`
CreatedAt time.Time `json:"created_at" oai:"description=创建时间"`
UpdatedAt time.Time `json:"updated_at" oai:"description=更新时间"`
}
type DocList struct {
Items []*Doc `json:"items" oai:"description=文档列表"`
Total int64 `json:"total" oai:"description=文档总数"`
}
type DocID struct {
ID string `path:"id" oai:"description=文档ID"`
}
type CreateDoc struct {
Name string `json:"name" validate:"required" oai:"description=文档名称"`
FolderID string `json:"folder_id" validate:"required" oai:"description=归属文件夹ID"`
}
type UpdateDoc struct {
Name *string `json:"name" oai:"description=更新文档名称"`
FolderID *string `json:"folder_id" oai:"description=更新归属文件夹ID"`
}
type ListDocQuery struct {
PageableQuery
SortableQuery
FolderIDs *[]string `query:"folder_ids" validate:"required" oai:"description=归属文件夹ID"`
}
type DocsBatchDelete struct {
IDs []string `query:"ids" validate:"required" oai:"description=批量选择文件ID列表"`
FolderID string ` validate:"required" oai:"description=更新归属文件夹ID" json:"folder_id"`
}
type DocsBatchUpdate struct {
IDs []string `query:"ids" validate:"required" oai:"description=批量选择文件ID列表"`
}
type DocActionResult struct {
ID string `json:"id" oai:"description=文档ID"`
Success bool `json:"success" oai:"description=操作是否成功"`
Message *string `json:"message,omitempty" oai:"description=操作失败信息"`
}
type DocsBatchResults []DocActionResult
func (q *ListDocQuery) Validate() error {
sortable := tools.NewSet("uploaded_at")
for _, s := range q.GetOrderField() {
if !sortable.Has(s.Field) {
return fiber.NewError(fiber.StatusBadRequest, "unsupported order field")
}
}
return nil
}