diff --git a/backend_v1/app/http/admin/auth.go b/backend_v1/app/http/admin/auth.go index f226878..0988573 100644 --- a/backend_v1/app/http/admin/auth.go +++ b/backend_v1/app/http/admin/auth.go @@ -22,8 +22,14 @@ type TokenResponse struct { // Login // -// @Router /admin/auth [post] -// @Bind body body +// @Summary 管理员登录 +// @Tags Admin Auth +// @Accept json +// @Produce json +// @Param body body AuthBody true "请求体" +// @Success 200 {object} TokenResponse "成功" +// @Router /admin/auth [post] +// @Bind body body func (ctl *auth) Login(ctx fiber.Ctx, body *AuthBody) (*TokenResponse, error) { if body.Username == "pl.yang" && body.Password == "Xixi@0202" { claim := ctl.jwt.CreateClaims(jwt.BaseClaims{ diff --git a/backend_v1/app/http/admin/medias.go b/backend_v1/app/http/admin/medias.go index 5cdad8b..f686167 100644 --- a/backend_v1/app/http/admin/medias.go +++ b/backend_v1/app/http/admin/medias.go @@ -17,17 +17,27 @@ type medias struct { // List medias // -// @Router /admin/medias [get] -// @Bind pagination query -// @Bind query query +// @Summary 媒体列表 +// @Tags Admin Medias +// @Produce json +// @Param pagination query requests.Pagination false "分页参数" +// @Param query query ListQuery false "筛选条件" +// @Success 200 {object} requests.Pager{items=models.Media} "成功" +// @Router /admin/medias [get] +// @Bind pagination query +// @Bind query query func (ctl *medias) List(ctx fiber.Ctx, pagination *requests.Pagination, query *ListQuery) (*requests.Pager, error) { return services.Medias.List(ctx, pagination, models.MediaQuery.Name.Like(database.WrapLike(*query.Keyword))) } // Show media // -// @Router /admin/medias/:id [get] -// @Bind id path +// @Summary 媒体预览(跳转到签名 URL) +// @Tags Admin Medias +// @Param id path int64 true "媒体 ID" +// @Success 302 {string} string "跳转" +// @Router /admin/medias/:id [get] +// @Bind id path func (ctl *medias) Show(ctx fiber.Ctx, id int64) error { media, err := services.Medias.FindByID(ctx, id) if err != nil { @@ -44,8 +54,13 @@ func (ctl *medias) Show(ctx fiber.Ctx, id int64) error { // Delete // -// @Router /admin/medias/:id [delete] -// @Bind id path +// @Summary 删除媒体 +// @Tags Admin Medias +// @Produce json +// @Param id path int64 true "媒体 ID" +// @Success 204 {object} any "成功" +// @Router /admin/medias/:id [delete] +// @Bind id path func (ctl *medias) Delete(ctx fiber.Ctx, id int64) error { media, err := services.Medias.FindByID(ctx, id) if err != nil { diff --git a/backend_v1/app/http/admin/orders.go b/backend_v1/app/http/admin/orders.go index 46318e0..9716017 100644 --- a/backend_v1/app/http/admin/orders.go +++ b/backend_v1/app/http/admin/orders.go @@ -26,9 +26,15 @@ type orders struct { // List users // -// @Router /admin/orders [get] -// @Bind pagination query -// @Bind query query +// @Summary 订单列表 +// @Tags Admin Orders +// @Produce json +// @Param pagination query requests.Pagination false "分页参数" +// @Param query query OrderListQuery false "筛选条件" +// @Success 200 {object} requests.Pager{items=services.OrderListItem} "成功" +// @Router /admin/orders [get] +// @Bind pagination query +// @Bind query query func (ctl *orders) List( ctx fiber.Ctx, pagination *requests.Pagination, @@ -47,8 +53,14 @@ func (ctl *orders) List( } // Refund -// @Router /admin/orders/:id/refund [post] -// @Bind id path +// +// @Summary 订单退款 +// @Tags Admin Orders +// @Produce json +// @Param id path int64 true "订单 ID" +// @Success 200 {object} any "成功" +// @Router /admin/orders/:id/refund [post] +// @Bind id path func (ctl *orders) Refund(ctx fiber.Ctx, id int64) error { order, err := services.Orders.FindByID(ctx, id) if err != nil { diff --git a/backend_v1/app/http/admin/posts.go b/backend_v1/app/http/admin/posts.go index 4b47e4c..06bb175 100644 --- a/backend_v1/app/http/admin/posts.go +++ b/backend_v1/app/http/admin/posts.go @@ -21,9 +21,15 @@ type posts struct{} // List posts // -// @Router /admin/posts [get] -// @Bind pagination query -// @Bind query query +// @Summary 作品列表 +// @Tags Admin Posts +// @Produce json +// @Param pagination query requests.Pagination false "分页参数" +// @Param query query ListQuery false "筛选条件" +// @Success 200 {object} requests.Pager{items=PostItem} "成功" +// @Router /admin/posts [get] +// @Bind pagination query +// @Bind query query func (ctl *posts) List(ctx fiber.Ctx, pagination *requests.Pagination, query *ListQuery) (*requests.Pager, error) { conds := []gen.Condition{ models.PostQuery.Title.Like(*query.Keyword), @@ -69,8 +75,14 @@ type PostForm struct { // Create // -// @Router /admin/posts [post] -// @Bind form body +// @Summary 创建作品 +// @Tags Admin Posts +// @Accept json +// @Produce json +// @Param form body PostForm true "请求体" +// @Success 200 {object} any "成功" +// @Router /admin/posts [post] +// @Bind form body func (ctl *posts) Create(ctx fiber.Ctx, form *PostForm) error { post := models.Post{ Title: form.Title, @@ -107,9 +119,16 @@ func (ctl *posts) Create(ctx fiber.Ctx, form *PostForm) error { // Update posts // -// @Router /admin/posts/:id [put] -// @Bind id path -// @Bind form body +// @Summary 更新作品 +// @Tags Admin Posts +// @Accept json +// @Produce json +// @Param id path int64 true "作品 ID" +// @Param form body PostForm true "请求体" +// @Success 200 {object} any "成功" +// @Router /admin/posts/:id [put] +// @Bind id path +// @Bind form body func (ctl *posts) Update(ctx fiber.Ctx, id int64, form *PostForm) error { post, err := services.Posts.FindByID(ctx, id) if err != nil { @@ -147,8 +166,13 @@ func (ctl *posts) Update(ctx fiber.Ctx, id int64, form *PostForm) error { // Delete posts // -// @Router /admin/posts/:id [delete] -// @Bind id path +// @Summary 删除作品 +// @Tags Admin Posts +// @Produce json +// @Param id path int64 true "作品 ID" +// @Success 204 {object} any "成功" +// @Router /admin/posts/:id [delete] +// @Bind id path func (ctl *posts) Delete(ctx fiber.Ctx, id int64) error { post, err := services.Posts.FindByID(ctx, id) if err != nil { @@ -172,8 +196,13 @@ type PostItem struct { // Show posts by id // -// @Router /admin/posts/:id [get] -// @Bind id path +// @Summary 作品详情 +// @Tags Admin Posts +// @Produce json +// @Param id path int64 true "作品 ID" +// @Success 200 {object} PostItem "成功" +// @Router /admin/posts/:id [get] +// @Bind id path func (ctl *posts) Show(ctx fiber.Ctx, id int64) (*PostItem, error) { post, err := services.Posts.FindByID(ctx, id) if err != nil { @@ -194,9 +223,15 @@ func (ctl *posts) Show(ctx fiber.Ctx, id int64) (*PostItem, error) { // SendTo // -// @Router /admin/posts/:id/send-to/:userId [post] -// @Bind id path -// @Bind userId path +// @Summary 赠送作品给用户 +// @Tags Admin Posts +// @Produce json +// @Param id path int64 true "作品 ID" +// @Param userId path int64 true "用户 ID" +// @Success 200 {object} any "成功" +// @Router /admin/posts/:id/send-to/:userId [post] +// @Bind id path +// @Bind userId path func (ctl *posts) SendTo(ctx fiber.Ctx, id, userId int64) error { post, err := services.Posts.FindByID(ctx, id) if err != nil { diff --git a/backend_v1/app/http/admin/statistics.go b/backend_v1/app/http/admin/statistics.go index c05b441..4eed135 100644 --- a/backend_v1/app/http/admin/statistics.go +++ b/backend_v1/app/http/admin/statistics.go @@ -22,7 +22,11 @@ type StatisticsResponse struct { // dashboard statistics // -// @Router /admin/statistics [get] +// @Summary 仪表盘统计 +// @Tags Admin Statistics +// @Produce json +// @Success 200 {object} StatisticsResponse "成功" +// @Router /admin/statistics [get] func (s *statistics) statistics(ctx fiber.Ctx) (*StatisticsResponse, error) { statistics := &StatisticsResponse{} diff --git a/backend_v1/app/http/admin/uploads.go b/backend_v1/app/http/admin/uploads.go index d2b4a36..6122150 100644 --- a/backend_v1/app/http/admin/uploads.go +++ b/backend_v1/app/http/admin/uploads.go @@ -34,10 +34,17 @@ type PreCheckResp struct { // PreUploadCheck // -// @Router /admin/uploads/pre-uploaded-check/:md5.:ext [get] -// @Bind md5 path -// @Bind ext path -// @Bind mime query +// @Summary 预上传检查 +// @Tags Admin Uploads +// @Produce json +// @Param md5 path string true "文件 MD5" +// @Param ext path string true "文件扩展名(不含点)" +// @Param mime query string true "文件 MIME 类型" +// @Success 200 {object} PreCheckResp "成功" +// @Router /admin/uploads/pre-uploaded-check/:md5.:ext [get] +// @Bind md5 path +// @Bind ext path +// @Bind mime query func (up *uploads) PreUploadCheck(ctx fiber.Ctx, md5, ext, mime string) (*PreCheckResp, error) { _, err := services.Medias.GetByHash(ctx, md5) if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { @@ -61,8 +68,14 @@ type PostUploadedForm struct { // PostUploadedAction // -// @Router /admin/uploads/post-uploaded-action [post] -// @Bind body body +// @Summary 上传完成回调处理 +// @Tags Admin Uploads +// @Accept json +// @Produce json +// @Param body body PostUploadedForm true "请求体" +// @Success 200 {object} any "成功" +// @Router /admin/uploads/post-uploaded-action [post] +// @Bind body body func (up *uploads) PostUploadedAction(ctx fiber.Ctx, body *PostUploadedForm) error { m, err := services.Medias.GetByHash(ctx, body.Md5) if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { diff --git a/backend_v1/app/http/admin/users.go b/backend_v1/app/http/admin/users.go index c4daa67..b5f791f 100644 --- a/backend_v1/app/http/admin/users.go +++ b/backend_v1/app/http/admin/users.go @@ -19,9 +19,15 @@ type users struct{} // List users // -// @Router /admin/users [get] -// @Bind pagination query -// @Bind query query +// @Summary 用户列表 +// @Tags Admin Users +// @Produce json +// @Param pagination query requests.Pagination false "分页参数" +// @Param query query UserListQuery false "筛选条件" +// @Success 200 {object} requests.Pager{items=models.User} "成功" +// @Router /admin/users [get] +// @Bind pagination query +// @Bind query query func (ctl *users) List(ctx fiber.Ctx, pagination *requests.Pagination, query *UserListQuery) (*requests.Pager, error) { conds := []gen.Condition{ models.UserQuery.Username.Like(database.WrapLike(*query.Keyword)), @@ -31,17 +37,28 @@ func (ctl *users) List(ctx fiber.Ctx, pagination *requests.Pagination, query *Us // Show user // -// @Router /admin/users/:id [get] -// @Bind id path +// @Summary 用户详情 +// @Tags Admin Users +// @Produce json +// @Param id path int64 true "用户 ID" +// @Success 200 {object} models.User "成功" +// @Router /admin/users/:id [get] +// @Bind id path func (ctl *users) Show(ctx fiber.Ctx, id int64) (*models.User, error) { return services.Users.FindByID(ctx, id) } // Articles show user bought articles // -// @Router /admin/users/:id/articles [get] -// @Bind id path -// @Bind pagination query +// @Summary 用户已购作品 +// @Tags Admin Users +// @Produce json +// @Param id path int64 true "用户 ID" +// @Param pagination query requests.Pagination false "分页参数" +// @Success 200 {object} requests.Pager{items=models.Post} "成功" +// @Router /admin/users/:id/articles [get] +// @Bind id path +// @Bind pagination query func (ctl *users) Articles(ctx fiber.Ctx, id int64, pagination *requests.Pagination) (*requests.Pager, error) { return services.Posts.Bought(ctx, id, pagination) } @@ -52,9 +69,16 @@ type UserBalance struct { // Balance // -// @Router /admin/users/:id/balance [post] -// @Bind id path -// @Bind balance body +// @Summary 调整用户余额 +// @Tags Admin Users +// @Accept json +// @Produce json +// @Param id path int64 true "用户 ID" +// @Param balance body UserBalance true "请求体" +// @Success 200 {object} any "成功" +// @Router /admin/users/:id/balance [post] +// @Bind id path +// @Bind balance body func (ctl *users) Balance(ctx fiber.Ctx, id int64, balance *UserBalance) error { user, err := services.Users.FindByID(ctx, id) if err != nil { diff --git a/backend_v1/app/http/posts.go b/backend_v1/app/http/posts.go index 06dbf82..43726eb 100644 --- a/backend_v1/app/http/posts.go +++ b/backend_v1/app/http/posts.go @@ -38,10 +38,16 @@ type posts struct { // List posts // -// @Router /posts [get] -// @Bind pagination query -// @Bind query query -// @Bind user local +// @Summary 作品列表 +// @Tags Posts +// @Produce json +// @Param pagination query requests.Pagination false "分页参数" +// @Param query query ListQuery false "筛选条件" +// @Success 200 {object} requests.Pager{items=PostItem} "成功" +// @Router /posts [get] +// @Bind pagination query +// @Bind query query +// @Bind user local func (ctl *posts) List( ctx fiber.Ctx, pagination *requests.Pagination, @@ -123,9 +129,14 @@ type PostItem struct { // Show // -// @Router /posts/:id/show [get] -// @Bind id path -// @Bind user local +// @Summary 作品详情 +// @Tags Posts +// @Produce json +// @Param id path int64 true "作品 ID" +// @Success 200 {object} PostItem "成功" +// @Router /posts/:id/show [get] +// @Bind id path +// @Bind user local func (ctl *posts) Show(ctx fiber.Ctx, id int64, user *models.User) (*PostItem, error) { log.Infof("Fetching post with ID: %d", id) @@ -179,9 +190,14 @@ type PlayUrl struct { // Play // -// @Router /posts/:id/play [get] -// @Bind id path -// @Bind user local +// @Summary 获取播放地址 +// @Tags Posts +// @Produce json +// @Param id path int64 true "作品 ID" +// @Success 200 {object} PlayUrl "成功" +// @Router /posts/:id/play [get] +// @Bind id path +// @Bind user local func (ctl *posts) Play(ctx fiber.Ctx, id int64, user *models.User) (*PlayUrl, error) { log := log.WithField("PlayPostID", strconv.FormatInt(id, 10)) // return &PlayUrl{ @@ -230,10 +246,16 @@ func (ctl *posts) Play(ctx fiber.Ctx, id int64, user *models.User) (*PlayUrl, er // Mine posts // -// @Router /posts/mine [get] -// @Bind pagination query -// @Bind query query -// @Bind user local +// @Summary 我的已购作品 +// @Tags Posts +// @Produce json +// @Param pagination query requests.Pagination false "分页参数" +// @Param query query ListQuery false "筛选条件" +// @Success 200 {object} requests.Pager{items=PostItem} "成功" +// @Router /posts/mine [get] +// @Bind pagination query +// @Bind query query +// @Bind user local func (ctl *posts) Mine( ctx fiber.Ctx, pagination *requests.Pagination, @@ -292,9 +314,14 @@ func (ctl *posts) Mine( // Buy // -// @Router /posts/:id/buy [post] -// @Bind id path -// @Bind user local +// @Summary 购买作品 +// @Tags Posts +// @Produce json +// @Param id path int64 true "作品 ID" +// @Success 200 {object} wechat.JSAPIPayParams "成功(余额支付返回 AppId=balance)" +// @Router /posts/:id/buy [post] +// @Bind id path +// @Bind user local func (ctl *posts) Buy(ctx fiber.Ctx, id int64, user *models.User) (*wechat.JSAPIPayParams, error) { bought, err := services.Users.HasBought(ctx, user.ID, id) if err != nil { diff --git a/backend_v1/app/http/users.go b/backend_v1/app/http/users.go index dad47d1..e337704 100644 --- a/backend_v1/app/http/users.go +++ b/backend_v1/app/http/users.go @@ -21,8 +21,14 @@ type UserInfo struct { Balance int64 `json:"balance"` } -// @Router /users/profile [get] -// @Bind user local +// Profile 获取当前登录用户的基础信息。 +// +// @Summary 获取个人信息 +// @Tags Users +// @Produce json +// @Success 200 {object} UserInfo "成功" +// @Router /users/profile [get] +// @Bind user local func (ctl *users) Profile(ctx fiber.Ctx, user *models.User) (*UserInfo, error) { return &UserInfo{ ID: user.ID, @@ -37,11 +43,17 @@ type ProfileForm struct { Username string `json:"username" validate:"required"` } -// Update +// Update 修改当前登录用户的用户名。 // -// @Router /users/username [put] -// @Bind user local -// @Bind form body +// @Summary 修改用户名 +// @Tags Users +// @Accept json +// @Produce json +// @Param form body ProfileForm true "请求体" +// @Success 200 {object} any "成功" +// @Router /users/username [put] +// @Bind user local +// @Bind form body func (ctl *users) Update(ctx fiber.Ctx, user *models.User, form *ProfileForm) error { username := strings.TrimSpace(form.Username) if len([]rune(username)) > 12 { diff --git a/backend_v1/app/http/v1/demo.go b/backend_v1/app/http/v1/demo.go index 25100d3..edcec46 100644 --- a/backend_v1/app/http/v1/demo.go +++ b/backend_v1/app/http/v1/demo.go @@ -30,18 +30,20 @@ type Filter struct { type ResponseItem struct{} -// Foo +// Foo 演示端点:展示 Fiber 参数绑定与 Swagger 注释写法。 // -// @Summary Test -// @Description Test -// @Tags Test -// @Accept json +// @Summary 演示接口 +// @Tags Demo +// @Accept multipart/form-data // @Produce json // -// @Param id path int true "ID" -// @Param query query Filter true "Filter" -// @Param pager query requests.Pagination true "Pager" -// @Success 200 {object} requests.Pager{list=ResponseItem} "成功" +// @Param id path int true "ID" +// @Param pager query requests.Pagination false "分页参数" +// @Param query query FooQuery false "查询参数" +// @Param Content-Type header string false "内容类型" +// @Param folder formData string false "上传到指定文件夹" +// @Param file formData file true "上传文件" +// @Success 200 {object} requests.Pager{items=ResponseItem} "成功" // // @Router /v1/medias/:id [post] // @Bind query query diff --git a/backend_v1/app/services/orders.go b/backend_v1/app/services/orders.go index 4c9bfe2..dbd570f 100644 --- a/backend_v1/app/services/orders.go +++ b/backend_v1/app/services/orders.go @@ -14,6 +14,13 @@ import ( "go.ipao.vip/gen/types" ) +// OrderListItem 用于订单列表展示,补充作品标题与用户名等冗余信息,避免前端二次查询。 +type OrderListItem struct { + *models.Order + PostTitle string `json:"post_title"` + Username string `json:"username"` +} + // @provider type orders struct{} @@ -51,15 +58,8 @@ func (m *orders) List( postMap := lo.SliceToMap(posts, func(p *models.Post) (int64, *models.Post) { return p.ID, p }) userMap := lo.SliceToMap(users, func(u *models.User) (int64, *models.User) { return u.ID, u }) - // OrderListItem 用于订单列表展示,补充作品标题与用户名等冗余信息,避免前端二次查询。 - type orderListItem struct { - *models.Order - PostTitle string `json:"post_title"` - Username string `json:"username"` - } - - items := lo.Map(orders, func(o *models.Order, _ int) *orderListItem { - item := &orderListItem{Order: o} + items := lo.Map(orders, func(o *models.Order, _ int) *OrderListItem { + item := &OrderListItem{Order: o} if post, ok := postMap[o.PostID]; ok { item.PostTitle = post.Title } diff --git a/backend_v1/docs/docs.go b/backend_v1/docs/docs.go index 8c35c88..8176d62 100644 --- a/backend_v1/docs/docs.go +++ b/backend_v1/docs/docs.go @@ -24,9 +24,8 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { - "/v1/medias/{id}": { + "/admin/auth": { "post": { - "description": "Test", "consumes": [ "application/json" ], @@ -34,28 +33,598 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Test" + "Admin Auth" ], - "summary": "Test", + "summary": "管理员登录", + "parameters": [ + { + "description": "请求体", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.AuthBody" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/admin.TokenResponse" + } + } + } + } + }, + "/admin/medias": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Medias" + ], + "summary": "媒体列表", "parameters": [ { "type": "integer", - "description": "ID", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "name": "keyword", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/models.Media" + } + } + } + ] + } + } + } + } + }, + "/admin/medias/{id}": { + "get": { + "tags": [ + "Admin Medias" + ], + "summary": "媒体预览(跳转到签名 URL)", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "媒体 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "302": { + "description": "跳转", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Medias" + ], + "summary": "删除媒体", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "媒体 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/orders": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Orders" + ], + "summary": "订单列表", + "parameters": [ + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "name": "orderNumber", + "in": "query" + }, + { + "type": "integer", + "name": "userID", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/services.OrderListItem" + } + } + } + ] + } + } + } + } + }, + "/admin/orders/{id}/refund": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Orders" + ], + "summary": "订单退款", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "订单 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/posts": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "作品列表", + "parameters": [ + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "name": "keyword", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/admin.PostItem" + } + } + } + ] + } + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "创建作品", + "parameters": [ + { + "description": "请求体", + "name": "form", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.PostForm" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/posts/{id}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "作品详情", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/admin.PostItem" + } + } + } + }, + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "更新作品", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "请求体", + "name": "form", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.PostForm" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "删除作品", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/posts/{id}/send-to/{userId}": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "赠送作品给用户", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", "name": "id", "in": "path", "required": true }, { "type": "integer", - "description": "年龄", - "name": "age", + "format": "int64", + "description": "用户 ID", + "name": "userId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/statistics": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Statistics" + ], + "summary": "仪表盘统计", + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/admin.StatisticsResponse" + } + } + } + } + }, + "/admin/uploads/post-uploaded-action": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Admin Uploads" + ], + "summary": "上传完成回调处理", + "parameters": [ + { + "description": "请求体", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.PostUploadedForm" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/uploads/pre-uploaded-check/{md5}.{ext}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Uploads" + ], + "summary": "预上传检查", + "parameters": [ + { + "type": "string", + "description": "文件 MD5", + "name": "md5", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文件扩展名(不含点)", + "name": "ext", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文件 MIME 类型", + "name": "mime", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/admin.PreCheckResp" + } + } + } + } + }, + "/admin/users": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Users" + ], + "summary": "用户列表", + "parameters": [ + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", "in": "query" }, { "type": "string", - "description": "名称", - "name": "name", + "name": "keyword", "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/models.User" + } + } + } + ] + } + } + } + } + }, + "/admin/users/{id}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Users" + ], + "summary": "用户详情", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "用户 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/models.User" + } + } + } + } + }, + "/admin/users/{id}/articles": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Users" + ], + "summary": "用户已购作品", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "用户 ID", + "name": "id", + "in": "path", + "required": true }, { "type": "integer", @@ -79,7 +648,357 @@ const docTemplate = `{ { "type": "object", "properties": { - "list": { + "items": { + "$ref": "#/definitions/models.Post" + } + } + } + ] + } + } + } + } + }, + "/admin/users/{id}/balance": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Admin Users" + ], + "summary": "调整用户余额", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "用户 ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "请求体", + "name": "balance", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.UserBalance" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/posts": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Posts" + ], + "summary": "作品列表", + "parameters": [ + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "name": "keyword", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/http.PostItem" + } + } + } + ] + } + } + } + } + }, + "/posts/mine": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Posts" + ], + "summary": "我的已购作品", + "parameters": [ + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "name": "keyword", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/http.PostItem" + } + } + } + ] + } + } + } + } + }, + "/posts/{id}/buy": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "Posts" + ], + "summary": "购买作品", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功(余额支付返回 AppId=balance)", + "schema": { + "$ref": "#/definitions/wechat.JSAPIPayParams" + } + } + } + } + }, + "/posts/{id}/play": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Posts" + ], + "summary": "获取播放地址", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/http.PlayUrl" + } + } + } + } + }, + "/posts/{id}/show": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Posts" + ], + "summary": "作品详情", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/http.PostItem" + } + } + } + } + }, + "/users/profile": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "获取个人信息", + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/http.UserInfo" + } + } + } + } + }, + "/users/username": { + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "修改用户名", + "parameters": [ + { + "description": "请求体", + "name": "form", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/http.ProfileForm" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/v1/medias/{id}": { + "post": { + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Demo" + ], + "summary": "演示接口", + "parameters": [ + { + "type": "integer", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键词", + "name": "search", + "in": "query" + }, + { + "type": "string", + "description": "内容类型", + "name": "Content-Type", + "in": "header" + }, + { + "type": "string", + "description": "上传到指定文件夹", + "name": "folder", + "in": "formData" + }, + { + "type": "file", + "description": "上传文件", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { "$ref": "#/definitions/v1.ResponseItem" } } @@ -92,6 +1011,467 @@ const docTemplate = `{ } }, "definitions": { + "admin.AuthBody": { + "type": "object", + "required": [ + "password", + "username" + ], + "properties": { + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "admin.PostForm": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "discount": { + "type": "integer" + }, + "head_images": { + "type": "array", + "items": { + "type": "integer" + } + }, + "introduction": { + "type": "string" + }, + "medias": { + "type": "array", + "items": { + "type": "integer" + } + }, + "price": { + "type": "integer" + }, + "status": { + "$ref": "#/definitions/fields.PostStatus" + }, + "title": { + "type": "string" + } + } + }, + "admin.PostItem": { + "type": "object", + "properties": { + "assets": { + "$ref": "#/definitions/types.JSONType-array_fields_MediaAsset" + }, + "bought_count": { + "type": "integer" + }, + "content": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "$ref": "#/definitions/gorm.DeletedAt" + }, + "description": { + "type": "string" + }, + "discount": { + "type": "integer" + }, + "head_images": { + "$ref": "#/definitions/types.JSONType-array_int64" + }, + "id": { + "type": "integer" + }, + "likes": { + "type": "integer" + }, + "medias": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Media" + } + }, + "price": { + "type": "integer" + }, + "status": { + "$ref": "#/definitions/fields.PostStatus" + }, + "tags": { + "$ref": "#/definitions/types.JSONType-array_string" + }, + "title": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "views": { + "type": "integer" + } + } + }, + "admin.PostUploadedForm": { + "type": "object", + "properties": { + "md5": { + "type": "string" + }, + "mimeType": { + "type": "string" + }, + "originalName": { + "type": "string" + }, + "size": { + "type": "integer" + } + } + }, + "admin.PreCheckResp": { + "type": "object", + "properties": { + "exists": { + "type": "boolean" + }, + "pre_sign": { + "$ref": "#/definitions/oss.PresignResult" + } + } + }, + "admin.StatisticsResponse": { + "type": "object", + "properties": { + "amount": { + "type": "integer" + }, + "media": { + "type": "integer" + }, + "order": { + "type": "integer" + }, + "post_draft": { + "type": "integer" + }, + "post_published": { + "type": "integer" + }, + "user": { + "type": "integer" + } + } + }, + "admin.TokenResponse": { + "type": "object", + "properties": { + "token": { + "type": "string" + } + } + }, + "admin.UserBalance": { + "type": "object", + "properties": { + "balance": { + "type": "integer" + } + } + }, + "fields.OrderStatus": { + "type": "integer", + "format": "int32", + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "x-enum-varnames": [ + "OrderStatusPending", + "OrderStatusPaid", + "OrderStatusRefundSuccess", + "OrderStatusRefundClosed", + "OrderStatusRefundProcessing", + "OrderStatusRefundAbnormal", + "OrderStatusCancelled", + "OrderStatusCompleted" + ] + }, + "fields.PostStatus": { + "type": "integer", + "format": "int32", + "enum": [ + 0, + 1 + ], + "x-enum-varnames": [ + "PostStatusDraft", + "PostStatusPublished" + ] + }, + "fields.UserStatus": { + "type": "integer", + "format": "int32", + "enum": [ + 0, + 1, + 2 + ], + "x-enum-varnames": [ + "UserStatusOk", + "UserStatusBanned", + "UserStatusBlocked" + ] + }, + "gorm.DeletedAt": { + "type": "object", + "properties": { + "time": { + "type": "string" + }, + "valid": { + "description": "Valid is true if Time is not NULL", + "type": "boolean" + } + } + }, + "http.PlayUrl": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + } + }, + "http.PostItem": { + "type": "object", + "properties": { + "bought": { + "type": "boolean" + }, + "content": { + "type": "string" + }, + "description": { + "type": "string" + }, + "discount": { + "type": "integer" + }, + "head_images": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "integer" + }, + "likes": { + "type": "integer" + }, + "price": { + "type": "integer" + }, + "recharge_wechat": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "title": { + "type": "string" + }, + "views": { + "type": "integer" + } + } + }, + "http.ProfileForm": { + "type": "object", + "required": [ + "username" + ], + "properties": { + "username": { + "type": "string" + } + } + }, + "http.UserInfo": { + "type": "object", + "properties": { + "avatar": { + "type": "string" + }, + "balance": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "username": { + "type": "string" + } + } + }, + "models.Media": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "metas": { + "$ref": "#/definitions/types.JSONType-fields_MediaMetas" + }, + "mime_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "size": { + "type": "integer" + } + } + }, + "models.Post": { + "type": "object", + "properties": { + "assets": { + "$ref": "#/definitions/types.JSONType-array_fields_MediaAsset" + }, + "content": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "$ref": "#/definitions/gorm.DeletedAt" + }, + "description": { + "type": "string" + }, + "discount": { + "type": "integer" + }, + "head_images": { + "$ref": "#/definitions/types.JSONType-array_int64" + }, + "id": { + "type": "integer" + }, + "likes": { + "type": "integer" + }, + "price": { + "type": "integer" + }, + "status": { + "$ref": "#/definitions/fields.PostStatus" + }, + "tags": { + "$ref": "#/definitions/types.JSONType-array_string" + }, + "title": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "views": { + "type": "integer" + } + } + }, + "models.User": { + "type": "object", + "properties": { + "auth_token": { + "$ref": "#/definitions/types.JSONType-fields_UserAuthToken" + }, + "avatar": { + "type": "string" + }, + "balance": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "$ref": "#/definitions/gorm.DeletedAt" + }, + "id": { + "type": "integer" + }, + "metas": { + "$ref": "#/definitions/types.JSONType-fields_UserMetas" + }, + "open_id": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/fields.UserStatus" + }, + "updated_at": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "oss.PresignResult": { + "type": "object", + "properties": { + "expiration": { + "type": "string" + }, + "method": { + "type": "string" + }, + "signedHeaders": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "url": { + "type": "string" + } + } + }, "requests.Pager": { "type": "object", "properties": { @@ -107,8 +1487,108 @@ const docTemplate = `{ } } }, + "services.OrderListItem": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "currency": { + "type": "string" + }, + "discount": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "meta": { + "$ref": "#/definitions/types.JSONType-fields_OrderMeta" + }, + "order_no": { + "type": "string" + }, + "payment_method": { + "type": "string" + }, + "post_id": { + "type": "integer" + }, + "post_title": { + "type": "string" + }, + "price": { + "type": "integer" + }, + "refund_transaction_id": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/fields.OrderStatus" + }, + "sub_order_no": { + "type": "string" + }, + "transaction_id": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "user_id": { + "type": "integer" + }, + "username": { + "type": "string" + } + } + }, + "types.JSONType-array_fields_MediaAsset": { + "type": "object" + }, + "types.JSONType-array_int64": { + "type": "object" + }, + "types.JSONType-array_string": { + "type": "object" + }, + "types.JSONType-fields_MediaMetas": { + "type": "object" + }, + "types.JSONType-fields_OrderMeta": { + "type": "object" + }, + "types.JSONType-fields_UserAuthToken": { + "type": "object" + }, + "types.JSONType-fields_UserMetas": { + "type": "object" + }, "v1.ResponseItem": { "type": "object" + }, + "wechat.JSAPIPayParams": { + "type": "object", + "properties": { + "appId": { + "type": "string" + }, + "nonceStr": { + "type": "string" + }, + "package": { + "type": "string" + }, + "paySign": { + "type": "string" + }, + "signType": { + "type": "string" + }, + "timeStamp": { + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/backend_v1/docs/swagger.json b/backend_v1/docs/swagger.json index c1e57c5..c1127dd 100644 --- a/backend_v1/docs/swagger.json +++ b/backend_v1/docs/swagger.json @@ -18,9 +18,8 @@ "host": "localhost:8080", "basePath": "/api/v1", "paths": { - "/v1/medias/{id}": { + "/admin/auth": { "post": { - "description": "Test", "consumes": [ "application/json" ], @@ -28,28 +27,598 @@ "application/json" ], "tags": [ - "Test" + "Admin Auth" ], - "summary": "Test", + "summary": "管理员登录", + "parameters": [ + { + "description": "请求体", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.AuthBody" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/admin.TokenResponse" + } + } + } + } + }, + "/admin/medias": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Medias" + ], + "summary": "媒体列表", "parameters": [ { "type": "integer", - "description": "ID", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "name": "keyword", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/models.Media" + } + } + } + ] + } + } + } + } + }, + "/admin/medias/{id}": { + "get": { + "tags": [ + "Admin Medias" + ], + "summary": "媒体预览(跳转到签名 URL)", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "媒体 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "302": { + "description": "跳转", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Medias" + ], + "summary": "删除媒体", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "媒体 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/orders": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Orders" + ], + "summary": "订单列表", + "parameters": [ + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "name": "orderNumber", + "in": "query" + }, + { + "type": "integer", + "name": "userID", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/services.OrderListItem" + } + } + } + ] + } + } + } + } + }, + "/admin/orders/{id}/refund": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Orders" + ], + "summary": "订单退款", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "订单 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/posts": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "作品列表", + "parameters": [ + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "name": "keyword", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/admin.PostItem" + } + } + } + ] + } + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "创建作品", + "parameters": [ + { + "description": "请求体", + "name": "form", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.PostForm" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/posts/{id}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "作品详情", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/admin.PostItem" + } + } + } + }, + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "更新作品", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "请求体", + "name": "form", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.PostForm" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "删除作品", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/posts/{id}/send-to/{userId}": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Posts" + ], + "summary": "赠送作品给用户", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", "name": "id", "in": "path", "required": true }, { "type": "integer", - "description": "年龄", - "name": "age", + "format": "int64", + "description": "用户 ID", + "name": "userId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/statistics": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Statistics" + ], + "summary": "仪表盘统计", + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/admin.StatisticsResponse" + } + } + } + } + }, + "/admin/uploads/post-uploaded-action": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Admin Uploads" + ], + "summary": "上传完成回调处理", + "parameters": [ + { + "description": "请求体", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.PostUploadedForm" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/admin/uploads/pre-uploaded-check/{md5}.{ext}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Uploads" + ], + "summary": "预上传检查", + "parameters": [ + { + "type": "string", + "description": "文件 MD5", + "name": "md5", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文件扩展名(不含点)", + "name": "ext", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文件 MIME 类型", + "name": "mime", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/admin.PreCheckResp" + } + } + } + } + }, + "/admin/users": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Users" + ], + "summary": "用户列表", + "parameters": [ + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", "in": "query" }, { "type": "string", - "description": "名称", - "name": "name", + "name": "keyword", "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/models.User" + } + } + } + ] + } + } + } + } + }, + "/admin/users/{id}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Users" + ], + "summary": "用户详情", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "用户 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/models.User" + } + } + } + } + }, + "/admin/users/{id}/articles": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Admin Users" + ], + "summary": "用户已购作品", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "用户 ID", + "name": "id", + "in": "path", + "required": true }, { "type": "integer", @@ -73,7 +642,357 @@ { "type": "object", "properties": { - "list": { + "items": { + "$ref": "#/definitions/models.Post" + } + } + } + ] + } + } + } + } + }, + "/admin/users/{id}/balance": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Admin Users" + ], + "summary": "调整用户余额", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "用户 ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "请求体", + "name": "balance", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.UserBalance" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/posts": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Posts" + ], + "summary": "作品列表", + "parameters": [ + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "name": "keyword", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/http.PostItem" + } + } + } + ] + } + } + } + } + }, + "/posts/mine": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Posts" + ], + "summary": "我的已购作品", + "parameters": [ + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "name": "keyword", + "in": "query" + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/http.PostItem" + } + } + } + ] + } + } + } + } + }, + "/posts/{id}/buy": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "Posts" + ], + "summary": "购买作品", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功(余额支付返回 AppId=balance)", + "schema": { + "$ref": "#/definitions/wechat.JSAPIPayParams" + } + } + } + } + }, + "/posts/{id}/play": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Posts" + ], + "summary": "获取播放地址", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/http.PlayUrl" + } + } + } + } + }, + "/posts/{id}/show": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Posts" + ], + "summary": "作品详情", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "作品 ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/http.PostItem" + } + } + } + } + }, + "/users/profile": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "获取个人信息", + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/http.UserInfo" + } + } + } + } + }, + "/users/username": { + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "修改用户名", + "parameters": [ + { + "description": "请求体", + "name": "form", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/http.ProfileForm" + } + } + ], + "responses": { + "200": { + "description": "成功", + "schema": {} + } + } + } + }, + "/v1/medias/{id}": { + "post": { + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Demo" + ], + "summary": "演示接口", + "parameters": [ + { + "type": "integer", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键词", + "name": "search", + "in": "query" + }, + { + "type": "string", + "description": "内容类型", + "name": "Content-Type", + "in": "header" + }, + { + "type": "string", + "description": "上传到指定文件夹", + "name": "folder", + "in": "formData" + }, + { + "type": "file", + "description": "上传文件", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/requests.Pager" + }, + { + "type": "object", + "properties": { + "items": { "$ref": "#/definitions/v1.ResponseItem" } } @@ -86,6 +1005,467 @@ } }, "definitions": { + "admin.AuthBody": { + "type": "object", + "required": [ + "password", + "username" + ], + "properties": { + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "admin.PostForm": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "discount": { + "type": "integer" + }, + "head_images": { + "type": "array", + "items": { + "type": "integer" + } + }, + "introduction": { + "type": "string" + }, + "medias": { + "type": "array", + "items": { + "type": "integer" + } + }, + "price": { + "type": "integer" + }, + "status": { + "$ref": "#/definitions/fields.PostStatus" + }, + "title": { + "type": "string" + } + } + }, + "admin.PostItem": { + "type": "object", + "properties": { + "assets": { + "$ref": "#/definitions/types.JSONType-array_fields_MediaAsset" + }, + "bought_count": { + "type": "integer" + }, + "content": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "$ref": "#/definitions/gorm.DeletedAt" + }, + "description": { + "type": "string" + }, + "discount": { + "type": "integer" + }, + "head_images": { + "$ref": "#/definitions/types.JSONType-array_int64" + }, + "id": { + "type": "integer" + }, + "likes": { + "type": "integer" + }, + "medias": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Media" + } + }, + "price": { + "type": "integer" + }, + "status": { + "$ref": "#/definitions/fields.PostStatus" + }, + "tags": { + "$ref": "#/definitions/types.JSONType-array_string" + }, + "title": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "views": { + "type": "integer" + } + } + }, + "admin.PostUploadedForm": { + "type": "object", + "properties": { + "md5": { + "type": "string" + }, + "mimeType": { + "type": "string" + }, + "originalName": { + "type": "string" + }, + "size": { + "type": "integer" + } + } + }, + "admin.PreCheckResp": { + "type": "object", + "properties": { + "exists": { + "type": "boolean" + }, + "pre_sign": { + "$ref": "#/definitions/oss.PresignResult" + } + } + }, + "admin.StatisticsResponse": { + "type": "object", + "properties": { + "amount": { + "type": "integer" + }, + "media": { + "type": "integer" + }, + "order": { + "type": "integer" + }, + "post_draft": { + "type": "integer" + }, + "post_published": { + "type": "integer" + }, + "user": { + "type": "integer" + } + } + }, + "admin.TokenResponse": { + "type": "object", + "properties": { + "token": { + "type": "string" + } + } + }, + "admin.UserBalance": { + "type": "object", + "properties": { + "balance": { + "type": "integer" + } + } + }, + "fields.OrderStatus": { + "type": "integer", + "format": "int32", + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "x-enum-varnames": [ + "OrderStatusPending", + "OrderStatusPaid", + "OrderStatusRefundSuccess", + "OrderStatusRefundClosed", + "OrderStatusRefundProcessing", + "OrderStatusRefundAbnormal", + "OrderStatusCancelled", + "OrderStatusCompleted" + ] + }, + "fields.PostStatus": { + "type": "integer", + "format": "int32", + "enum": [ + 0, + 1 + ], + "x-enum-varnames": [ + "PostStatusDraft", + "PostStatusPublished" + ] + }, + "fields.UserStatus": { + "type": "integer", + "format": "int32", + "enum": [ + 0, + 1, + 2 + ], + "x-enum-varnames": [ + "UserStatusOk", + "UserStatusBanned", + "UserStatusBlocked" + ] + }, + "gorm.DeletedAt": { + "type": "object", + "properties": { + "time": { + "type": "string" + }, + "valid": { + "description": "Valid is true if Time is not NULL", + "type": "boolean" + } + } + }, + "http.PlayUrl": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + } + }, + "http.PostItem": { + "type": "object", + "properties": { + "bought": { + "type": "boolean" + }, + "content": { + "type": "string" + }, + "description": { + "type": "string" + }, + "discount": { + "type": "integer" + }, + "head_images": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "integer" + }, + "likes": { + "type": "integer" + }, + "price": { + "type": "integer" + }, + "recharge_wechat": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "title": { + "type": "string" + }, + "views": { + "type": "integer" + } + } + }, + "http.ProfileForm": { + "type": "object", + "required": [ + "username" + ], + "properties": { + "username": { + "type": "string" + } + } + }, + "http.UserInfo": { + "type": "object", + "properties": { + "avatar": { + "type": "string" + }, + "balance": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "username": { + "type": "string" + } + } + }, + "models.Media": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "metas": { + "$ref": "#/definitions/types.JSONType-fields_MediaMetas" + }, + "mime_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "size": { + "type": "integer" + } + } + }, + "models.Post": { + "type": "object", + "properties": { + "assets": { + "$ref": "#/definitions/types.JSONType-array_fields_MediaAsset" + }, + "content": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "$ref": "#/definitions/gorm.DeletedAt" + }, + "description": { + "type": "string" + }, + "discount": { + "type": "integer" + }, + "head_images": { + "$ref": "#/definitions/types.JSONType-array_int64" + }, + "id": { + "type": "integer" + }, + "likes": { + "type": "integer" + }, + "price": { + "type": "integer" + }, + "status": { + "$ref": "#/definitions/fields.PostStatus" + }, + "tags": { + "$ref": "#/definitions/types.JSONType-array_string" + }, + "title": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "views": { + "type": "integer" + } + } + }, + "models.User": { + "type": "object", + "properties": { + "auth_token": { + "$ref": "#/definitions/types.JSONType-fields_UserAuthToken" + }, + "avatar": { + "type": "string" + }, + "balance": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "$ref": "#/definitions/gorm.DeletedAt" + }, + "id": { + "type": "integer" + }, + "metas": { + "$ref": "#/definitions/types.JSONType-fields_UserMetas" + }, + "open_id": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/fields.UserStatus" + }, + "updated_at": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "oss.PresignResult": { + "type": "object", + "properties": { + "expiration": { + "type": "string" + }, + "method": { + "type": "string" + }, + "signedHeaders": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "url": { + "type": "string" + } + } + }, "requests.Pager": { "type": "object", "properties": { @@ -101,8 +1481,108 @@ } } }, + "services.OrderListItem": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "currency": { + "type": "string" + }, + "discount": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "meta": { + "$ref": "#/definitions/types.JSONType-fields_OrderMeta" + }, + "order_no": { + "type": "string" + }, + "payment_method": { + "type": "string" + }, + "post_id": { + "type": "integer" + }, + "post_title": { + "type": "string" + }, + "price": { + "type": "integer" + }, + "refund_transaction_id": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/fields.OrderStatus" + }, + "sub_order_no": { + "type": "string" + }, + "transaction_id": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "user_id": { + "type": "integer" + }, + "username": { + "type": "string" + } + } + }, + "types.JSONType-array_fields_MediaAsset": { + "type": "object" + }, + "types.JSONType-array_int64": { + "type": "object" + }, + "types.JSONType-array_string": { + "type": "object" + }, + "types.JSONType-fields_MediaMetas": { + "type": "object" + }, + "types.JSONType-fields_OrderMeta": { + "type": "object" + }, + "types.JSONType-fields_UserAuthToken": { + "type": "object" + }, + "types.JSONType-fields_UserMetas": { + "type": "object" + }, "v1.ResponseItem": { "type": "object" + }, + "wechat.JSAPIPayParams": { + "type": "object", + "properties": { + "appId": { + "type": "string" + }, + "nonceStr": { + "type": "string" + }, + "package": { + "type": "string" + }, + "paySign": { + "type": "string" + }, + "signType": { + "type": "string" + }, + "timeStamp": { + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/backend_v1/docs/swagger.yaml b/backend_v1/docs/swagger.yaml index f9f7516..dfa2f40 100644 --- a/backend_v1/docs/swagger.yaml +++ b/backend_v1/docs/swagger.yaml @@ -1,5 +1,315 @@ basePath: /api/v1 definitions: + admin.AuthBody: + properties: + password: + type: string + username: + type: string + required: + - password + - username + type: object + admin.PostForm: + properties: + content: + type: string + discount: + type: integer + head_images: + items: + type: integer + type: array + introduction: + type: string + medias: + items: + type: integer + type: array + price: + type: integer + status: + $ref: '#/definitions/fields.PostStatus' + title: + type: string + type: object + admin.PostItem: + properties: + assets: + $ref: '#/definitions/types.JSONType-array_fields_MediaAsset' + bought_count: + type: integer + content: + type: string + created_at: + type: string + deleted_at: + $ref: '#/definitions/gorm.DeletedAt' + description: + type: string + discount: + type: integer + head_images: + $ref: '#/definitions/types.JSONType-array_int64' + id: + type: integer + likes: + type: integer + medias: + items: + $ref: '#/definitions/models.Media' + type: array + price: + type: integer + status: + $ref: '#/definitions/fields.PostStatus' + tags: + $ref: '#/definitions/types.JSONType-array_string' + title: + type: string + updated_at: + type: string + views: + type: integer + type: object + admin.PostUploadedForm: + properties: + md5: + type: string + mimeType: + type: string + originalName: + type: string + size: + type: integer + type: object + admin.PreCheckResp: + properties: + exists: + type: boolean + pre_sign: + $ref: '#/definitions/oss.PresignResult' + type: object + admin.StatisticsResponse: + properties: + amount: + type: integer + media: + type: integer + order: + type: integer + post_draft: + type: integer + post_published: + type: integer + user: + type: integer + type: object + admin.TokenResponse: + properties: + token: + type: string + type: object + admin.UserBalance: + properties: + balance: + type: integer + type: object + fields.OrderStatus: + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + format: int32 + type: integer + x-enum-varnames: + - OrderStatusPending + - OrderStatusPaid + - OrderStatusRefundSuccess + - OrderStatusRefundClosed + - OrderStatusRefundProcessing + - OrderStatusRefundAbnormal + - OrderStatusCancelled + - OrderStatusCompleted + fields.PostStatus: + enum: + - 0 + - 1 + format: int32 + type: integer + x-enum-varnames: + - PostStatusDraft + - PostStatusPublished + fields.UserStatus: + enum: + - 0 + - 1 + - 2 + format: int32 + type: integer + x-enum-varnames: + - UserStatusOk + - UserStatusBanned + - UserStatusBlocked + gorm.DeletedAt: + properties: + time: + type: string + valid: + description: Valid is true if Time is not NULL + type: boolean + type: object + http.PlayUrl: + properties: + url: + type: string + type: object + http.PostItem: + properties: + bought: + type: boolean + content: + type: string + description: + type: string + discount: + type: integer + head_images: + items: + type: string + type: array + id: + type: integer + likes: + type: integer + price: + type: integer + recharge_wechat: + type: string + tags: + items: + type: string + type: array + title: + type: string + views: + type: integer + type: object + http.ProfileForm: + properties: + username: + type: string + required: + - username + type: object + http.UserInfo: + properties: + avatar: + type: string + balance: + type: integer + created_at: + type: string + id: + type: integer + username: + type: string + type: object + models.Media: + properties: + created_at: + type: string + hash: + type: string + id: + type: integer + metas: + $ref: '#/definitions/types.JSONType-fields_MediaMetas' + mime_type: + type: string + name: + type: string + path: + type: string + size: + type: integer + type: object + models.Post: + properties: + assets: + $ref: '#/definitions/types.JSONType-array_fields_MediaAsset' + content: + type: string + created_at: + type: string + deleted_at: + $ref: '#/definitions/gorm.DeletedAt' + description: + type: string + discount: + type: integer + head_images: + $ref: '#/definitions/types.JSONType-array_int64' + id: + type: integer + likes: + type: integer + price: + type: integer + status: + $ref: '#/definitions/fields.PostStatus' + tags: + $ref: '#/definitions/types.JSONType-array_string' + title: + type: string + updated_at: + type: string + views: + type: integer + type: object + models.User: + properties: + auth_token: + $ref: '#/definitions/types.JSONType-fields_UserAuthToken' + avatar: + type: string + balance: + type: integer + created_at: + type: string + deleted_at: + $ref: '#/definitions/gorm.DeletedAt' + id: + type: integer + metas: + $ref: '#/definitions/types.JSONType-fields_UserMetas' + open_id: + type: string + status: + $ref: '#/definitions/fields.UserStatus' + updated_at: + type: string + username: + type: string + type: object + oss.PresignResult: + properties: + expiration: + type: string + method: + type: string + signedHeaders: + additionalProperties: + type: string + type: object + url: + type: string + type: object requests.Pager: properties: items: {} @@ -10,8 +320,74 @@ definitions: total: type: integer type: object + services.OrderListItem: + properties: + created_at: + type: string + currency: + type: string + discount: + type: integer + id: + type: integer + meta: + $ref: '#/definitions/types.JSONType-fields_OrderMeta' + order_no: + type: string + payment_method: + type: string + post_id: + type: integer + post_title: + type: string + price: + type: integer + refund_transaction_id: + type: string + status: + $ref: '#/definitions/fields.OrderStatus' + sub_order_no: + type: string + transaction_id: + type: string + updated_at: + type: string + user_id: + type: integer + username: + type: string + type: object + types.JSONType-array_fields_MediaAsset: + type: object + types.JSONType-array_int64: + type: object + types.JSONType-array_string: + type: object + types.JSONType-fields_MediaMetas: + type: object + types.JSONType-fields_OrderMeta: + type: object + types.JSONType-fields_UserAuthToken: + type: object + types.JSONType-fields_UserMetas: + type: object v1.ResponseItem: type: object + wechat.JSAPIPayParams: + properties: + appId: + type: string + nonceStr: + type: string + package: + type: string + paySign: + type: string + signType: + type: string + timeStamp: + type: string + type: object externalDocs: description: OpenAPI url: https://swagger.io/resources/open-api/ @@ -29,25 +405,382 @@ info: title: ApiDoc version: "1.0" paths: - /v1/medias/{id}: + /admin/auth: post: consumes: - application/json - description: Test parameters: - - description: ID + - description: 请求体 + in: body + name: body + required: true + schema: + $ref: '#/definitions/admin.AuthBody' + produces: + - application/json + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/admin.TokenResponse' + summary: 管理员登录 + tags: + - Admin Auth + /admin/medias: + get: + parameters: + - in: query + name: limit + type: integer + - in: query + name: page + type: integer + - in: query + name: keyword + type: string + produces: + - application/json + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/requests.Pager' + - properties: + items: + $ref: '#/definitions/models.Media' + type: object + summary: 媒体列表 + tags: + - Admin Medias + /admin/medias/{id}: + delete: + parameters: + - description: 媒体 ID + format: int64 in: path name: id required: true type: integer - - description: 年龄 - in: query - name: age + produces: + - application/json + responses: + "204": + description: 成功 + schema: {} + summary: 删除媒体 + tags: + - Admin Medias + get: + parameters: + - description: 媒体 ID + format: int64 + in: path + name: id + required: true type: integer - - description: 名称 - in: query - name: name + responses: + "302": + description: 跳转 + schema: + type: string + summary: 媒体预览(跳转到签名 URL) + tags: + - Admin Medias + /admin/orders: + get: + parameters: + - in: query + name: limit + type: integer + - in: query + name: page + type: integer + - in: query + name: orderNumber type: string + - in: query + name: userID + type: integer + produces: + - application/json + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/requests.Pager' + - properties: + items: + $ref: '#/definitions/services.OrderListItem' + type: object + summary: 订单列表 + tags: + - Admin Orders + /admin/orders/{id}/refund: + post: + parameters: + - description: 订单 ID + format: int64 + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 成功 + schema: {} + summary: 订单退款 + tags: + - Admin Orders + /admin/posts: + get: + parameters: + - in: query + name: limit + type: integer + - in: query + name: page + type: integer + - in: query + name: keyword + type: string + produces: + - application/json + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/requests.Pager' + - properties: + items: + $ref: '#/definitions/admin.PostItem' + type: object + summary: 作品列表 + tags: + - Admin Posts + post: + consumes: + - application/json + parameters: + - description: 请求体 + in: body + name: form + required: true + schema: + $ref: '#/definitions/admin.PostForm' + produces: + - application/json + responses: + "200": + description: 成功 + schema: {} + summary: 创建作品 + tags: + - Admin Posts + /admin/posts/{id}: + delete: + parameters: + - description: 作品 ID + format: int64 + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "204": + description: 成功 + schema: {} + summary: 删除作品 + tags: + - Admin Posts + get: + parameters: + - description: 作品 ID + format: int64 + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/admin.PostItem' + summary: 作品详情 + tags: + - Admin Posts + put: + consumes: + - application/json + parameters: + - description: 作品 ID + format: int64 + in: path + name: id + required: true + type: integer + - description: 请求体 + in: body + name: form + required: true + schema: + $ref: '#/definitions/admin.PostForm' + produces: + - application/json + responses: + "200": + description: 成功 + schema: {} + summary: 更新作品 + tags: + - Admin Posts + /admin/posts/{id}/send-to/{userId}: + post: + parameters: + - description: 作品 ID + format: int64 + in: path + name: id + required: true + type: integer + - description: 用户 ID + format: int64 + in: path + name: userId + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 成功 + schema: {} + summary: 赠送作品给用户 + tags: + - Admin Posts + /admin/statistics: + get: + produces: + - application/json + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/admin.StatisticsResponse' + summary: 仪表盘统计 + tags: + - Admin Statistics + /admin/uploads/post-uploaded-action: + post: + consumes: + - application/json + parameters: + - description: 请求体 + in: body + name: body + required: true + schema: + $ref: '#/definitions/admin.PostUploadedForm' + produces: + - application/json + responses: + "200": + description: 成功 + schema: {} + summary: 上传完成回调处理 + tags: + - Admin Uploads + /admin/uploads/pre-uploaded-check/{md5}.{ext}: + get: + parameters: + - description: 文件 MD5 + in: path + name: md5 + required: true + type: string + - description: 文件扩展名(不含点) + in: path + name: ext + required: true + type: string + - description: 文件 MIME 类型 + in: query + name: mime + required: true + type: string + produces: + - application/json + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/admin.PreCheckResp' + summary: 预上传检查 + tags: + - Admin Uploads + /admin/users: + get: + parameters: + - in: query + name: limit + type: integer + - in: query + name: page + type: integer + - in: query + name: keyword + type: string + produces: + - application/json + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/requests.Pager' + - properties: + items: + $ref: '#/definitions/models.User' + type: object + summary: 用户列表 + tags: + - Admin Users + /admin/users/{id}: + get: + parameters: + - description: 用户 ID + format: int64 + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/models.User' + summary: 用户详情 + tags: + - Admin Users + /admin/users/{id}/articles: + get: + parameters: + - description: 用户 ID + format: int64 + in: path + name: id + required: true + type: integer - in: query name: limit type: integer @@ -63,12 +796,229 @@ paths: allOf: - $ref: '#/definitions/requests.Pager' - properties: - list: + items: + $ref: '#/definitions/models.Post' + type: object + summary: 用户已购作品 + tags: + - Admin Users + /admin/users/{id}/balance: + post: + consumes: + - application/json + parameters: + - description: 用户 ID + format: int64 + in: path + name: id + required: true + type: integer + - description: 请求体 + in: body + name: balance + required: true + schema: + $ref: '#/definitions/admin.UserBalance' + produces: + - application/json + responses: + "200": + description: 成功 + schema: {} + summary: 调整用户余额 + tags: + - Admin Users + /posts: + get: + parameters: + - in: query + name: limit + type: integer + - in: query + name: page + type: integer + - in: query + name: keyword + type: string + produces: + - application/json + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/requests.Pager' + - properties: + items: + $ref: '#/definitions/http.PostItem' + type: object + summary: 作品列表 + tags: + - Posts + /posts/{id}/buy: + post: + parameters: + - description: 作品 ID + format: int64 + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 成功(余额支付返回 AppId=balance) + schema: + $ref: '#/definitions/wechat.JSAPIPayParams' + summary: 购买作品 + tags: + - Posts + /posts/{id}/play: + get: + parameters: + - description: 作品 ID + format: int64 + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/http.PlayUrl' + summary: 获取播放地址 + tags: + - Posts + /posts/{id}/show: + get: + parameters: + - description: 作品 ID + format: int64 + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/http.PostItem' + summary: 作品详情 + tags: + - Posts + /posts/mine: + get: + parameters: + - in: query + name: limit + type: integer + - in: query + name: page + type: integer + - in: query + name: keyword + type: string + produces: + - application/json + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/requests.Pager' + - properties: + items: + $ref: '#/definitions/http.PostItem' + type: object + summary: 我的已购作品 + tags: + - Posts + /users/profile: + get: + produces: + - application/json + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/http.UserInfo' + summary: 获取个人信息 + tags: + - Users + /users/username: + put: + consumes: + - application/json + parameters: + - description: 请求体 + in: body + name: form + required: true + schema: + $ref: '#/definitions/http.ProfileForm' + produces: + - application/json + responses: + "200": + description: 成功 + schema: {} + summary: 修改用户名 + tags: + - Users + /v1/medias/{id}: + post: + consumes: + - multipart/form-data + parameters: + - description: ID + in: path + name: id + required: true + type: integer + - in: query + name: limit + type: integer + - in: query + name: page + type: integer + - description: 搜索关键词 + in: query + name: search + type: string + - description: 内容类型 + in: header + name: Content-Type + type: string + - description: 上传到指定文件夹 + in: formData + name: folder + type: string + - description: 上传文件 + in: formData + name: file + required: true + type: file + produces: + - application/json + responses: + "200": + description: 成功 + schema: + allOf: + - $ref: '#/definitions/requests.Pager' + - properties: + items: $ref: '#/definitions/v1.ResponseItem' type: object - summary: Test + summary: 演示接口 tags: - - Test + - Demo securityDefinitions: BasicAuth: type: basic