diff --git a/README.md b/README.md index 2303ee4..e90be5b 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ const credential = await qdmp.auth.getUserAccessToken(code) // 调业务接口:accessToken 每次显式传进去 const me = await qdmp.user.me({ accessToken: credential.accessToken }) await qdmp.mark.add({ accessToken: credential.accessToken }, { spuId: '123', rating: { value: 5 } }) +await qdmp.mark.batchAdd({ accessToken: credential.accessToken }, { spuIds: ['123', '456'] }) +await qdmp.comment.create({ accessToken: credential.accessToken }, { postId: '123', content: '很喜欢' }) // accessToken 过期了,自己拿 refreshToken 换新的(SDK 不代管,也不自动重试) const fresh = await qdmp.auth.refreshToken(credential.refreshToken) @@ -123,7 +125,7 @@ appCredential, err := client.Auth.GetAppAccessToken(ctx) | 分组 | 要求 | |---|---| | `auth.*` | 不需要凭证(用 appId/appSecret 或 refreshToken) | -| `user.me` / `mark.*` / `wishspu.*` | 必须是用户授权凭证,缺失时本地直接报错,不发请求 | +| `user.me` / `mark.*` / `wishspu.*` / `post.*` / `comment.*` | 必须是用户授权凭证,缺失时本地直接报错,不发请求 | | `island.*` / `spu.*` / `tag.*` / `genai.*` | 应用凭证也实测调通过,但 SDK 不做静默 fallback,传哪种由调用方决定 | `x-echo-qdmp-version` 头只在 `standard` 鉴权方案下发送,`genai` 分组用 `x-openapi-access-token` + `x-openapi-app-id` 另一对头,`auth` 分组不需要——三端都从 `shared/generated/route-meta.json` 读取每个 operation 的 `authScheme`/`tokenRequired`。 diff --git a/go/auth_contract_matrix_test.go b/go/auth_contract_matrix_test.go index 3d3d1fd..fe1c2d7 100644 --- a/go/auth_contract_matrix_test.go +++ b/go/auth_contract_matrix_test.go @@ -26,6 +26,7 @@ import ( "net/http" "os" "sort" + "strings" "sync" "testing" @@ -158,6 +159,41 @@ func allBusinessOps() []businessOp { _, err := c.Mark.Add(ctx, q, generated.MarkAddJSONBody{SpuId: "123"}) return err }}, + {"markBatchAdd", func(c *qdmp.Client, ctx context.Context, q qdmp.Context) error { + _, err := c.Mark.BatchAdd(ctx, q, generated.MarkBatchAddJSONRequestBody{SpuIds: []string{"1"}}) + return err + }}, + {"postDetail", func(c *qdmp.Client, ctx context.Context, q qdmp.Context) error { + _, err := c.Post.Detail(ctx, q, "1") + return err + }}, + {"postList", func(c *qdmp.Client, ctx context.Context, q qdmp.Context) error { + _, err := c.Post.List(ctx, q, generated.PostListParams{}) + return err + }}, + {"postMyList", func(c *qdmp.Client, ctx context.Context, q qdmp.Context) error { + _, err := c.Post.MyList(ctx, q, generated.PostMyListParams{}) + return err + }}, + {"commentCreate", func(c *qdmp.Client, ctx context.Context, q qdmp.Context) error { + _, err := c.Comment.Create(ctx, q, generated.CommentCreateJSONRequestBody{PostId: "1", Content: "ok"}) + return err + }}, + {"commentReply", func(c *qdmp.Client, ctx context.Context, q qdmp.Context) error { + _, err := c.Comment.Reply(ctx, q, "1", generated.CommentReplyJSONRequestBody{Content: "ok"}) + return err + }}, + {"commentLike", func(c *qdmp.Client, ctx context.Context, q qdmp.Context) error { + return c.Comment.Like(ctx, q, "1", generated.CommentLikeJSONRequestBody{Liked: true}) + }}, + {"postComments", func(c *qdmp.Client, ctx context.Context, q qdmp.Context) error { + _, err := c.Comment.PostComments(ctx, q, "1", generated.PostCommentsParams{}) + return err + }}, + {"commentReplies", func(c *qdmp.Client, ctx context.Context, q qdmp.Context) error { + _, err := c.Comment.Replies(ctx, q, "1", generated.CommentRepliesParams{}) + return err + }}, {"markList", func(c *qdmp.Client, ctx context.Context, q qdmp.Context) error { _, err := c.Mark.List(ctx, q, generated.MarkListParams{Limit: "20", Offset: "0"}) return err @@ -283,7 +319,12 @@ func TestBusinessOps_TokenComesFromPerCallContext(t *testing.T) { // The table row must actually call the endpoint route-meta says it // does, otherwise a mis-wired row could satisfy the header check // while exercising a different operation entirely. - if method != route.Method || path != route.Path { + pathMatches := path == route.Path + if open := strings.Index(route.Path, "{"); open >= 0 { + close := strings.Index(route.Path[open:], "}") + pathMatches = close > 0 && strings.HasPrefix(path, route.Path[:open]) && strings.HasSuffix(path, route.Path[open+close+1:]) + } + if method != route.Method || !pathMatches { t.Fatalf("%s called %s %s, want %s %s per %s", op.operationID, method, path, route.Method, route.Path, routeMetaPath) } @@ -328,6 +369,14 @@ func TestBusinessOps_EmptyContextFailsLocally(t *testing.T) { if !errors.Is(err, qdmp.ErrAccessTokenRequired) { t.Fatalf("%s error = %v, want errors.Is(..., ErrAccessTokenRequired)", op.operationID, err) } + requireSpecificOperationName := map[string]bool{ + "postDetail": true, "postList": true, "postMyList": true, + "commentCreate": true, "commentReply": true, "commentLike": true, + "postComments": true, "commentReplies": true, + } + if requireSpecificOperationName[op.operationID] && !strings.Contains(err.Error(), op.operationID) { + t.Fatalf("%s error = %q, want operationId in missing-token message", op.operationID, err) + } if errors.Is(err, qdmp.ErrInvalidAccessToken) { t.Fatalf("%s: a missing token must not be reported as ErrInvalidAccessToken (err = %v)", op.operationID, err) diff --git a/go/client.go b/go/client.go index 095762a..fc18a16 100644 --- a/go/client.go +++ b/go/client.go @@ -81,6 +81,8 @@ type Client struct { Spu *SpuGroup Tag *TagGroup Mark *MarkGroup + Post *PostGroup + Comment *CommentGroup WishSpu *WishSpuGroup GenAI *GenAIGroup } @@ -146,6 +148,8 @@ func NewClient(opts ClientOptions) (*Client, error) { c.Spu = &SpuGroup{client: c} c.Tag = &TagGroup{client: c} c.Mark = &MarkGroup{client: c} + c.Post = &PostGroup{client: c} + c.Comment = &CommentGroup{client: c} c.WishSpu = &WishSpuGroup{client: c} c.GenAI = &GenAIGroup{client: c} return c, nil diff --git a/go/comment.go b/go/comment.go new file mode 100644 index 0000000..bfe1975 --- /dev/null +++ b/go/comment.go @@ -0,0 +1,130 @@ +package qdmp + +import ( + "context" + "encoding/json" + "fmt" + "github.com/EchoTechFE/qdmp-server-sdk/go/generated" + "net/http" + "net/url" + "regexp" +) + +type CommentGroup struct{ client *Client } + +var positiveIDPattern = regexp.MustCompile(`^[1-9][0-9]*$`) + +// CommentCreateResult is the identifier returned after creating a comment or reply. +type CommentCreateResult struct { + ID string `json:"id"` +} + +// PostCommentsResult is a page of top-level comments and their first replies. +type PostCommentsResult struct { + Items []generated.CommentThread `json:"items"` + Count int32 `json:"count"` +} + +// CommentRepliesResult is a cursor page of replies to a top-level comment. +type CommentRepliesResult struct { + Items []generated.CommentItem `json:"items"` + HasMore bool `json:"hasMore"` + Cursor string `json:"cursor"` + Count int32 `json:"count"` +} + +func (g *CommentGroup) Create(ctx context.Context, q Context, b generated.CommentCreateJSONRequestBody) (*CommentCreateResult, error) { + return g.postID(ctx, q, "commentCreate", "/comment", b) +} +func (g *CommentGroup) Reply(ctx context.Context, q Context, id string, b generated.CommentReplyJSONRequestBody) (*CommentCreateResult, error) { + if err := requireAccessToken(q, "commentReply"); err != nil { + return nil, err + } + if err := validatePositiveID("commentId", id); err != nil { + return nil, err + } + return g.postID(ctx, q, "commentReply", "/comment/"+id+"/reply", b) +} +func (g *CommentGroup) Like(ctx context.Context, q Context, id string, b generated.CommentLikeJSONRequestBody) error { + if err := requireAccessToken(q, "commentLike"); err != nil { + return err + } + if err := validatePositiveID("commentId", id); err != nil { + return err + } + _, err := g.client.doRequest(ctx, requestParams{method: http.MethodPost, path: "/comment/" + url.PathEscape(id) + "/like", jsonBody: b, authScheme: authSchemeStandard, accessToken: q.AccessToken}) + return err +} + +// PostComments returns top-level comments and their first replies for a post. +func (g *CommentGroup) PostComments(ctx context.Context, q Context, postID string, params generated.PostCommentsParams) (*PostCommentsResult, error) { + if err := requireAccessToken(q, "postComments"); err != nil { + return nil, err + } + if err := validatePositiveID("postId", postID); err != nil { + return nil, err + } + query := url.Values{} + if params.Limit != nil { + query.Set("limit", *params.Limit) + } + if params.Offset != nil { + query.Set("offset", *params.Offset) + } + data, err := g.client.doRequest(ctx, requestParams{method: http.MethodGet, path: "/post/" + postID + "/comments", query: query, authScheme: authSchemeStandard, accessToken: q.AccessToken}) + if err != nil { + return nil, err + } + var result PostCommentsResult + if err := json.Unmarshal(data, &result); err != nil { + return nil, fmt.Errorf("qdmp: decode post comments response: %w", err) + } + return &result, nil +} + +// Replies returns a page of replies for a top-level comment. +func (g *CommentGroup) Replies(ctx context.Context, q Context, commentID string, params generated.CommentRepliesParams) (*CommentRepliesResult, error) { + if err := requireAccessToken(q, "commentReplies"); err != nil { + return nil, err + } + if err := validatePositiveID("commentId", commentID); err != nil { + return nil, err + } + query := url.Values{} + if params.Limit != nil { + query.Set("limit", *params.Limit) + } + if params.Cursor != nil { + query.Set("cursor", *params.Cursor) + } + data, err := g.client.doRequest(ctx, requestParams{method: http.MethodGet, path: "/comment/" + commentID + "/replies", query: query, authScheme: authSchemeStandard, accessToken: q.AccessToken}) + if err != nil { + return nil, err + } + var result CommentRepliesResult + if err := json.Unmarshal(data, &result); err != nil { + return nil, fmt.Errorf("qdmp: decode comment replies response: %w", err) + } + return &result, nil +} +func (g *CommentGroup) postID(ctx context.Context, q Context, operationID, path string, b any) (*CommentCreateResult, error) { + if err := requireAccessToken(q, operationID); err != nil { + return nil, err + } + data, err := g.client.doRequest(ctx, requestParams{method: http.MethodPost, path: path, jsonBody: b, authScheme: authSchemeStandard, accessToken: q.AccessToken}) + if err != nil { + return nil, err + } + var v CommentCreateResult + if err = json.Unmarshal(data, &v); err != nil { + return nil, fmt.Errorf("qdmp: decode comment response: %w", err) + } + return &v, nil +} + +func validatePositiveID(name, value string) error { + if !positiveIDPattern.MatchString(value) { + return fmt.Errorf("qdmp: %s must be a positive integer ID", name) + } + return nil +} diff --git a/go/generated/types.gen.go b/go/generated/types.gen.go index d5b03c5..ec730de 100644 --- a/go/generated/types.gen.go +++ b/go/generated/types.gen.go @@ -82,18 +82,281 @@ func (e WishCancelJSONBodyType) Valid() bool { } } +// BusinessEnvelopeBase 业务信封基础结构 {code, message, requestId, data}(data 由各 operation 的响应单独描述)。实测确认:code 字段类型不统一,见过数字(0/10008/20000等)也见过字符串("0");且不保证 HTTP 200 即代表业务成功——例如 refreshToken 过期时是 HTTP 200 + code=10008,而 access-token 缺失/非法则是真实 HTTP 401 + code=10005。调用方必须显式检查 code 字段,不能只信任 HTTP 状态码。 +type BusinessEnvelopeBase struct { + // Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 + Code BusinessEnvelopeBase_Code `json:"code"` + + // Message 人类可读的提示信息 + Message string `json:"message"` + + // RequestId 请求追踪 ID + RequestId *string `json:"requestId,omitempty"` +} + +// BusinessEnvelopeBaseCode0 defines model for BusinessEnvelopeBase.Code.0. +type BusinessEnvelopeBaseCode0 = int + +// BusinessEnvelopeBaseCode1 defines model for BusinessEnvelopeBase.Code.1. +type BusinessEnvelopeBaseCode1 = string + +// BusinessEnvelopeBase_Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 +type BusinessEnvelopeBase_Code struct { + union json.RawMessage +} + +// CommentCreateRequest 创建帖子评论。 +type CommentCreateRequest struct { + Content string `json:"content"` + + // PostId 帖子 ID;源接口为 int64,在线格式为 string,值必须大于 0。 + PostId string `json:"postId"` +} + +// CommentCreateResponse defines model for CommentCreateResponse. +type CommentCreateResponse struct { + // Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 + Code CommentCreateResponse_Code `json:"code"` + Data *struct { + Id *string `json:"id,omitempty"` + } `json:"data,omitempty"` + + // Message 人类可读的提示信息 + Message string `json:"message"` + + // RequestId 请求追踪 ID + RequestId *string `json:"requestId,omitempty"` +} + +// CommentCreateResponseCode0 defines model for CommentCreateResponse.Code.0. +type CommentCreateResponseCode0 = int + +// CommentCreateResponseCode1 defines model for CommentCreateResponse.Code.1. +type CommentCreateResponseCode1 = string + +// CommentCreateResponse_Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 +type CommentCreateResponse_Code struct { + union json.RawMessage +} + +// CommentItem defines model for CommentItem. +type CommentItem struct { + Content *string `json:"content,omitempty"` + CreatedAt *string `json:"createdAt,omitempty"` + Creator *map[string]interface{} `json:"creator,omitempty"` + Id *string `json:"id,omitempty"` + LikeCount *int32 `json:"likeCount,omitempty"` + Liked *bool `json:"liked,omitempty"` + ReplyCommentId *string `json:"replyCommentId,omitempty"` + ReplyToUser *map[string]interface{} `json:"replyToUser,omitempty"` + RootCommentId *string `json:"rootCommentId,omitempty"` +} + +// CommentLikeRequest defines model for CommentLikeRequest. +type CommentLikeRequest struct { + Liked bool `json:"liked"` +} + +// CommentRepliesResponse defines model for CommentRepliesResponse. +type CommentRepliesResponse struct { + // Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 + Code CommentRepliesResponse_Code `json:"code"` + Data *struct { + Count *int32 `json:"count,omitempty"` + Cursor *string `json:"cursor,omitempty"` + HasMore *bool `json:"hasMore,omitempty"` + Items *[]CommentItem `json:"items,omitempty"` + } `json:"data,omitempty"` + + // Message 人类可读的提示信息 + Message string `json:"message"` + + // RequestId 请求追踪 ID + RequestId *string `json:"requestId,omitempty"` +} + +// CommentRepliesResponseCode0 defines model for CommentRepliesResponse.Code.0. +type CommentRepliesResponseCode0 = int + +// CommentRepliesResponseCode1 defines model for CommentRepliesResponse.Code.1. +type CommentRepliesResponseCode1 = string + +// CommentRepliesResponse_Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 +type CommentRepliesResponse_Code struct { + union json.RawMessage +} + +// CommentReplyRequest 回复评论。 +type CommentReplyRequest struct { + Content string `json:"content"` +} + +// CommentThread defines model for CommentThread. +type CommentThread struct { + Comment *CommentItem `json:"comment,omitempty"` + Replies *[]CommentItem `json:"replies,omitempty"` + ReplyCount *int32 `json:"replyCount,omitempty"` +} + +// EmptyDataResponse defines model for EmptyDataResponse. +type EmptyDataResponse struct { + // Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 + Code EmptyDataResponse_Code `json:"code"` + Data *map[string]interface{} `json:"data,omitempty"` + + // Message 人类可读的提示信息 + Message string `json:"message"` + + // RequestId 请求追踪 ID + RequestId *string `json:"requestId,omitempty"` +} + +// EmptyDataResponseCode0 defines model for EmptyDataResponse.Code.0. +type EmptyDataResponseCode0 = int + +// EmptyDataResponseCode1 defines model for EmptyDataResponse.Code.1. +type EmptyDataResponseCode1 = string + +// EmptyDataResponse_Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 +type EmptyDataResponse_Code struct { + union json.RawMessage +} + +// GatewayErrorEnvelope 第二种错误信封:网关层错误,不含 data / requestId 字段,与业务信封结构不同。code 是类 gRPC 状态码的小整数,实测见过 13("query parse error")、2("openid is required")。这两个具体码是网关层示例,不属于顶层 x-error-codes 清单(那份清单专指业务信封的已知错误码)。HTTP 状态码未逐条验证。 +type GatewayErrorEnvelope struct { + // Code 类 gRPC 状态码,实测见过 2、13 + Code int `json:"code"` + + // Details 错误详情,具体结构未完全验证 + Details interface{} `json:"details,omitempty"` + Message string `json:"message"` +} + +// MarkBatchAddRequest 批量添加标记。 +type MarkBatchAddRequest struct { + // SpuIds SPU ID 列表;源接口为 int64[],在线格式为 string[]。 + SpuIds []string `json:"spuIds"` +} + +// MarkBatchAddResponse defines model for MarkBatchAddResponse. +type MarkBatchAddResponse struct { + // Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 + Code MarkBatchAddResponse_Code `json:"code"` + Data *struct { + Result *map[string]string `json:"result,omitempty"` + } `json:"data,omitempty"` + + // Message 人类可读的提示信息 + Message string `json:"message"` + + // RequestId 请求追踪 ID + RequestId *string `json:"requestId,omitempty"` +} + +// MarkBatchAddResponseCode0 defines model for MarkBatchAddResponse.Code.0. +type MarkBatchAddResponseCode0 = int + +// MarkBatchAddResponseCode1 defines model for MarkBatchAddResponse.Code.1. +type MarkBatchAddResponseCode1 = string + +// MarkBatchAddResponse_Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 +type MarkBatchAddResponse_Code struct { + union json.RawMessage +} + +// PostCommentsResponse defines model for PostCommentsResponse. +type PostCommentsResponse struct { + // Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 + Code PostCommentsResponse_Code `json:"code"` + Data *struct { + Count *int32 `json:"count,omitempty"` + Items *[]CommentThread `json:"items,omitempty"` + } `json:"data,omitempty"` + + // Message 人类可读的提示信息 + Message string `json:"message"` + + // RequestId 请求追踪 ID + RequestId *string `json:"requestId,omitempty"` +} + +// PostCommentsResponseCode0 defines model for PostCommentsResponse.Code.0. +type PostCommentsResponseCode0 = int + +// PostCommentsResponseCode1 defines model for PostCommentsResponse.Code.1. +type PostCommentsResponseCode1 = string + +// PostCommentsResponse_Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 +type PostCommentsResponse_Code struct { + union json.RawMessage +} + +// PostObjectResponse defines model for PostObjectResponse. +type PostObjectResponse struct { + // Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 + Code PostObjectResponse_Code `json:"code"` + Data *map[string]interface{} `json:"data,omitempty"` + + // Message 人类可读的提示信息 + Message string `json:"message"` + + // RequestId 请求追踪 ID + RequestId *string `json:"requestId,omitempty"` +} + +// PostObjectResponseCode0 defines model for PostObjectResponse.Code.0. +type PostObjectResponseCode0 = int + +// PostObjectResponseCode1 defines model for PostObjectResponse.Code.1. +type PostObjectResponseCode1 = string + +// PostObjectResponse_Code 业务状态码,0/"0" 通常表示成功,非零/非"0"表示业务错误。取值不是封闭枚举,已知码见顶层 x-error-codes。 +type PostObjectResponse_Code struct { + union json.RawMessage +} + // AccessTokenHeader defines model for AccessTokenHeader. type AccessTokenHeader = string +// CommentIdPath defines model for CommentIdPath. +type CommentIdPath = string + +// CursorQuery defines model for CursorQuery. +type CursorQuery = string + // GenaiAccessTokenHeader defines model for GenaiAccessTokenHeader. type GenaiAccessTokenHeader = string // GenaiAppIdHeader defines model for GenaiAppIdHeader. type GenaiAppIdHeader = string +// Limit100Query defines model for Limit100Query. +type Limit100Query = string + +// Limit20Query defines model for Limit20Query. +type Limit20Query = string + +// OffsetQuery defines model for OffsetQuery. +type OffsetQuery = string + +// PostIdPath defines model for PostIdPath. +type PostIdPath = string + +// PostIdQuery defines model for PostIdQuery. +type PostIdQuery = string + // QdmpVersionHeader defines model for QdmpVersionHeader. type QdmpVersionHeader = string +// GatewayErrorResponse 第二种错误信封:网关层错误,不含 data / requestId 字段,与业务信封结构不同。code 是类 gRPC 状态码的小整数,实测见过 13("query parse error")、2("openid is required")。这两个具体码是网关层示例,不属于顶层 x-error-codes 清单(那份清单专指业务信封的已知错误码)。HTTP 状态码未逐条验证。 +type GatewayErrorResponse = GatewayErrorEnvelope + +// NotFoundResponse 业务信封基础结构 {code, message, requestId, data}(data 由各 operation 的响应单独描述)。实测确认:code 字段类型不统一,见过数字(0/10008/20000等)也见过字符串("0");且不保证 HTTP 200 即代表业务成功——例如 refreshToken 过期时是 HTTP 200 + code=10008,而 access-token 缺失/非法则是真实 HTTP 401 + code=10005。调用方必须显式检查 code 字段,不能只信任 HTTP 状态码。 +type NotFoundResponse = BusinessEnvelopeBase + +// UnauthorizedResponse 业务信封基础结构 {code, message, requestId, data}(data 由各 operation 的响应单独描述)。实测确认:code 字段类型不统一,见过数字(0/10008/20000等)也见过字符串("0");且不保证 HTTP 200 即代表业务成功——例如 refreshToken 过期时是 HTTP 200 + code=10008,而 access-token 缺失/非法则是真实 HTTP 401 + code=10005。调用方必须显式检查 code 字段,不能只信任 HTTP 状态码。 +type UnauthorizedResponse = BusinessEnvelopeBase + // AuthRefreshJSONBody defines parameters for AuthRefresh. type AuthRefreshJSONBody struct { // RefreshToken 刷新令牌 @@ -140,6 +403,48 @@ type AuthToken200JSONResponseBody_Code struct { union json.RawMessage } +// CommentCreateParams defines parameters for CommentCreate. +type CommentCreateParams struct { + // AccessToken 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 + AccessToken AccessTokenHeader `json:"access-token"` + + // XEchoQdmpVersion qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 + XEchoQdmpVersion QdmpVersionHeader `json:"x-echo-qdmp-version"` +} + +// CommentLikeParams defines parameters for CommentLike. +type CommentLikeParams struct { + // AccessToken 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 + AccessToken AccessTokenHeader `json:"access-token"` + + // XEchoQdmpVersion qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 + XEchoQdmpVersion QdmpVersionHeader `json:"x-echo-qdmp-version"` +} + +// CommentRepliesParams defines parameters for CommentReplies. +type CommentRepliesParams struct { + // Limit 评论或回复列表每页数量,默认 10,最大 20。 + Limit *Limit20Query `form:"limit,omitempty" json:"limit,omitempty"` + + // Cursor 回复列表游标;首次请求省略,后续请求使用上一页响应返回的 cursor。 + Cursor *CursorQuery `form:"cursor,omitempty" json:"cursor,omitempty"` + + // AccessToken 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 + AccessToken AccessTokenHeader `json:"access-token"` + + // XEchoQdmpVersion qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 + XEchoQdmpVersion QdmpVersionHeader `json:"x-echo-qdmp-version"` +} + +// CommentReplyParams defines parameters for CommentReply. +type CommentReplyParams struct { + // AccessToken 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 + AccessToken AccessTokenHeader `json:"access-token"` + + // XEchoQdmpVersion qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 + XEchoQdmpVersion QdmpVersionHeader `json:"x-echo-qdmp-version"` +} + // GenaiDetailParams defines parameters for GenaiDetail. type GenaiDetailParams struct { // Id 异步任务 ID @@ -321,6 +626,15 @@ type MarkAdd401JSONResponseBody_Code struct { union json.RawMessage } +// MarkBatchAddParams defines parameters for MarkBatchAdd. +type MarkBatchAddParams struct { + // AccessToken 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 + AccessToken AccessTokenHeader `json:"access-token"` + + // XEchoQdmpVersion qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 + XEchoQdmpVersion QdmpVersionHeader `json:"x-echo-qdmp-version"` +} + // MarkDetailParams defines parameters for MarkDetail. type MarkDetailParams struct { // Id mark spu info ID(int64 线格式为字符串) @@ -438,6 +752,63 @@ type MarkSearch401JSONResponseBody_Code struct { union json.RawMessage } +// PostDetailParams defines parameters for PostDetail. +type PostDetailParams struct { + // PostId 帖子 ID;源接口为 int64,在线格式为 string,值必须大于 0。 + PostId PostIdQuery `form:"postId" json:"postId"` + + // AccessToken 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 + AccessToken AccessTokenHeader `json:"access-token"` + + // XEchoQdmpVersion qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 + XEchoQdmpVersion QdmpVersionHeader `json:"x-echo-qdmp-version"` +} + +// PostListParams defines parameters for PostList. +type PostListParams struct { + // Offset 从 0 开始的分页偏移量。 + Offset *OffsetQuery `form:"offset,omitempty" json:"offset,omitempty"` + + // Limit 帖子列表每页数量,默认 20,最大 100。 + Limit *Limit100Query `form:"limit,omitempty" json:"limit,omitempty"` + + // AccessToken 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 + AccessToken AccessTokenHeader `json:"access-token"` + + // XEchoQdmpVersion qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 + XEchoQdmpVersion QdmpVersionHeader `json:"x-echo-qdmp-version"` +} + +// PostMyListParams defines parameters for PostMyList. +type PostMyListParams struct { + // Offset 从 0 开始的分页偏移量。 + Offset *OffsetQuery `form:"offset,omitempty" json:"offset,omitempty"` + + // Limit 帖子列表每页数量,默认 20,最大 100。 + Limit *Limit100Query `form:"limit,omitempty" json:"limit,omitempty"` + + // AccessToken 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 + AccessToken AccessTokenHeader `json:"access-token"` + + // XEchoQdmpVersion qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 + XEchoQdmpVersion QdmpVersionHeader `json:"x-echo-qdmp-version"` +} + +// PostCommentsParams defines parameters for PostComments. +type PostCommentsParams struct { + // Limit 评论或回复列表每页数量,默认 10,最大 20。 + Limit *Limit20Query `form:"limit,omitempty" json:"limit,omitempty"` + + // Offset 从 0 开始的分页偏移量。 + Offset *OffsetQuery `form:"offset,omitempty" json:"offset,omitempty"` + + // AccessToken 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 + AccessToken AccessTokenHeader `json:"access-token"` + + // XEchoQdmpVersion qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 + XEchoQdmpVersion QdmpVersionHeader `json:"x-echo-qdmp-version"` +} + // SpuDetailParams defines parameters for SpuDetail. type SpuDetailParams struct { // Id SPU ID(源类型 uint64,线格式为字符串) @@ -804,12 +1175,24 @@ type AuthRefreshJSONRequestBody AuthRefreshJSONBody // AuthTokenJSONRequestBody defines body for AuthToken for application/json ContentType. type AuthTokenJSONRequestBody AuthTokenJSONBody +// CommentCreateJSONRequestBody defines body for CommentCreate for application/json ContentType. +type CommentCreateJSONRequestBody = CommentCreateRequest + +// CommentLikeJSONRequestBody defines body for CommentLike for application/json ContentType. +type CommentLikeJSONRequestBody = CommentLikeRequest + +// CommentReplyJSONRequestBody defines body for CommentReply for application/json ContentType. +type CommentReplyJSONRequestBody = CommentReplyRequest + // GenaiGenerateJSONRequestBody defines body for GenaiGenerate for application/json ContentType. type GenaiGenerateJSONRequestBody GenaiGenerateJSONBody // MarkAddJSONRequestBody defines body for MarkAdd for application/json ContentType. type MarkAddJSONRequestBody MarkAddJSONBody +// MarkBatchAddJSONRequestBody defines body for MarkBatchAdd for application/json ContentType. +type MarkBatchAddJSONRequestBody = MarkBatchAddRequest + // WishAddJSONRequestBody defines body for WishAdd for application/json ContentType. type WishAddJSONRequestBody WishAddJSONBody @@ -1057,6 +1440,440 @@ func (a SpuSearch200JSONResponseBody_Data_Items_Item) MarshalJSON() ([]byte, err return json.Marshal(object) } +// AsBusinessEnvelopeBaseCode0 returns the union data inside the BusinessEnvelopeBase_Code as a BusinessEnvelopeBaseCode0 +func (t BusinessEnvelopeBase_Code) AsBusinessEnvelopeBaseCode0() (BusinessEnvelopeBaseCode0, error) { + var body BusinessEnvelopeBaseCode0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromBusinessEnvelopeBaseCode0 overwrites any union data inside the BusinessEnvelopeBase_Code as the provided BusinessEnvelopeBaseCode0 +func (t *BusinessEnvelopeBase_Code) FromBusinessEnvelopeBaseCode0(v BusinessEnvelopeBaseCode0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeBusinessEnvelopeBaseCode0 performs a merge with any union data inside the BusinessEnvelopeBase_Code, using the provided BusinessEnvelopeBaseCode0 +func (t *BusinessEnvelopeBase_Code) MergeBusinessEnvelopeBaseCode0(v BusinessEnvelopeBaseCode0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsBusinessEnvelopeBaseCode1 returns the union data inside the BusinessEnvelopeBase_Code as a BusinessEnvelopeBaseCode1 +func (t BusinessEnvelopeBase_Code) AsBusinessEnvelopeBaseCode1() (BusinessEnvelopeBaseCode1, error) { + var body BusinessEnvelopeBaseCode1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromBusinessEnvelopeBaseCode1 overwrites any union data inside the BusinessEnvelopeBase_Code as the provided BusinessEnvelopeBaseCode1 +func (t *BusinessEnvelopeBase_Code) FromBusinessEnvelopeBaseCode1(v BusinessEnvelopeBaseCode1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeBusinessEnvelopeBaseCode1 performs a merge with any union data inside the BusinessEnvelopeBase_Code, using the provided BusinessEnvelopeBaseCode1 +func (t *BusinessEnvelopeBase_Code) MergeBusinessEnvelopeBaseCode1(v BusinessEnvelopeBaseCode1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t BusinessEnvelopeBase_Code) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *BusinessEnvelopeBase_Code) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsCommentCreateResponseCode0 returns the union data inside the CommentCreateResponse_Code as a CommentCreateResponseCode0 +func (t CommentCreateResponse_Code) AsCommentCreateResponseCode0() (CommentCreateResponseCode0, error) { + var body CommentCreateResponseCode0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromCommentCreateResponseCode0 overwrites any union data inside the CommentCreateResponse_Code as the provided CommentCreateResponseCode0 +func (t *CommentCreateResponse_Code) FromCommentCreateResponseCode0(v CommentCreateResponseCode0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeCommentCreateResponseCode0 performs a merge with any union data inside the CommentCreateResponse_Code, using the provided CommentCreateResponseCode0 +func (t *CommentCreateResponse_Code) MergeCommentCreateResponseCode0(v CommentCreateResponseCode0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsCommentCreateResponseCode1 returns the union data inside the CommentCreateResponse_Code as a CommentCreateResponseCode1 +func (t CommentCreateResponse_Code) AsCommentCreateResponseCode1() (CommentCreateResponseCode1, error) { + var body CommentCreateResponseCode1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromCommentCreateResponseCode1 overwrites any union data inside the CommentCreateResponse_Code as the provided CommentCreateResponseCode1 +func (t *CommentCreateResponse_Code) FromCommentCreateResponseCode1(v CommentCreateResponseCode1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeCommentCreateResponseCode1 performs a merge with any union data inside the CommentCreateResponse_Code, using the provided CommentCreateResponseCode1 +func (t *CommentCreateResponse_Code) MergeCommentCreateResponseCode1(v CommentCreateResponseCode1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t CommentCreateResponse_Code) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *CommentCreateResponse_Code) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsCommentRepliesResponseCode0 returns the union data inside the CommentRepliesResponse_Code as a CommentRepliesResponseCode0 +func (t CommentRepliesResponse_Code) AsCommentRepliesResponseCode0() (CommentRepliesResponseCode0, error) { + var body CommentRepliesResponseCode0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromCommentRepliesResponseCode0 overwrites any union data inside the CommentRepliesResponse_Code as the provided CommentRepliesResponseCode0 +func (t *CommentRepliesResponse_Code) FromCommentRepliesResponseCode0(v CommentRepliesResponseCode0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeCommentRepliesResponseCode0 performs a merge with any union data inside the CommentRepliesResponse_Code, using the provided CommentRepliesResponseCode0 +func (t *CommentRepliesResponse_Code) MergeCommentRepliesResponseCode0(v CommentRepliesResponseCode0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsCommentRepliesResponseCode1 returns the union data inside the CommentRepliesResponse_Code as a CommentRepliesResponseCode1 +func (t CommentRepliesResponse_Code) AsCommentRepliesResponseCode1() (CommentRepliesResponseCode1, error) { + var body CommentRepliesResponseCode1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromCommentRepliesResponseCode1 overwrites any union data inside the CommentRepliesResponse_Code as the provided CommentRepliesResponseCode1 +func (t *CommentRepliesResponse_Code) FromCommentRepliesResponseCode1(v CommentRepliesResponseCode1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeCommentRepliesResponseCode1 performs a merge with any union data inside the CommentRepliesResponse_Code, using the provided CommentRepliesResponseCode1 +func (t *CommentRepliesResponse_Code) MergeCommentRepliesResponseCode1(v CommentRepliesResponseCode1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t CommentRepliesResponse_Code) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *CommentRepliesResponse_Code) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsEmptyDataResponseCode0 returns the union data inside the EmptyDataResponse_Code as a EmptyDataResponseCode0 +func (t EmptyDataResponse_Code) AsEmptyDataResponseCode0() (EmptyDataResponseCode0, error) { + var body EmptyDataResponseCode0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromEmptyDataResponseCode0 overwrites any union data inside the EmptyDataResponse_Code as the provided EmptyDataResponseCode0 +func (t *EmptyDataResponse_Code) FromEmptyDataResponseCode0(v EmptyDataResponseCode0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeEmptyDataResponseCode0 performs a merge with any union data inside the EmptyDataResponse_Code, using the provided EmptyDataResponseCode0 +func (t *EmptyDataResponse_Code) MergeEmptyDataResponseCode0(v EmptyDataResponseCode0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsEmptyDataResponseCode1 returns the union data inside the EmptyDataResponse_Code as a EmptyDataResponseCode1 +func (t EmptyDataResponse_Code) AsEmptyDataResponseCode1() (EmptyDataResponseCode1, error) { + var body EmptyDataResponseCode1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromEmptyDataResponseCode1 overwrites any union data inside the EmptyDataResponse_Code as the provided EmptyDataResponseCode1 +func (t *EmptyDataResponse_Code) FromEmptyDataResponseCode1(v EmptyDataResponseCode1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeEmptyDataResponseCode1 performs a merge with any union data inside the EmptyDataResponse_Code, using the provided EmptyDataResponseCode1 +func (t *EmptyDataResponse_Code) MergeEmptyDataResponseCode1(v EmptyDataResponseCode1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t EmptyDataResponse_Code) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *EmptyDataResponse_Code) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsMarkBatchAddResponseCode0 returns the union data inside the MarkBatchAddResponse_Code as a MarkBatchAddResponseCode0 +func (t MarkBatchAddResponse_Code) AsMarkBatchAddResponseCode0() (MarkBatchAddResponseCode0, error) { + var body MarkBatchAddResponseCode0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromMarkBatchAddResponseCode0 overwrites any union data inside the MarkBatchAddResponse_Code as the provided MarkBatchAddResponseCode0 +func (t *MarkBatchAddResponse_Code) FromMarkBatchAddResponseCode0(v MarkBatchAddResponseCode0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeMarkBatchAddResponseCode0 performs a merge with any union data inside the MarkBatchAddResponse_Code, using the provided MarkBatchAddResponseCode0 +func (t *MarkBatchAddResponse_Code) MergeMarkBatchAddResponseCode0(v MarkBatchAddResponseCode0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsMarkBatchAddResponseCode1 returns the union data inside the MarkBatchAddResponse_Code as a MarkBatchAddResponseCode1 +func (t MarkBatchAddResponse_Code) AsMarkBatchAddResponseCode1() (MarkBatchAddResponseCode1, error) { + var body MarkBatchAddResponseCode1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromMarkBatchAddResponseCode1 overwrites any union data inside the MarkBatchAddResponse_Code as the provided MarkBatchAddResponseCode1 +func (t *MarkBatchAddResponse_Code) FromMarkBatchAddResponseCode1(v MarkBatchAddResponseCode1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeMarkBatchAddResponseCode1 performs a merge with any union data inside the MarkBatchAddResponse_Code, using the provided MarkBatchAddResponseCode1 +func (t *MarkBatchAddResponse_Code) MergeMarkBatchAddResponseCode1(v MarkBatchAddResponseCode1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t MarkBatchAddResponse_Code) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *MarkBatchAddResponse_Code) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsPostCommentsResponseCode0 returns the union data inside the PostCommentsResponse_Code as a PostCommentsResponseCode0 +func (t PostCommentsResponse_Code) AsPostCommentsResponseCode0() (PostCommentsResponseCode0, error) { + var body PostCommentsResponseCode0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromPostCommentsResponseCode0 overwrites any union data inside the PostCommentsResponse_Code as the provided PostCommentsResponseCode0 +func (t *PostCommentsResponse_Code) FromPostCommentsResponseCode0(v PostCommentsResponseCode0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergePostCommentsResponseCode0 performs a merge with any union data inside the PostCommentsResponse_Code, using the provided PostCommentsResponseCode0 +func (t *PostCommentsResponse_Code) MergePostCommentsResponseCode0(v PostCommentsResponseCode0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsPostCommentsResponseCode1 returns the union data inside the PostCommentsResponse_Code as a PostCommentsResponseCode1 +func (t PostCommentsResponse_Code) AsPostCommentsResponseCode1() (PostCommentsResponseCode1, error) { + var body PostCommentsResponseCode1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromPostCommentsResponseCode1 overwrites any union data inside the PostCommentsResponse_Code as the provided PostCommentsResponseCode1 +func (t *PostCommentsResponse_Code) FromPostCommentsResponseCode1(v PostCommentsResponseCode1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergePostCommentsResponseCode1 performs a merge with any union data inside the PostCommentsResponse_Code, using the provided PostCommentsResponseCode1 +func (t *PostCommentsResponse_Code) MergePostCommentsResponseCode1(v PostCommentsResponseCode1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t PostCommentsResponse_Code) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *PostCommentsResponse_Code) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsPostObjectResponseCode0 returns the union data inside the PostObjectResponse_Code as a PostObjectResponseCode0 +func (t PostObjectResponse_Code) AsPostObjectResponseCode0() (PostObjectResponseCode0, error) { + var body PostObjectResponseCode0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromPostObjectResponseCode0 overwrites any union data inside the PostObjectResponse_Code as the provided PostObjectResponseCode0 +func (t *PostObjectResponse_Code) FromPostObjectResponseCode0(v PostObjectResponseCode0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergePostObjectResponseCode0 performs a merge with any union data inside the PostObjectResponse_Code, using the provided PostObjectResponseCode0 +func (t *PostObjectResponse_Code) MergePostObjectResponseCode0(v PostObjectResponseCode0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsPostObjectResponseCode1 returns the union data inside the PostObjectResponse_Code as a PostObjectResponseCode1 +func (t PostObjectResponse_Code) AsPostObjectResponseCode1() (PostObjectResponseCode1, error) { + var body PostObjectResponseCode1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromPostObjectResponseCode1 overwrites any union data inside the PostObjectResponse_Code as the provided PostObjectResponseCode1 +func (t *PostObjectResponse_Code) FromPostObjectResponseCode1(v PostObjectResponseCode1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergePostObjectResponseCode1 performs a merge with any union data inside the PostObjectResponse_Code, using the provided PostObjectResponseCode1 +func (t *PostObjectResponse_Code) MergePostObjectResponseCode1(v PostObjectResponseCode1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t PostObjectResponse_Code) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *PostObjectResponse_Code) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + // AsAuthRefresh200JSONResponseBodyCode0 returns the union data inside the AuthRefresh200JSONResponseBody_Code as a AuthRefresh200JSONResponseBodyCode0 func (t AuthRefresh200JSONResponseBody_Code) AsAuthRefresh200JSONResponseBodyCode0() (AuthRefresh200JSONResponseBodyCode0, error) { var body AuthRefresh200JSONResponseBodyCode0 diff --git a/go/mark.go b/go/mark.go index 3c673ea..488f540 100644 --- a/go/mark.go +++ b/go/mark.go @@ -28,6 +28,11 @@ type MarkAddResult struct { ID string `json:"id"` } +// MarkBatchAddResult maps each requested SPU ID to its created mark ID. +type MarkBatchAddResult struct { + Result map[string]string `json:"result"` +} + // MarkItem is one element of mark.list / mark.search's data.items[]. type MarkItem struct { ID string `json:"id"` @@ -101,6 +106,22 @@ func (g *MarkGroup) Add(ctx context.Context, qdmpCtx Context, body generated.Mar return &result, nil } +// BatchAdd adds marks for multiple SPUs. +func (g *MarkGroup) BatchAdd(ctx context.Context, qdmpCtx Context, body generated.MarkBatchAddJSONRequestBody) (*MarkBatchAddResult, error) { + if err := requireAccessToken(qdmpCtx, "mark.batchAdd"); err != nil { + return nil, err + } + data, err := g.client.doRequest(ctx, requestParams{method: http.MethodPost, path: "/mark/v1/batch/add", jsonBody: body, authScheme: authSchemeStandard, accessToken: qdmpCtx.AccessToken}) + if err != nil { + return nil, err + } + var result MarkBatchAddResult + if err := json.Unmarshal(data, &result); err != nil { + return nil, fmt.Errorf("qdmp: failed to decode mark.batchAdd response: %w", err) + } + return &result, nil +} + // List fetches the current user's marks, paginated. func (g *MarkGroup) List(ctx context.Context, qdmpCtx Context, params generated.MarkListParams) (*MarkListResult, error) { if err := requireAccessToken(qdmpCtx, "mark.list"); err != nil { diff --git a/go/post.go b/go/post.go new file mode 100644 index 0000000..aefc14b --- /dev/null +++ b/go/post.go @@ -0,0 +1,41 @@ +package qdmp + +import ( + "context" + "encoding/json" + "net/http" + "net/url" + + "github.com/EchoTechFE/qdmp-server-sdk/go/generated" +) + +// PostGroup implements post detail and list operations. Public documentation does not define post data fields. +type PostGroup struct{ client *Client } + +func (g *PostGroup) Detail(ctx context.Context, q Context, postID string) (map[string]any, error) { + return g.get(ctx, q, "postDetail", "/post/v1/detail", url.Values{"postId": {postID}}) +} +func (g *PostGroup) List(ctx context.Context, q Context, params generated.PostListParams) (map[string]any, error) { + query := url.Values{} + setIfNotNil(query, "offset", params.Offset) + setIfNotNil(query, "limit", params.Limit) + return g.get(ctx, q, "postList", "/post/v1/list", query) +} +func (g *PostGroup) MyList(ctx context.Context, q Context, params generated.PostMyListParams) (map[string]any, error) { + query := url.Values{} + setIfNotNil(query, "offset", params.Offset) + setIfNotNil(query, "limit", params.Limit) + return g.get(ctx, q, "postMyList", "/post/v1/me/list", query) +} +func (g *PostGroup) get(ctx context.Context, q Context, operationID, path string, query url.Values) (map[string]any, error) { + if err := requireAccessToken(q, operationID); err != nil { + return nil, err + } + data, err := g.client.doRequest(ctx, requestParams{method: http.MethodGet, path: path, query: query, authScheme: authSchemeStandard, accessToken: q.AccessToken}) + if err != nil { + return nil, err + } + var out map[string]any + err = json.Unmarshal(data, &out) + return out, err +} diff --git a/go/post_comment_behavior_test.go b/go/post_comment_behavior_test.go new file mode 100644 index 0000000..0b1c11b --- /dev/null +++ b/go/post_comment_behavior_test.go @@ -0,0 +1,113 @@ +package qdmp_test + +import ( + "context" + "errors" + "net/http" + "testing" + + qdmp "github.com/EchoTechFE/qdmp-server-sdk/go" + "github.com/EchoTechFE/qdmp-server-sdk/go/generated" +) + +func stringPtr(value string) *string { return &value } + +func TestPostAndCommentOperations_MapWireContractAndDecodeData(t *testing.T) { + expected := []struct { + method, path, query string + body bool + data any + }{ + {http.MethodPost, "/mark/v1/batch/add", "", true, map[string]any{"result": map[string]string{"1": "m1"}}}, + {http.MethodGet, "/post/v1/detail", "postId=1", false, map[string]any{"id": "1"}}, + {http.MethodGet, "/post/v1/list", "limit=20&offset=0", false, map[string]any{"items": []any{}}}, + {http.MethodGet, "/post/v1/me/list", "", false, map[string]any{"items": []any{}}}, + {http.MethodPost, "/comment", "", true, map[string]any{"id": "c1"}}, + {http.MethodPost, "/comment/1/reply", "", true, map[string]any{"id": "c2"}}, + {http.MethodPost, "/comment/1/like", "", true, nil}, + {http.MethodGet, "/post/1/comments", "limit=10&offset=0", false, map[string]any{"items": []any{}, "count": 0}}, + {http.MethodGet, "/comment/1/replies", "cursor=next&limit=10", false, map[string]any{"items": []any{}, "count": 0, "hasMore": false, "cursor": "next"}}, + } + request := 0 + srv := startServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if request >= len(expected) { + t.Fatalf("unexpected request %s %s", r.Method, r.URL) + } + want := expected[request] + request++ + if r.Method != want.method || r.URL.EscapedPath() != want.path || r.URL.RawQuery != want.query { + t.Fatalf("request = %s %s?%s, want %s %s?%s", r.Method, r.URL.EscapedPath(), r.URL.RawQuery, want.method, want.path, want.query) + } + if want.body && r.Header.Get("Content-Type") != "application/json" { + t.Fatal("missing JSON body") + } + businessEnvelope(w, http.StatusOK, "0", "ok", "", want.data) + })) + c := newTestClient(t, srv.URL) + ctx := context.Background() + q := qdmp.Context{AccessToken: "token"} + if result, err := c.Mark.BatchAdd(ctx, q, generated.MarkBatchAddJSONRequestBody{SpuIds: []string{"1"}}); err != nil || result.Result["1"] != "m1" { + t.Fatalf("batch add = %#v, %v", result, err) + } + if result, err := c.Post.Detail(ctx, q, "1"); err != nil || result["id"] != "1" { + t.Fatalf("detail = %#v, %v", result, err) + } + if _, err := c.Post.List(ctx, q, generated.PostListParams{Offset: stringPtr("0"), Limit: stringPtr("20")}); err != nil { + t.Fatal(err) + } + if _, err := c.Post.MyList(ctx, q, generated.PostMyListParams{}); err != nil { + t.Fatal(err) + } + if result, err := c.Comment.Create(ctx, q, generated.CommentCreateJSONRequestBody{PostId: "1", Content: "hi"}); err != nil || result.ID != "c1" { + t.Fatalf("create = %#v, %v", result, err) + } + if result, err := c.Comment.Reply(ctx, q, "1", generated.CommentReplyJSONRequestBody{Content: "hi"}); err != nil || result.ID != "c2" { + t.Fatalf("reply = %#v, %v", result, err) + } + if err := c.Comment.Like(ctx, q, "1", generated.CommentLikeJSONRequestBody{Liked: true}); err != nil { + t.Fatal(err) + } + if result, err := c.Comment.PostComments(ctx, q, "1", generated.PostCommentsParams{Limit: stringPtr("10"), Offset: stringPtr("0")}); err != nil || result.Count != 0 { + t.Fatalf("comments = %#v, %v", result, err) + } + if result, err := c.Comment.Replies(ctx, q, "1", generated.CommentRepliesParams{Limit: stringPtr("10"), Cursor: stringPtr("next")}); err != nil || result.Cursor != "next" { + t.Fatalf("replies = %#v, %v", result, err) + } + if request != len(expected) { + t.Fatalf("requests = %d, want %d", request, len(expected)) + } +} + +func TestPostAndCommentOperations_RejectDotSegmentIDsBeforeRequest(t *testing.T) { + counter := newRequestCounter(func(w http.ResponseWriter, r *http.Request) { t.Fatalf("unexpected request: %s", r.URL) }) + c := newTestClient(t, startServer(t, counter).URL) + ctx, q := context.Background(), qdmp.Context{AccessToken: "token"} + for _, call := range []func() error{ + func() error { + _, err := c.Comment.Reply(ctx, q, "..", generated.CommentReplyJSONRequestBody{}) + return err + }, + func() error { return c.Comment.Like(ctx, q, "..", generated.CommentLikeJSONRequestBody{}) }, + func() error { + _, err := c.Comment.PostComments(ctx, q, "..", generated.PostCommentsParams{}) + return err + }, + func() error { _, err := c.Comment.Replies(ctx, q, "..", generated.CommentRepliesParams{}); return err }, + } { + if err := call(); err == nil { + t.Fatal("invalid ID unexpectedly succeeded") + } + } + if counter.Count() != 0 { + t.Fatalf("requests=%d", counter.Count()) + } +} + +func TestPostAndCommentOperations_RejectMissingTokenBeforeRequest(t *testing.T) { + counter := newRequestCounter(func(w http.ResponseWriter, r *http.Request) { t.Fatalf("unexpected request: %s", r.URL) }) + c := newTestClient(t, startServer(t, counter).URL) + _, err := c.Post.List(context.Background(), qdmp.Context{}, generated.PostListParams{}) + if !errors.Is(err, qdmp.ErrAccessTokenRequired) || counter.Count() != 0 { + t.Fatalf("err=%v requests=%d", err, counter.Count()) + } +} diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentCreateRequest.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentCreateRequest.java new file mode 100644 index 0000000..9b2203d --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentCreateRequest.java @@ -0,0 +1,130 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * 创建帖子评论。 + */ +@JsonPropertyOrder({ + CommentCreateRequest.JSON_PROPERTY_POST_ID, + CommentCreateRequest.JSON_PROPERTY_CONTENT +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class CommentCreateRequest { + public static final String JSON_PROPERTY_POST_ID = "postId"; + @javax.annotation.Nonnull + private String postId; + + public static final String JSON_PROPERTY_CONTENT = "content"; + @javax.annotation.Nonnull + private String content; + + public CommentCreateRequest() { + } + + public CommentCreateRequest postId(@javax.annotation.Nonnull String postId) { + + this.postId = postId; + return this; + } + + /** + * 帖子 ID;源接口为 int64,在线格式为 string,值必须大于 0。 + * @return postId + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_POST_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getPostId() { + return postId; + } + + + @JsonProperty(value = JSON_PROPERTY_POST_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setPostId(@javax.annotation.Nonnull String postId) { + this.postId = postId; + } + + public CommentCreateRequest content(@javax.annotation.Nonnull String content) { + + this.content = content; + return this; + } + + /** + * Get content + * @return content + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CONTENT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getContent() { + return content; + } + + + @JsonProperty(value = JSON_PROPERTY_CONTENT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setContent(@javax.annotation.Nonnull String content) { + this.content = content; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CommentCreateRequest commentCreateRequest = (CommentCreateRequest) o; + return Objects.equals(this.postId, commentCreateRequest.postId) && + Objects.equals(this.content, commentCreateRequest.content); + } + + @Override + public int hashCode() { + return Objects.hash(postId, content); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CommentCreateRequest {\n"); + sb.append(" postId: ").append(toIndentedString(postId)).append("\n"); + sb.append(" content: ").append(toIndentedString(content)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentCreateResponse.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentCreateResponse.java new file mode 100644 index 0000000..5106531 --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentCreateResponse.java @@ -0,0 +1,196 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.github.echotechfe.qdmp.generated.AuthToken200ResponseAllOfCode; +import io.github.echotechfe.qdmp.generated.CommentCreateResponseAllOfData; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * CommentCreateResponse + */ +@JsonPropertyOrder({ + CommentCreateResponse.JSON_PROPERTY_CODE, + CommentCreateResponse.JSON_PROPERTY_MESSAGE, + CommentCreateResponse.JSON_PROPERTY_REQUEST_ID, + CommentCreateResponse.JSON_PROPERTY_DATA +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class CommentCreateResponse { + public static final String JSON_PROPERTY_CODE = "code"; + @javax.annotation.Nonnull + private AuthToken200ResponseAllOfCode code; + + public static final String JSON_PROPERTY_MESSAGE = "message"; + @javax.annotation.Nonnull + private String message; + + public static final String JSON_PROPERTY_REQUEST_ID = "requestId"; + @javax.annotation.Nullable + private String requestId; + + public static final String JSON_PROPERTY_DATA = "data"; + @javax.annotation.Nullable + private CommentCreateResponseAllOfData data; + + public CommentCreateResponse() { + } + + public CommentCreateResponse code(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + + this.code = code; + return this; + } + + /** + * Get code + * @return code + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AuthToken200ResponseAllOfCode getCode() { + return code; + } + + + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCode(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + this.code = code; + } + + public CommentCreateResponse message(@javax.annotation.Nonnull String message) { + + this.message = message; + return this; + } + + /** + * 人类可读的提示信息 + * @return message + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getMessage() { + return message; + } + + + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMessage(@javax.annotation.Nonnull String message) { + this.message = message; + } + + public CommentCreateResponse requestId(@javax.annotation.Nullable String requestId) { + + this.requestId = requestId; + return this; + } + + /** + * 请求追踪 ID + * @return requestId + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getRequestId() { + return requestId; + } + + + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRequestId(@javax.annotation.Nullable String requestId) { + this.requestId = requestId; + } + + public CommentCreateResponse data(@javax.annotation.Nullable CommentCreateResponseAllOfData data) { + + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public CommentCreateResponseAllOfData getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setData(@javax.annotation.Nullable CommentCreateResponseAllOfData data) { + this.data = data; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CommentCreateResponse commentCreateResponse = (CommentCreateResponse) o; + return Objects.equals(this.code, commentCreateResponse.code) && + Objects.equals(this.message, commentCreateResponse.message) && + Objects.equals(this.requestId, commentCreateResponse.requestId) && + Objects.equals(this.data, commentCreateResponse.data); + } + + @Override + public int hashCode() { + return Objects.hash(code, message, requestId, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CommentCreateResponse {\n"); + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append(" requestId: ").append(toIndentedString(requestId)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentCreateResponseAllOfData.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentCreateResponseAllOfData.java new file mode 100644 index 0000000..a250dc0 --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentCreateResponseAllOfData.java @@ -0,0 +1,99 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * CommentCreateResponseAllOfData + */ +@JsonPropertyOrder({ + CommentCreateResponseAllOfData.JSON_PROPERTY_ID +}) +@JsonTypeName("CommentCreateResponse_allOf_data") +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class CommentCreateResponseAllOfData { + public static final String JSON_PROPERTY_ID = "id"; + @javax.annotation.Nullable + private String id; + + public CommentCreateResponseAllOfData() { + } + + public CommentCreateResponseAllOfData id(@javax.annotation.Nullable String id) { + + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setId(@javax.annotation.Nullable String id) { + this.id = id; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CommentCreateResponseAllOfData commentCreateResponseAllOfData = (CommentCreateResponseAllOfData) o; + return Objects.equals(this.id, commentCreateResponseAllOfData.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CommentCreateResponseAllOfData {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentItem.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentItem.java new file mode 100644 index 0000000..bb75c65 --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentItem.java @@ -0,0 +1,372 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * CommentItem + */ +@JsonPropertyOrder({ + CommentItem.JSON_PROPERTY_ID, + CommentItem.JSON_PROPERTY_CONTENT, + CommentItem.JSON_PROPERTY_CREATED_AT, + CommentItem.JSON_PROPERTY_CREATOR, + CommentItem.JSON_PROPERTY_REPLY_TO_USER, + CommentItem.JSON_PROPERTY_ROOT_COMMENT_ID, + CommentItem.JSON_PROPERTY_REPLY_COMMENT_ID, + CommentItem.JSON_PROPERTY_LIKE_COUNT, + CommentItem.JSON_PROPERTY_LIKED +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class CommentItem { + public static final String JSON_PROPERTY_ID = "id"; + @javax.annotation.Nullable + private String id; + + public static final String JSON_PROPERTY_CONTENT = "content"; + @javax.annotation.Nullable + private String content; + + public static final String JSON_PROPERTY_CREATED_AT = "createdAt"; + @javax.annotation.Nullable + private String createdAt; + + public static final String JSON_PROPERTY_CREATOR = "creator"; + @javax.annotation.Nullable + private Map creator = new HashMap<>(); + + public static final String JSON_PROPERTY_REPLY_TO_USER = "replyToUser"; + @javax.annotation.Nullable + private Map replyToUser = new HashMap<>(); + + public static final String JSON_PROPERTY_ROOT_COMMENT_ID = "rootCommentId"; + @javax.annotation.Nullable + private String rootCommentId; + + public static final String JSON_PROPERTY_REPLY_COMMENT_ID = "replyCommentId"; + @javax.annotation.Nullable + private String replyCommentId; + + public static final String JSON_PROPERTY_LIKE_COUNT = "likeCount"; + @javax.annotation.Nullable + private Integer likeCount; + + public static final String JSON_PROPERTY_LIKED = "liked"; + @javax.annotation.Nullable + private Boolean liked; + + public CommentItem() { + } + + public CommentItem id(@javax.annotation.Nullable String id) { + + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setId(@javax.annotation.Nullable String id) { + this.id = id; + } + + public CommentItem content(@javax.annotation.Nullable String content) { + + this.content = content; + return this; + } + + /** + * Get content + * @return content + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CONTENT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getContent() { + return content; + } + + + @JsonProperty(value = JSON_PROPERTY_CONTENT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setContent(@javax.annotation.Nullable String content) { + this.content = content; + } + + public CommentItem createdAt(@javax.annotation.Nullable String createdAt) { + + this.createdAt = createdAt; + return this; + } + + /** + * Get createdAt + * @return createdAt + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getCreatedAt() { + return createdAt; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATED_AT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCreatedAt(@javax.annotation.Nullable String createdAt) { + this.createdAt = createdAt; + } + + public CommentItem creator(@javax.annotation.Nullable Map creator) { + + this.creator = creator; + return this; + } + + public CommentItem putCreatorItem(String key, Object creatorItem) { + if (this.creator == null) { + this.creator = new HashMap<>(); + } + this.creator.put(key, creatorItem); + return this; + } + + /** + * Get creator + * @return creator + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CREATOR, required = false) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.USE_DEFAULTS) + + public Map getCreator() { + return creator; + } + + + @JsonProperty(value = JSON_PROPERTY_CREATOR, required = false) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.USE_DEFAULTS) + public void setCreator(@javax.annotation.Nullable Map creator) { + this.creator = creator; + } + + public CommentItem replyToUser(@javax.annotation.Nullable Map replyToUser) { + + this.replyToUser = replyToUser; + return this; + } + + public CommentItem putReplyToUserItem(String key, Object replyToUserItem) { + if (this.replyToUser == null) { + this.replyToUser = new HashMap<>(); + } + this.replyToUser.put(key, replyToUserItem); + return this; + } + + /** + * Get replyToUser + * @return replyToUser + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REPLY_TO_USER, required = false) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.USE_DEFAULTS) + + public Map getReplyToUser() { + return replyToUser; + } + + + @JsonProperty(value = JSON_PROPERTY_REPLY_TO_USER, required = false) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.USE_DEFAULTS) + public void setReplyToUser(@javax.annotation.Nullable Map replyToUser) { + this.replyToUser = replyToUser; + } + + public CommentItem rootCommentId(@javax.annotation.Nullable String rootCommentId) { + + this.rootCommentId = rootCommentId; + return this; + } + + /** + * Get rootCommentId + * @return rootCommentId + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ROOT_COMMENT_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getRootCommentId() { + return rootCommentId; + } + + + @JsonProperty(value = JSON_PROPERTY_ROOT_COMMENT_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRootCommentId(@javax.annotation.Nullable String rootCommentId) { + this.rootCommentId = rootCommentId; + } + + public CommentItem replyCommentId(@javax.annotation.Nullable String replyCommentId) { + + this.replyCommentId = replyCommentId; + return this; + } + + /** + * Get replyCommentId + * @return replyCommentId + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REPLY_COMMENT_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getReplyCommentId() { + return replyCommentId; + } + + + @JsonProperty(value = JSON_PROPERTY_REPLY_COMMENT_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setReplyCommentId(@javax.annotation.Nullable String replyCommentId) { + this.replyCommentId = replyCommentId; + } + + public CommentItem likeCount(@javax.annotation.Nullable Integer likeCount) { + + this.likeCount = likeCount; + return this; + } + + /** + * Get likeCount + * @return likeCount + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_LIKE_COUNT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Integer getLikeCount() { + return likeCount; + } + + + @JsonProperty(value = JSON_PROPERTY_LIKE_COUNT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setLikeCount(@javax.annotation.Nullable Integer likeCount) { + this.likeCount = likeCount; + } + + public CommentItem liked(@javax.annotation.Nullable Boolean liked) { + + this.liked = liked; + return this; + } + + /** + * Get liked + * @return liked + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_LIKED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Boolean getLiked() { + return liked; + } + + + @JsonProperty(value = JSON_PROPERTY_LIKED, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setLiked(@javax.annotation.Nullable Boolean liked) { + this.liked = liked; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CommentItem commentItem = (CommentItem) o; + return Objects.equals(this.id, commentItem.id) && + Objects.equals(this.content, commentItem.content) && + Objects.equals(this.createdAt, commentItem.createdAt) && + Objects.equals(this.creator, commentItem.creator) && + Objects.equals(this.replyToUser, commentItem.replyToUser) && + Objects.equals(this.rootCommentId, commentItem.rootCommentId) && + Objects.equals(this.replyCommentId, commentItem.replyCommentId) && + Objects.equals(this.likeCount, commentItem.likeCount) && + Objects.equals(this.liked, commentItem.liked); + } + + @Override + public int hashCode() { + return Objects.hash(id, content, createdAt, creator, replyToUser, rootCommentId, replyCommentId, likeCount, liked); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CommentItem {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" content: ").append(toIndentedString(content)).append("\n"); + sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); + sb.append(" creator: ").append(toIndentedString(creator)).append("\n"); + sb.append(" replyToUser: ").append(toIndentedString(replyToUser)).append("\n"); + sb.append(" rootCommentId: ").append(toIndentedString(rootCommentId)).append("\n"); + sb.append(" replyCommentId: ").append(toIndentedString(replyCommentId)).append("\n"); + sb.append(" likeCount: ").append(toIndentedString(likeCount)).append("\n"); + sb.append(" liked: ").append(toIndentedString(liked)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentLikeRequest.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentLikeRequest.java new file mode 100644 index 0000000..01d74ab --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentLikeRequest.java @@ -0,0 +1,98 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * CommentLikeRequest + */ +@JsonPropertyOrder({ + CommentLikeRequest.JSON_PROPERTY_LIKED +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class CommentLikeRequest { + public static final String JSON_PROPERTY_LIKED = "liked"; + @javax.annotation.Nonnull + private Boolean liked; + + public CommentLikeRequest() { + } + + public CommentLikeRequest liked(@javax.annotation.Nonnull Boolean liked) { + + this.liked = liked; + return this; + } + + /** + * Get liked + * @return liked + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_LIKED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Boolean getLiked() { + return liked; + } + + + @JsonProperty(value = JSON_PROPERTY_LIKED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setLiked(@javax.annotation.Nonnull Boolean liked) { + this.liked = liked; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CommentLikeRequest commentLikeRequest = (CommentLikeRequest) o; + return Objects.equals(this.liked, commentLikeRequest.liked); + } + + @Override + public int hashCode() { + return Objects.hash(liked); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CommentLikeRequest {\n"); + sb.append(" liked: ").append(toIndentedString(liked)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentRepliesResponse.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentRepliesResponse.java new file mode 100644 index 0000000..e65d7a1 --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentRepliesResponse.java @@ -0,0 +1,196 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.github.echotechfe.qdmp.generated.AuthToken200ResponseAllOfCode; +import io.github.echotechfe.qdmp.generated.CommentRepliesResponseAllOfData; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * CommentRepliesResponse + */ +@JsonPropertyOrder({ + CommentRepliesResponse.JSON_PROPERTY_CODE, + CommentRepliesResponse.JSON_PROPERTY_MESSAGE, + CommentRepliesResponse.JSON_PROPERTY_REQUEST_ID, + CommentRepliesResponse.JSON_PROPERTY_DATA +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class CommentRepliesResponse { + public static final String JSON_PROPERTY_CODE = "code"; + @javax.annotation.Nonnull + private AuthToken200ResponseAllOfCode code; + + public static final String JSON_PROPERTY_MESSAGE = "message"; + @javax.annotation.Nonnull + private String message; + + public static final String JSON_PROPERTY_REQUEST_ID = "requestId"; + @javax.annotation.Nullable + private String requestId; + + public static final String JSON_PROPERTY_DATA = "data"; + @javax.annotation.Nullable + private CommentRepliesResponseAllOfData data; + + public CommentRepliesResponse() { + } + + public CommentRepliesResponse code(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + + this.code = code; + return this; + } + + /** + * Get code + * @return code + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AuthToken200ResponseAllOfCode getCode() { + return code; + } + + + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCode(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + this.code = code; + } + + public CommentRepliesResponse message(@javax.annotation.Nonnull String message) { + + this.message = message; + return this; + } + + /** + * 人类可读的提示信息 + * @return message + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getMessage() { + return message; + } + + + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMessage(@javax.annotation.Nonnull String message) { + this.message = message; + } + + public CommentRepliesResponse requestId(@javax.annotation.Nullable String requestId) { + + this.requestId = requestId; + return this; + } + + /** + * 请求追踪 ID + * @return requestId + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getRequestId() { + return requestId; + } + + + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRequestId(@javax.annotation.Nullable String requestId) { + this.requestId = requestId; + } + + public CommentRepliesResponse data(@javax.annotation.Nullable CommentRepliesResponseAllOfData data) { + + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public CommentRepliesResponseAllOfData getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setData(@javax.annotation.Nullable CommentRepliesResponseAllOfData data) { + this.data = data; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CommentRepliesResponse commentRepliesResponse = (CommentRepliesResponse) o; + return Objects.equals(this.code, commentRepliesResponse.code) && + Objects.equals(this.message, commentRepliesResponse.message) && + Objects.equals(this.requestId, commentRepliesResponse.requestId) && + Objects.equals(this.data, commentRepliesResponse.data); + } + + @Override + public int hashCode() { + return Objects.hash(code, message, requestId, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CommentRepliesResponse {\n"); + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append(" requestId: ").append(toIndentedString(requestId)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentRepliesResponseAllOfData.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentRepliesResponseAllOfData.java new file mode 100644 index 0000000..c58fb63 --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentRepliesResponseAllOfData.java @@ -0,0 +1,207 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.github.echotechfe.qdmp.generated.CommentItem; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * CommentRepliesResponseAllOfData + */ +@JsonPropertyOrder({ + CommentRepliesResponseAllOfData.JSON_PROPERTY_ITEMS, + CommentRepliesResponseAllOfData.JSON_PROPERTY_HAS_MORE, + CommentRepliesResponseAllOfData.JSON_PROPERTY_CURSOR, + CommentRepliesResponseAllOfData.JSON_PROPERTY_COUNT +}) +@JsonTypeName("CommentRepliesResponse_allOf_data") +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class CommentRepliesResponseAllOfData { + public static final String JSON_PROPERTY_ITEMS = "items"; + @javax.annotation.Nullable + private List items = new ArrayList<>(); + + public static final String JSON_PROPERTY_HAS_MORE = "hasMore"; + @javax.annotation.Nullable + private Boolean hasMore; + + public static final String JSON_PROPERTY_CURSOR = "cursor"; + @javax.annotation.Nullable + private String cursor; + + public static final String JSON_PROPERTY_COUNT = "count"; + @javax.annotation.Nullable + private Integer count; + + public CommentRepliesResponseAllOfData() { + } + + public CommentRepliesResponseAllOfData items(@javax.annotation.Nullable List items) { + + this.items = items; + return this; + } + + public CommentRepliesResponseAllOfData addItemsItem(CommentItem itemsItem) { + if (this.items == null) { + this.items = new ArrayList<>(); + } + this.items.add(itemsItem); + return this; + } + + /** + * Get items + * @return items + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ITEMS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getItems() { + return items; + } + + + @JsonProperty(value = JSON_PROPERTY_ITEMS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setItems(@javax.annotation.Nullable List items) { + this.items = items; + } + + public CommentRepliesResponseAllOfData hasMore(@javax.annotation.Nullable Boolean hasMore) { + + this.hasMore = hasMore; + return this; + } + + /** + * Get hasMore + * @return hasMore + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_HAS_MORE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Boolean getHasMore() { + return hasMore; + } + + + @JsonProperty(value = JSON_PROPERTY_HAS_MORE, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setHasMore(@javax.annotation.Nullable Boolean hasMore) { + this.hasMore = hasMore; + } + + public CommentRepliesResponseAllOfData cursor(@javax.annotation.Nullable String cursor) { + + this.cursor = cursor; + return this; + } + + /** + * Get cursor + * @return cursor + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_CURSOR, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getCursor() { + return cursor; + } + + + @JsonProperty(value = JSON_PROPERTY_CURSOR, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCursor(@javax.annotation.Nullable String cursor) { + this.cursor = cursor; + } + + public CommentRepliesResponseAllOfData count(@javax.annotation.Nullable Integer count) { + + this.count = count; + return this; + } + + /** + * Get count + * @return count + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_COUNT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Integer getCount() { + return count; + } + + + @JsonProperty(value = JSON_PROPERTY_COUNT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCount(@javax.annotation.Nullable Integer count) { + this.count = count; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CommentRepliesResponseAllOfData commentRepliesResponseAllOfData = (CommentRepliesResponseAllOfData) o; + return Objects.equals(this.items, commentRepliesResponseAllOfData.items) && + Objects.equals(this.hasMore, commentRepliesResponseAllOfData.hasMore) && + Objects.equals(this.cursor, commentRepliesResponseAllOfData.cursor) && + Objects.equals(this.count, commentRepliesResponseAllOfData.count); + } + + @Override + public int hashCode() { + return Objects.hash(items, hasMore, cursor, count); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CommentRepliesResponseAllOfData {\n"); + sb.append(" items: ").append(toIndentedString(items)).append("\n"); + sb.append(" hasMore: ").append(toIndentedString(hasMore)).append("\n"); + sb.append(" cursor: ").append(toIndentedString(cursor)).append("\n"); + sb.append(" count: ").append(toIndentedString(count)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentReplyRequest.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentReplyRequest.java new file mode 100644 index 0000000..ad428e0 --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentReplyRequest.java @@ -0,0 +1,98 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * 回复评论。 + */ +@JsonPropertyOrder({ + CommentReplyRequest.JSON_PROPERTY_CONTENT +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class CommentReplyRequest { + public static final String JSON_PROPERTY_CONTENT = "content"; + @javax.annotation.Nonnull + private String content; + + public CommentReplyRequest() { + } + + public CommentReplyRequest content(@javax.annotation.Nonnull String content) { + + this.content = content; + return this; + } + + /** + * Get content + * @return content + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CONTENT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getContent() { + return content; + } + + + @JsonProperty(value = JSON_PROPERTY_CONTENT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setContent(@javax.annotation.Nonnull String content) { + this.content = content; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CommentReplyRequest commentReplyRequest = (CommentReplyRequest) o; + return Objects.equals(this.content, commentReplyRequest.content); + } + + @Override + public int hashCode() { + return Objects.hash(content); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CommentReplyRequest {\n"); + sb.append(" content: ").append(toIndentedString(content)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentThread.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentThread.java new file mode 100644 index 0000000..1ed6be4 --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/CommentThread.java @@ -0,0 +1,174 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.github.echotechfe.qdmp.generated.CommentItem; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * CommentThread + */ +@JsonPropertyOrder({ + CommentThread.JSON_PROPERTY_COMMENT, + CommentThread.JSON_PROPERTY_REPLIES, + CommentThread.JSON_PROPERTY_REPLY_COUNT +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class CommentThread { + public static final String JSON_PROPERTY_COMMENT = "comment"; + @javax.annotation.Nullable + private CommentItem comment; + + public static final String JSON_PROPERTY_REPLIES = "replies"; + @javax.annotation.Nullable + private List replies = new ArrayList<>(); + + public static final String JSON_PROPERTY_REPLY_COUNT = "replyCount"; + @javax.annotation.Nullable + private Integer replyCount; + + public CommentThread() { + } + + public CommentThread comment(@javax.annotation.Nullable CommentItem comment) { + + this.comment = comment; + return this; + } + + /** + * Get comment + * @return comment + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_COMMENT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public CommentItem getComment() { + return comment; + } + + + @JsonProperty(value = JSON_PROPERTY_COMMENT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setComment(@javax.annotation.Nullable CommentItem comment) { + this.comment = comment; + } + + public CommentThread replies(@javax.annotation.Nullable List replies) { + + this.replies = replies; + return this; + } + + public CommentThread addRepliesItem(CommentItem repliesItem) { + if (this.replies == null) { + this.replies = new ArrayList<>(); + } + this.replies.add(repliesItem); + return this; + } + + /** + * Get replies + * @return replies + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REPLIES, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getReplies() { + return replies; + } + + + @JsonProperty(value = JSON_PROPERTY_REPLIES, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setReplies(@javax.annotation.Nullable List replies) { + this.replies = replies; + } + + public CommentThread replyCount(@javax.annotation.Nullable Integer replyCount) { + + this.replyCount = replyCount; + return this; + } + + /** + * Get replyCount + * @return replyCount + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REPLY_COUNT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Integer getReplyCount() { + return replyCount; + } + + + @JsonProperty(value = JSON_PROPERTY_REPLY_COUNT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setReplyCount(@javax.annotation.Nullable Integer replyCount) { + this.replyCount = replyCount; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CommentThread commentThread = (CommentThread) o; + return Objects.equals(this.comment, commentThread.comment) && + Objects.equals(this.replies, commentThread.replies) && + Objects.equals(this.replyCount, commentThread.replyCount); + } + + @Override + public int hashCode() { + return Objects.hash(comment, replies, replyCount); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CommentThread {\n"); + sb.append(" comment: ").append(toIndentedString(comment)).append("\n"); + sb.append(" replies: ").append(toIndentedString(replies)).append("\n"); + sb.append(" replyCount: ").append(toIndentedString(replyCount)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/EmptyDataResponse.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/EmptyDataResponse.java new file mode 100644 index 0000000..bc46e12 --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/EmptyDataResponse.java @@ -0,0 +1,205 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.github.echotechfe.qdmp.generated.AuthToken200ResponseAllOfCode; +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * EmptyDataResponse + */ +@JsonPropertyOrder({ + EmptyDataResponse.JSON_PROPERTY_CODE, + EmptyDataResponse.JSON_PROPERTY_MESSAGE, + EmptyDataResponse.JSON_PROPERTY_REQUEST_ID, + EmptyDataResponse.JSON_PROPERTY_DATA +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class EmptyDataResponse { + public static final String JSON_PROPERTY_CODE = "code"; + @javax.annotation.Nonnull + private AuthToken200ResponseAllOfCode code; + + public static final String JSON_PROPERTY_MESSAGE = "message"; + @javax.annotation.Nonnull + private String message; + + public static final String JSON_PROPERTY_REQUEST_ID = "requestId"; + @javax.annotation.Nullable + private String requestId; + + public static final String JSON_PROPERTY_DATA = "data"; + @javax.annotation.Nullable + private Map data = new HashMap<>(); + + public EmptyDataResponse() { + } + + public EmptyDataResponse code(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + + this.code = code; + return this; + } + + /** + * Get code + * @return code + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AuthToken200ResponseAllOfCode getCode() { + return code; + } + + + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCode(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + this.code = code; + } + + public EmptyDataResponse message(@javax.annotation.Nonnull String message) { + + this.message = message; + return this; + } + + /** + * 人类可读的提示信息 + * @return message + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getMessage() { + return message; + } + + + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMessage(@javax.annotation.Nonnull String message) { + this.message = message; + } + + public EmptyDataResponse requestId(@javax.annotation.Nullable String requestId) { + + this.requestId = requestId; + return this; + } + + /** + * 请求追踪 ID + * @return requestId + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getRequestId() { + return requestId; + } + + + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRequestId(@javax.annotation.Nullable String requestId) { + this.requestId = requestId; + } + + public EmptyDataResponse data(@javax.annotation.Nullable Map data) { + + this.data = data; + return this; + } + + public EmptyDataResponse putDataItem(String key, Object dataItem) { + if (this.data == null) { + this.data = new HashMap<>(); + } + this.data.put(key, dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.USE_DEFAULTS) + + public Map getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.USE_DEFAULTS) + public void setData(@javax.annotation.Nullable Map data) { + this.data = data; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EmptyDataResponse emptyDataResponse = (EmptyDataResponse) o; + return Objects.equals(this.code, emptyDataResponse.code) && + Objects.equals(this.message, emptyDataResponse.message) && + Objects.equals(this.requestId, emptyDataResponse.requestId) && + Objects.equals(this.data, emptyDataResponse.data); + } + + @Override + public int hashCode() { + return Objects.hash(code, message, requestId, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class EmptyDataResponse {\n"); + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append(" requestId: ").append(toIndentedString(requestId)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/MarkBatchAddRequest.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/MarkBatchAddRequest.java new file mode 100644 index 0000000..b16fcdc --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/MarkBatchAddRequest.java @@ -0,0 +1,109 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * 批量添加标记。 + */ +@JsonPropertyOrder({ + MarkBatchAddRequest.JSON_PROPERTY_SPU_IDS +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class MarkBatchAddRequest { + public static final String JSON_PROPERTY_SPU_IDS = "spuIds"; + @javax.annotation.Nonnull + private List spuIds = new ArrayList<>(); + + public MarkBatchAddRequest() { + } + + public MarkBatchAddRequest spuIds(@javax.annotation.Nonnull List spuIds) { + + this.spuIds = spuIds; + return this; + } + + public MarkBatchAddRequest addSpuIdsItem(String spuIdsItem) { + if (this.spuIds == null) { + this.spuIds = new ArrayList<>(); + } + this.spuIds.add(spuIdsItem); + return this; + } + + /** + * SPU ID 列表;源接口为 int64[],在线格式为 string[]。 + * @return spuIds + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SPU_IDS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getSpuIds() { + return spuIds; + } + + + @JsonProperty(value = JSON_PROPERTY_SPU_IDS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSpuIds(@javax.annotation.Nonnull List spuIds) { + this.spuIds = spuIds; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MarkBatchAddRequest markBatchAddRequest = (MarkBatchAddRequest) o; + return Objects.equals(this.spuIds, markBatchAddRequest.spuIds); + } + + @Override + public int hashCode() { + return Objects.hash(spuIds); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MarkBatchAddRequest {\n"); + sb.append(" spuIds: ").append(toIndentedString(spuIds)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/MarkBatchAddResponse.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/MarkBatchAddResponse.java new file mode 100644 index 0000000..cfacf7f --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/MarkBatchAddResponse.java @@ -0,0 +1,196 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.github.echotechfe.qdmp.generated.AuthToken200ResponseAllOfCode; +import io.github.echotechfe.qdmp.generated.MarkBatchAddResponseAllOfData; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * MarkBatchAddResponse + */ +@JsonPropertyOrder({ + MarkBatchAddResponse.JSON_PROPERTY_CODE, + MarkBatchAddResponse.JSON_PROPERTY_MESSAGE, + MarkBatchAddResponse.JSON_PROPERTY_REQUEST_ID, + MarkBatchAddResponse.JSON_PROPERTY_DATA +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class MarkBatchAddResponse { + public static final String JSON_PROPERTY_CODE = "code"; + @javax.annotation.Nonnull + private AuthToken200ResponseAllOfCode code; + + public static final String JSON_PROPERTY_MESSAGE = "message"; + @javax.annotation.Nonnull + private String message; + + public static final String JSON_PROPERTY_REQUEST_ID = "requestId"; + @javax.annotation.Nullable + private String requestId; + + public static final String JSON_PROPERTY_DATA = "data"; + @javax.annotation.Nullable + private MarkBatchAddResponseAllOfData data; + + public MarkBatchAddResponse() { + } + + public MarkBatchAddResponse code(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + + this.code = code; + return this; + } + + /** + * Get code + * @return code + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AuthToken200ResponseAllOfCode getCode() { + return code; + } + + + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCode(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + this.code = code; + } + + public MarkBatchAddResponse message(@javax.annotation.Nonnull String message) { + + this.message = message; + return this; + } + + /** + * 人类可读的提示信息 + * @return message + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getMessage() { + return message; + } + + + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMessage(@javax.annotation.Nonnull String message) { + this.message = message; + } + + public MarkBatchAddResponse requestId(@javax.annotation.Nullable String requestId) { + + this.requestId = requestId; + return this; + } + + /** + * 请求追踪 ID + * @return requestId + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getRequestId() { + return requestId; + } + + + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRequestId(@javax.annotation.Nullable String requestId) { + this.requestId = requestId; + } + + public MarkBatchAddResponse data(@javax.annotation.Nullable MarkBatchAddResponseAllOfData data) { + + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public MarkBatchAddResponseAllOfData getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setData(@javax.annotation.Nullable MarkBatchAddResponseAllOfData data) { + this.data = data; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MarkBatchAddResponse markBatchAddResponse = (MarkBatchAddResponse) o; + return Objects.equals(this.code, markBatchAddResponse.code) && + Objects.equals(this.message, markBatchAddResponse.message) && + Objects.equals(this.requestId, markBatchAddResponse.requestId) && + Objects.equals(this.data, markBatchAddResponse.data); + } + + @Override + public int hashCode() { + return Objects.hash(code, message, requestId, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MarkBatchAddResponse {\n"); + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append(" requestId: ").append(toIndentedString(requestId)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/MarkBatchAddResponseAllOfData.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/MarkBatchAddResponseAllOfData.java new file mode 100644 index 0000000..ac4e9f2 --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/MarkBatchAddResponseAllOfData.java @@ -0,0 +1,109 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * MarkBatchAddResponseAllOfData + */ +@JsonPropertyOrder({ + MarkBatchAddResponseAllOfData.JSON_PROPERTY_RESULT +}) +@JsonTypeName("MarkBatchAddResponse_allOf_data") +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class MarkBatchAddResponseAllOfData { + public static final String JSON_PROPERTY_RESULT = "result"; + @javax.annotation.Nullable + private Map result = new HashMap<>(); + + public MarkBatchAddResponseAllOfData() { + } + + public MarkBatchAddResponseAllOfData result(@javax.annotation.Nullable Map result) { + + this.result = result; + return this; + } + + public MarkBatchAddResponseAllOfData putResultItem(String key, String resultItem) { + if (this.result == null) { + this.result = new HashMap<>(); + } + this.result.put(key, resultItem); + return this; + } + + /** + * Get result + * @return result + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_RESULT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Map getResult() { + return result; + } + + + @JsonProperty(value = JSON_PROPERTY_RESULT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setResult(@javax.annotation.Nullable Map result) { + this.result = result; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MarkBatchAddResponseAllOfData markBatchAddResponseAllOfData = (MarkBatchAddResponseAllOfData) o; + return Objects.equals(this.result, markBatchAddResponseAllOfData.result); + } + + @Override + public int hashCode() { + return Objects.hash(result); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MarkBatchAddResponseAllOfData {\n"); + sb.append(" result: ").append(toIndentedString(result)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/PostCommentsResponse.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/PostCommentsResponse.java new file mode 100644 index 0000000..b81cf28 --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/PostCommentsResponse.java @@ -0,0 +1,196 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.github.echotechfe.qdmp.generated.AuthToken200ResponseAllOfCode; +import io.github.echotechfe.qdmp.generated.PostCommentsResponseAllOfData; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * PostCommentsResponse + */ +@JsonPropertyOrder({ + PostCommentsResponse.JSON_PROPERTY_CODE, + PostCommentsResponse.JSON_PROPERTY_MESSAGE, + PostCommentsResponse.JSON_PROPERTY_REQUEST_ID, + PostCommentsResponse.JSON_PROPERTY_DATA +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class PostCommentsResponse { + public static final String JSON_PROPERTY_CODE = "code"; + @javax.annotation.Nonnull + private AuthToken200ResponseAllOfCode code; + + public static final String JSON_PROPERTY_MESSAGE = "message"; + @javax.annotation.Nonnull + private String message; + + public static final String JSON_PROPERTY_REQUEST_ID = "requestId"; + @javax.annotation.Nullable + private String requestId; + + public static final String JSON_PROPERTY_DATA = "data"; + @javax.annotation.Nullable + private PostCommentsResponseAllOfData data; + + public PostCommentsResponse() { + } + + public PostCommentsResponse code(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + + this.code = code; + return this; + } + + /** + * Get code + * @return code + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AuthToken200ResponseAllOfCode getCode() { + return code; + } + + + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCode(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + this.code = code; + } + + public PostCommentsResponse message(@javax.annotation.Nonnull String message) { + + this.message = message; + return this; + } + + /** + * 人类可读的提示信息 + * @return message + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getMessage() { + return message; + } + + + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMessage(@javax.annotation.Nonnull String message) { + this.message = message; + } + + public PostCommentsResponse requestId(@javax.annotation.Nullable String requestId) { + + this.requestId = requestId; + return this; + } + + /** + * 请求追踪 ID + * @return requestId + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getRequestId() { + return requestId; + } + + + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRequestId(@javax.annotation.Nullable String requestId) { + this.requestId = requestId; + } + + public PostCommentsResponse data(@javax.annotation.Nullable PostCommentsResponseAllOfData data) { + + this.data = data; + return this; + } + + /** + * Get data + * @return data + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public PostCommentsResponseAllOfData getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setData(@javax.annotation.Nullable PostCommentsResponseAllOfData data) { + this.data = data; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PostCommentsResponse postCommentsResponse = (PostCommentsResponse) o; + return Objects.equals(this.code, postCommentsResponse.code) && + Objects.equals(this.message, postCommentsResponse.message) && + Objects.equals(this.requestId, postCommentsResponse.requestId) && + Objects.equals(this.data, postCommentsResponse.data); + } + + @Override + public int hashCode() { + return Objects.hash(code, message, requestId, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class PostCommentsResponse {\n"); + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append(" requestId: ").append(toIndentedString(requestId)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/PostCommentsResponseAllOfData.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/PostCommentsResponseAllOfData.java new file mode 100644 index 0000000..f685b89 --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/PostCommentsResponseAllOfData.java @@ -0,0 +1,143 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.github.echotechfe.qdmp.generated.CommentThread; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * PostCommentsResponseAllOfData + */ +@JsonPropertyOrder({ + PostCommentsResponseAllOfData.JSON_PROPERTY_ITEMS, + PostCommentsResponseAllOfData.JSON_PROPERTY_COUNT +}) +@JsonTypeName("PostCommentsResponse_allOf_data") +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class PostCommentsResponseAllOfData { + public static final String JSON_PROPERTY_ITEMS = "items"; + @javax.annotation.Nullable + private List items = new ArrayList<>(); + + public static final String JSON_PROPERTY_COUNT = "count"; + @javax.annotation.Nullable + private Integer count; + + public PostCommentsResponseAllOfData() { + } + + public PostCommentsResponseAllOfData items(@javax.annotation.Nullable List items) { + + this.items = items; + return this; + } + + public PostCommentsResponseAllOfData addItemsItem(CommentThread itemsItem) { + if (this.items == null) { + this.items = new ArrayList<>(); + } + this.items.add(itemsItem); + return this; + } + + /** + * Get items + * @return items + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_ITEMS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getItems() { + return items; + } + + + @JsonProperty(value = JSON_PROPERTY_ITEMS, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setItems(@javax.annotation.Nullable List items) { + this.items = items; + } + + public PostCommentsResponseAllOfData count(@javax.annotation.Nullable Integer count) { + + this.count = count; + return this; + } + + /** + * Get count + * @return count + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_COUNT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Integer getCount() { + return count; + } + + + @JsonProperty(value = JSON_PROPERTY_COUNT, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setCount(@javax.annotation.Nullable Integer count) { + this.count = count; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PostCommentsResponseAllOfData postCommentsResponseAllOfData = (PostCommentsResponseAllOfData) o; + return Objects.equals(this.items, postCommentsResponseAllOfData.items) && + Objects.equals(this.count, postCommentsResponseAllOfData.count); + } + + @Override + public int hashCode() { + return Objects.hash(items, count); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class PostCommentsResponseAllOfData {\n"); + sb.append(" items: ").append(toIndentedString(items)).append("\n"); + sb.append(" count: ").append(toIndentedString(count)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/PostObjectResponse.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/PostObjectResponse.java new file mode 100644 index 0000000..28b997f --- /dev/null +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/PostObjectResponse.java @@ -0,0 +1,205 @@ +/* + * Code generated by openapi-generator from shared/openapi.yaml. DO NOT EDIT. + */ + + +package io.github.echotechfe.qdmp.generated; + +import java.util.Objects; +import java.util.Arrays; +import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import io.github.echotechfe.qdmp.generated.AuthToken200ResponseAllOfCode; +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * PostObjectResponse + */ +@JsonPropertyOrder({ + PostObjectResponse.JSON_PROPERTY_CODE, + PostObjectResponse.JSON_PROPERTY_MESSAGE, + PostObjectResponse.JSON_PROPERTY_REQUEST_ID, + PostObjectResponse.JSON_PROPERTY_DATA +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.16.0") +public class PostObjectResponse { + public static final String JSON_PROPERTY_CODE = "code"; + @javax.annotation.Nonnull + private AuthToken200ResponseAllOfCode code; + + public static final String JSON_PROPERTY_MESSAGE = "message"; + @javax.annotation.Nonnull + private String message; + + public static final String JSON_PROPERTY_REQUEST_ID = "requestId"; + @javax.annotation.Nullable + private String requestId; + + public static final String JSON_PROPERTY_DATA = "data"; + @javax.annotation.Nullable + private Map data = new HashMap<>(); + + public PostObjectResponse() { + } + + public PostObjectResponse code(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + + this.code = code; + return this; + } + + /** + * Get code + * @return code + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AuthToken200ResponseAllOfCode getCode() { + return code; + } + + + @JsonProperty(value = JSON_PROPERTY_CODE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setCode(@javax.annotation.Nonnull AuthToken200ResponseAllOfCode code) { + this.code = code; + } + + public PostObjectResponse message(@javax.annotation.Nonnull String message) { + + this.message = message; + return this; + } + + /** + * 人类可读的提示信息 + * @return message + */ + @javax.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getMessage() { + return message; + } + + + @JsonProperty(value = JSON_PROPERTY_MESSAGE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMessage(@javax.annotation.Nonnull String message) { + this.message = message; + } + + public PostObjectResponse requestId(@javax.annotation.Nullable String requestId) { + + this.requestId = requestId; + return this; + } + + /** + * 请求追踪 ID + * @return requestId + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public String getRequestId() { + return requestId; + } + + + @JsonProperty(value = JSON_PROPERTY_REQUEST_ID, required = false) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setRequestId(@javax.annotation.Nullable String requestId) { + this.requestId = requestId; + } + + public PostObjectResponse data(@javax.annotation.Nullable Map data) { + + this.data = data; + return this; + } + + public PostObjectResponse putDataItem(String key, Object dataItem) { + if (this.data == null) { + this.data = new HashMap<>(); + } + this.data.put(key, dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @javax.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.USE_DEFAULTS) + + public Map getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = false) + @JsonInclude(content = JsonInclude.Include.ALWAYS, value = JsonInclude.Include.USE_DEFAULTS) + public void setData(@javax.annotation.Nullable Map data) { + this.data = data; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PostObjectResponse postObjectResponse = (PostObjectResponse) o; + return Objects.equals(this.code, postObjectResponse.code) && + Objects.equals(this.message, postObjectResponse.message) && + Objects.equals(this.requestId, postObjectResponse.requestId) && + Objects.equals(this.data, postObjectResponse.data); + } + + @Override + public int hashCode() { + return Objects.hash(code, message, requestId, data); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class PostObjectResponse {\n"); + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append(" requestId: ").append(toIndentedString(requestId)).append("\n"); + sb.append(" data: ").append(toIndentedString(data)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/RouteMeta.java b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/RouteMeta.java index 1fbae13..a313ce0 100644 --- a/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/RouteMeta.java +++ b/java/generated/src/main/java/io/github/echotechfe/qdmp/generated/RouteMeta.java @@ -161,6 +161,60 @@ public boolean isTokenRequired() { "GET", "/genai/v1/detail", "genai", + true), + new Entry( + "markBatchAdd", + "POST", + "/mark/v1/batch/add", + "standard", + true), + new Entry( + "postDetail", + "GET", + "/post/v1/detail", + "standard", + true), + new Entry( + "postList", + "GET", + "/post/v1/list", + "standard", + true), + new Entry( + "postMyList", + "GET", + "/post/v1/me/list", + "standard", + true), + new Entry( + "commentCreate", + "POST", + "/comment", + "standard", + true), + new Entry( + "commentReply", + "POST", + "/comment/{commentId}/reply", + "standard", + true), + new Entry( + "commentLike", + "POST", + "/comment/{commentId}/like", + "standard", + true), + new Entry( + "postComments", + "GET", + "/post/{postId}/comments", + "standard", + true), + new Entry( + "commentReplies", + "GET", + "/comment/{commentId}/replies", + "standard", true) )); diff --git a/java/src/main/java/io/github/echotechfe/qdmp/QdmpClient.java b/java/src/main/java/io/github/echotechfe/qdmp/QdmpClient.java index c8489e4..e653e9e 100644 --- a/java/src/main/java/io/github/echotechfe/qdmp/QdmpClient.java +++ b/java/src/main/java/io/github/echotechfe/qdmp/QdmpClient.java @@ -1,9 +1,11 @@ package io.github.echotechfe.qdmp; import io.github.echotechfe.qdmp.auth.QdmpAuth; +import io.github.echotechfe.qdmp.groups.CommentGroup; import io.github.echotechfe.qdmp.groups.GenaiGroup; import io.github.echotechfe.qdmp.groups.IslandGroup; import io.github.echotechfe.qdmp.groups.MarkGroup; +import io.github.echotechfe.qdmp.groups.PostGroup; import io.github.echotechfe.qdmp.groups.SpuGroup; import io.github.echotechfe.qdmp.groups.TagGroup; import io.github.echotechfe.qdmp.groups.UserGroup; @@ -23,6 +25,8 @@ public final class QdmpClient { private final SpuGroup spu; private final TagGroup tag; private final MarkGroup mark; + private final PostGroup post; + private final CommentGroup comment; private final WishSpuGroup wishspu; private final GenaiGroup genai; @@ -50,6 +54,8 @@ public QdmpClient(QdmpClientConfig config) { this.spu = new SpuGroup(transport); this.tag = new TagGroup(transport); this.mark = new MarkGroup(transport); + this.post = new PostGroup(transport); + this.comment = new CommentGroup(transport); this.wishspu = new WishSpuGroup(transport); this.genai = new GenaiGroup(transport); } @@ -78,6 +84,14 @@ public MarkGroup mark() { return mark; } + public PostGroup post() { + return post; + } + + public CommentGroup comment() { + return comment; + } + public WishSpuGroup wishspu() { return wishspu; } diff --git a/java/src/main/java/io/github/echotechfe/qdmp/groups/CommentGroup.java b/java/src/main/java/io/github/echotechfe/qdmp/groups/CommentGroup.java new file mode 100644 index 0000000..bf8941a --- /dev/null +++ b/java/src/main/java/io/github/echotechfe/qdmp/groups/CommentGroup.java @@ -0,0 +1,115 @@ +package io.github.echotechfe.qdmp.groups; + +import io.github.echotechfe.qdmp.AuthScheme; +import io.github.echotechfe.qdmp.QdmpContext; +import io.github.echotechfe.qdmp.QdmpTransport; +import io.github.echotechfe.qdmp.generated.CommentCreateRequest; +import io.github.echotechfe.qdmp.generated.CommentCreateResponseAllOfData; +import io.github.echotechfe.qdmp.generated.CommentLikeRequest; +import io.github.echotechfe.qdmp.generated.CommentRepliesResponseAllOfData; +import io.github.echotechfe.qdmp.generated.CommentReplyRequest; +import io.github.echotechfe.qdmp.generated.PostCommentsResponseAllOfData; +import io.github.echotechfe.qdmp.generated.RouteMeta; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; + +/** Comment operations and pagination. */ +public final class CommentGroup { + private final QdmpTransport transport; + + public CommentGroup(QdmpTransport transport) { + this.transport = transport; + } + + public CommentCreateResponseAllOfData create(QdmpContext ctx, CommentCreateRequest request) { + return post("commentCreate", ctx, null, request, CommentCreateResponseAllOfData.class); + } + + public CommentCreateResponseAllOfData reply( + QdmpContext ctx, String commentId, CommentReplyRequest request) { + return post("commentReply", ctx, commentId, request, CommentCreateResponseAllOfData.class); + } + + /** Likes or unlikes a comment. */ + public void like(QdmpContext ctx, String commentId, CommentLikeRequest request) { + post("commentLike", ctx, commentId, request, Void.class); + } + + /** Lists comments on a post. */ + public PostCommentsResponseAllOfData postComments( + QdmpContext ctx, String postId, String limit, String offset) { + return get( + "postComments", + ctx, + "postId", + postId, + query("limit", limit, "offset", offset), + PostCommentsResponseAllOfData.class); + } + + /** Lists replies to a comment. */ + public CommentRepliesResponseAllOfData replies( + QdmpContext ctx, String commentId, String limit, String cursor) { + return get( + "commentReplies", + ctx, + "commentId", + commentId, + query("limit", limit, "cursor", cursor), + CommentRepliesResponseAllOfData.class); + } + + private T post( + String operationId, QdmpContext ctx, String commentId, Object body, Class type) { + RouteMeta.Entry route = RouteMeta.get(operationId); + return transport.post( + path(route, "commentId", commentId), + AuthScheme.fromWireValue(route.getAuthScheme()), + ctx, + body, + type); + } + + private T get( + String operationId, + QdmpContext ctx, + String parameter, + String id, + Map query, + Class type) { + RouteMeta.Entry route = RouteMeta.get(operationId); + return transport.get( + path(route, parameter, id), + AuthScheme.fromWireValue(route.getAuthScheme()), + ctx, + query, + type); + } + + private static String path(RouteMeta.Entry route, String parameter, String value) { + String placeholder = "{" + parameter + "}"; + if (!route.getPath().contains(placeholder)) { + return route.getPath(); + } + Objects.requireNonNull(value, parameter + " must not be null"); + validatePositiveId(parameter, value); + return route.getPath().replace(placeholder, value); + } + + private static void validatePositiveId(String name, String value) { + if (!value.matches("^[1-9][0-9]*$")) { + throw new IllegalArgumentException(name + " must be a positive integer ID"); + } + } + + private static Map query(Object... entries) { + Map result = new LinkedHashMap<>(); + for (int i = 0; i < entries.length; i += 2) { + if (entries[i + 1] != null) { + result.put((String) entries[i], entries[i + 1]); + } + } + return result; + } +} diff --git a/java/src/main/java/io/github/echotechfe/qdmp/groups/MarkGroup.java b/java/src/main/java/io/github/echotechfe/qdmp/groups/MarkGroup.java index ddea39f..08bee81 100644 --- a/java/src/main/java/io/github/echotechfe/qdmp/groups/MarkGroup.java +++ b/java/src/main/java/io/github/echotechfe/qdmp/groups/MarkGroup.java @@ -5,6 +5,8 @@ import io.github.echotechfe.qdmp.QdmpTransport; import io.github.echotechfe.qdmp.generated.MarkAdd200ResponseAllOfData; import io.github.echotechfe.qdmp.generated.MarkAddRequest; +import io.github.echotechfe.qdmp.generated.MarkBatchAddRequest; +import io.github.echotechfe.qdmp.generated.MarkBatchAddResponseAllOfData; import io.github.echotechfe.qdmp.generated.MarkDetail200ResponseAllOfData; import io.github.echotechfe.qdmp.generated.MarkList200ResponseAllOfData; import io.github.echotechfe.qdmp.generated.MarkSearch200ResponseAllOfData; @@ -45,6 +47,17 @@ public MarkAdd200ResponseAllOfData add(QdmpContext ctx, MarkAddRequest request) MarkAdd200ResponseAllOfData.class); } + /** Adds marks for multiple SPUs and returns the SPU-to-mark-ID mapping. */ + public MarkBatchAddResponseAllOfData batchAdd(QdmpContext ctx, MarkBatchAddRequest request) { + RouteMeta.Entry route = RouteMeta.get("markBatchAdd"); + return transport.post( + route.getPath(), + AuthScheme.fromWireValue(route.getAuthScheme()), + ctx, + request, + MarkBatchAddResponseAllOfData.class); + } + /** * Lists the current user's marks, paginated. * diff --git a/java/src/main/java/io/github/echotechfe/qdmp/groups/PostGroup.java b/java/src/main/java/io/github/echotechfe/qdmp/groups/PostGroup.java new file mode 100644 index 0000000..9c0a70e --- /dev/null +++ b/java/src/main/java/io/github/echotechfe/qdmp/groups/PostGroup.java @@ -0,0 +1,52 @@ +package io.github.echotechfe.qdmp.groups; + +import io.github.echotechfe.qdmp.AuthScheme; +import io.github.echotechfe.qdmp.QdmpContext; +import io.github.echotechfe.qdmp.QdmpTransport; +import io.github.echotechfe.qdmp.generated.RouteMeta; +import java.util.LinkedHashMap; +import java.util.Map; + +/** Post queries return extensible maps because the public documentation does not define data. */ +public final class PostGroup { + private final QdmpTransport transport; + + public PostGroup(QdmpTransport transport) { + this.transport = transport; + } + + public Map detail(QdmpContext ctx, String postId) { + return get("postDetail", ctx, query("postId", postId)); + } + + public Map list(QdmpContext ctx, String offset, String limit) { + return get("postList", ctx, query("offset", offset, "limit", limit)); + } + + public Map myList(QdmpContext ctx, String offset, String limit) { + return get("postMyList", ctx, query("offset", offset, "limit", limit)); + } + + private Map get(String operationId, QdmpContext ctx, Map query) { + RouteMeta.Entry route = RouteMeta.get(operationId); + @SuppressWarnings("unchecked") + Map result = + transport.get( + route.getPath(), + AuthScheme.fromWireValue(route.getAuthScheme()), + ctx, + query, + Map.class); + return result; + } + + private static Map query(String... entries) { + Map result = new LinkedHashMap<>(); + for (int i = 0; i < entries.length; i += 2) { + if (entries[i + 1] != null) { + result.put(entries[i], entries[i + 1]); + } + } + return result; + } +} diff --git a/java/src/test/java/io/github/echotechfe/qdmp/groups/MarkGroupTest.java b/java/src/test/java/io/github/echotechfe/qdmp/groups/MarkGroupTest.java index d620ac0..fce58a5 100644 --- a/java/src/test/java/io/github/echotechfe/qdmp/groups/MarkGroupTest.java +++ b/java/src/test/java/io/github/echotechfe/qdmp/groups/MarkGroupTest.java @@ -11,11 +11,14 @@ import io.github.echotechfe.qdmp.generated.MarkAdd200ResponseAllOfData; import io.github.echotechfe.qdmp.generated.MarkAddRequest; import io.github.echotechfe.qdmp.generated.MarkAddRequestRating; +import io.github.echotechfe.qdmp.generated.MarkBatchAddRequest; +import io.github.echotechfe.qdmp.generated.MarkBatchAddResponseAllOfData; import io.github.echotechfe.qdmp.generated.MarkDetail200ResponseAllOfData; import io.github.echotechfe.qdmp.generated.MarkList200ResponseAllOfData; import io.github.echotechfe.qdmp.generated.MarkSearch200ResponseAllOfData; import io.github.echotechfe.qdmp.testsupport.TestClients; import java.io.IOException; +import java.util.List; import okhttp3.HttpUrl; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; @@ -75,6 +78,30 @@ void add_success_serializesRequestBody_andParsesResponse() throws Exception { assertThat(body.get("rating").get("value").asInt()).isEqualTo(5); } + @Test + void batchAdd_success_sendsSpuIdsAndParsesResult() throws Exception { + server.enqueue( + new MockResponse() + .setResponseCode(200) + .setBody( + "{\"code\":\"0\",\"message\":\"ok\",\"data\":{\"result\":{\"1\":\"mark-1\"}}}")); + QdmpClient client = TestClients.create(server); + + MarkBatchAddResponseAllOfData result = + client + .mark() + .batchAdd( + QdmpContext.of("user-access-token"), + new MarkBatchAddRequest().spuIds(List.of("1"))); + + assertThat(result.getResult()).containsEntry("1", "mark-1"); + RecordedRequest recorded = server.takeRequest(); + assertThat(recorded.getMethod()).isEqualTo("POST"); + assertThat(recorded.getPath()).isEqualTo("/mark/v1/batch/add"); + assertThat(JSON.readTree(recorded.getBody().readUtf8()).get("spuIds").get(0).asText()) + .isEqualTo("1"); + } + @Test void add_http401_code10005_throwsQdmpApiError() { server.enqueue( diff --git a/java/src/test/java/io/github/echotechfe/qdmp/groups/PostCommentGroupTest.java b/java/src/test/java/io/github/echotechfe/qdmp/groups/PostCommentGroupTest.java new file mode 100644 index 0000000..1c255ba --- /dev/null +++ b/java/src/test/java/io/github/echotechfe/qdmp/groups/PostCommentGroupTest.java @@ -0,0 +1,131 @@ +package io.github.echotechfe.qdmp.groups; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import io.github.echotechfe.qdmp.QdmpClient; +import io.github.echotechfe.qdmp.QdmpContext; +import io.github.echotechfe.qdmp.generated.CommentCreateRequest; +import io.github.echotechfe.qdmp.generated.CommentLikeRequest; +import io.github.echotechfe.qdmp.generated.CommentReplyRequest; +import io.github.echotechfe.qdmp.testsupport.TestClients; +import java.io.IOException; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class PostCommentGroupTest { + private MockWebServer server; + + @BeforeEach + void startServer() throws IOException { + server = new MockWebServer(); + server.start(); + } + + @AfterEach + void stopServer() throws IOException { + server.shutdown(); + } + + @Test + void postEndpoints_useDocumentedMethodsQueriesAndMapData() throws Exception { + server.enqueue(ok("{\"id\":\"1\"}")); + server.enqueue(ok("{\"items\":[]}")); + server.enqueue(ok("{\"items\":[]}")); + QdmpClient client = TestClients.create(server); + assertThat(client.post().detail(QdmpContext.of("token"), "1")).containsEntry("id", "1"); + client.post().list(QdmpContext.of("token"), "0", null); + client.post().myList(QdmpContext.of("token"), null, "20"); + assertThat(server.takeRequest().getPath()).isEqualTo("/post/v1/detail?postId=1"); + assertThat(server.takeRequest().getPath()).isEqualTo("/post/v1/list?offset=0"); + assertThat(server.takeRequest().getPath()).isEqualTo("/post/v1/me/list?limit=20"); + } + + @Test + void commentEndpoints_useNumericPathsOptionalQueriesBodiesAndDtos() throws Exception { + server.enqueue(ok("{\"id\":\"2\"}")); + server.enqueue(ok("{\"id\":\"3\"}")); + server.enqueue(new MockResponse().setBody("{\"code\":\"0\",\"message\":\"ok\"}")); + server.enqueue(ok("{\"items\":[],\"count\":0}")); + server.enqueue(ok("{\"items\":[],\"hasMore\":false,\"count\":0}")); + QdmpClient client = TestClients.create(server); + assertThat( + client + .comment() + .create( + QdmpContext.of("token"), new CommentCreateRequest().postId("1").content("hi")) + .getId()) + .isEqualTo("2"); + assertThat( + client + .comment() + .reply(QdmpContext.of("token"), "1", new CommentReplyRequest().content("reply")) + .getId()) + .isEqualTo("3"); + client.comment().like(QdmpContext.of("token"), "1", new CommentLikeRequest().liked(true)); + assertThat(client.comment().postComments(QdmpContext.of("token"), "1", null, "0").getCount()) + .isZero(); + assertThat(client.comment().replies(QdmpContext.of("token"), "1", "10", "next").getHasMore()) + .isFalse(); + assertThat(server.takeRequest().getMethod()).isEqualTo("POST"); + assertThat(server.takeRequest().getPath()).isEqualTo("/comment/1/reply"); + assertThat(server.takeRequest().getPath()).isEqualTo("/comment/1/like"); + assertThat(server.takeRequest().getPath()).isEqualTo("/post/1/comments?offset=0"); + assertThat(server.takeRequest().getPath()).isEqualTo("/comment/1/replies?limit=10&cursor=next"); + } + + @Test + void postAndCommentGroups_rejectNullContextBeforeNetwork() { + QdmpClient client = TestClients.create(server); + assertThatThrownBy(() -> client.post().detail(null, "1")) + .isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> client.comment().like(null, "1", new CommentLikeRequest().liked(true))) + .isInstanceOf(NullPointerException.class); + assertThat(server.getRequestCount()).isEqualTo(0); + } + + @Test + void commentEndpoints_rejectDotSegmentIdsBeforeNetwork() { + QdmpClient client = TestClients.create(server); + assertThatThrownBy( + () -> client.comment().reply(QdmpContext.of("token"), "..", new CommentReplyRequest())) + .isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy( + () -> client.comment().like(QdmpContext.of("token"), "..", new CommentLikeRequest())) + .isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy( + () -> client.comment().postComments(QdmpContext.of("token"), "..", null, null)) + .isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> client.comment().replies(QdmpContext.of("token"), "..", null, null)) + .isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy( + () -> client.comment().reply(QdmpContext.of("token"), null, new CommentReplyRequest())) + .isInstanceOf(NullPointerException.class); + assertThatThrownBy( + () -> client.comment().like(QdmpContext.of("token"), null, new CommentLikeRequest())) + .isInstanceOf(NullPointerException.class); + assertThatThrownBy( + () -> client.comment().postComments(QdmpContext.of("token"), null, null, null)) + .isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> client.comment().replies(QdmpContext.of("token"), null, null, null)) + .isInstanceOf(NullPointerException.class); + assertThat(server.getRequestCount()).isEqualTo(0); + } + + @Test + void like_acceptsSuccessfulResponseWithEmptyData() { + server.enqueue(ok("{}")); + QdmpClient client = TestClients.create(server); + + client.comment().like(QdmpContext.of("token"), "1", new CommentLikeRequest().liked(true)); + + assertThat(server.getRequestCount()).isEqualTo(1); + } + + private static MockResponse ok(String data) { + return new MockResponse().setBody("{\"code\":\"0\",\"message\":\"ok\",\"data\":" + data + "}"); + } +} diff --git a/node/src/client.ts b/node/src/client.ts index aa1e462..80a9064 100644 --- a/node/src/client.ts +++ b/node/src/client.ts @@ -5,6 +5,8 @@ import {QdmpValidationError} from './errors.js'; import {GenaiGroup} from './groups/genai.js'; import {IslandGroup} from './groups/island.js'; import {MarkGroup} from './groups/mark.js'; +import {PostGroup} from './groups/post.js'; +import {CommentGroup} from './groups/comment.js'; import {SpuGroup} from './groups/spu.js'; import {TagGroup} from './groups/tag.js'; import {UserGroup} from './groups/user.js'; @@ -94,6 +96,8 @@ export class QdmpClient { readonly spu: SpuGroup; readonly tag: TagGroup; readonly mark: MarkGroup; + readonly post: PostGroup; + readonly comment: CommentGroup; readonly wishspu: WishSpuGroup; readonly genai: GenaiGroup; @@ -116,6 +120,8 @@ export class QdmpClient { this.spu = new SpuGroup(deps); this.tag = new TagGroup(deps); this.mark = new MarkGroup(deps); + this.post = new PostGroup(deps); + this.comment = new CommentGroup(deps); this.wishspu = new WishSpuGroup(deps); this.genai = new GenaiGroup(deps); } diff --git a/node/src/generated/route-meta.ts b/node/src/generated/route-meta.ts index 925a695..81846db 100644 --- a/node/src/generated/route-meta.ts +++ b/node/src/generated/route-meta.ts @@ -142,6 +142,69 @@ export const ROUTE_META: readonly RouteMeta[] = [ authScheme: 'genai', tokenRequired: true, }, + { + operationId: 'markBatchAdd', + method: 'POST', + path: '/mark/v1/batch/add', + authScheme: 'standard', + tokenRequired: true, + }, + { + operationId: 'postDetail', + method: 'GET', + path: '/post/v1/detail', + authScheme: 'standard', + tokenRequired: true, + }, + { + operationId: 'postList', + method: 'GET', + path: '/post/v1/list', + authScheme: 'standard', + tokenRequired: true, + }, + { + operationId: 'postMyList', + method: 'GET', + path: '/post/v1/me/list', + authScheme: 'standard', + tokenRequired: true, + }, + { + operationId: 'commentCreate', + method: 'POST', + path: '/comment', + authScheme: 'standard', + tokenRequired: true, + }, + { + operationId: 'commentReply', + method: 'POST', + path: '/comment/{commentId}/reply', + authScheme: 'standard', + tokenRequired: true, + }, + { + operationId: 'commentLike', + method: 'POST', + path: '/comment/{commentId}/like', + authScheme: 'standard', + tokenRequired: true, + }, + { + operationId: 'postComments', + method: 'GET', + path: '/post/{postId}/comments', + authScheme: 'standard', + tokenRequired: true, + }, + { + operationId: 'commentReplies', + method: 'GET', + path: '/comment/{commentId}/replies', + authScheme: 'standard', + tokenRequired: true, + }, ]; const routeByOperationId = new Map( diff --git a/node/src/generated/schema.d.ts b/node/src/generated/schema.d.ts index 7dd588c..bb4ab31 100644 --- a/node/src/generated/schema.d.ts +++ b/node/src/generated/schema.d.ts @@ -344,6 +344,186 @@ export interface paths { patch?: never; trace?: never; }; + "/mark/v1/batch/add": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 批量添加标记 + * @description 为多个 SPU 创建标记。 + */ + post: operations["markBatchAdd"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/post/v1/detail": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 获取帖子详情 + * @description 按帖子 ID 获取详情。 + */ + get: operations["postDetail"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/post/v1/list": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 获取帖子列表 + * @description 获取公开帖子列表;分页参数可省略。 + */ + get: operations["postList"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/post/v1/me/list": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 获取我的帖子列表 + * @description 获取当前用户的帖子列表;分页参数可省略。 + */ + get: operations["postMyList"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/comment": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 创建帖子评论 + * @description 为帖子创建评论;帖子不存在时返回 HTTP 404。 + */ + post: operations["commentCreate"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/comment/{commentId}/reply": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 回复评论 + * @description 回复指定评论;评论不存在时返回 HTTP 404。 + */ + post: operations["commentReply"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/comment/{commentId}/like": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * 点赞或取消点赞评论 + * @description 设置评论点赞状态;评论不存在时返回 HTTP 404。 + */ + post: operations["commentLike"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/post/{postId}/comments": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 获取帖子评论 + * @description 获取帖子顶级评论及首批回复;帖子不存在时返回 HTTP 404。 + */ + get: operations["postComments"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/comment/{commentId}/replies": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * 获取评论回复 + * @description 获取指定评论的回复;评论不存在时返回 HTTP 404。 + */ + get: operations["commentReplies"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; } export type webhooks = Record; export interface components { @@ -552,8 +732,168 @@ export interface components { [key: string]: unknown; })[]; }; + /** @description 批量添加标记。 */ + MarkBatchAddRequest: { + /** @description SPU ID 列表;源接口为 int64[],在线格式为 string[]。 */ + spuIds: string[]; + }; + /** @description 创建帖子评论。 */ + CommentCreateRequest: { + /** @description 帖子 ID;源接口为 int64,在线格式为 string,值必须大于 0。 */ + postId: string; + content: string; + }; + /** @description 回复评论。 */ + CommentReplyRequest: { + content: string; + }; + CommentLikeRequest: { + liked: boolean; + }; + CommentItem: { + id?: string; + content?: string; + createdAt?: string; + creator?: { + [key: string]: unknown; + }; + replyToUser?: { + [key: string]: unknown; + }; + rootCommentId?: string; + replyCommentId?: string; + /** Format: int32 */ + likeCount?: number; + liked?: boolean; + }; + CommentThread: { + comment?: components["schemas"]["CommentItem"]; + replies?: components["schemas"]["CommentItem"][]; + /** Format: int32 */ + replyCount?: number; + }; + MarkBatchAddResponse: components["schemas"]["BusinessEnvelopeBase"] & { + data?: { + result?: { + [key: string]: string; + }; + }; + }; + PostObjectResponse: components["schemas"]["BusinessEnvelopeBase"] & { + data?: { + [key: string]: unknown; + }; + }; + CommentCreateResponse: components["schemas"]["BusinessEnvelopeBase"] & { + data?: { + id?: string; + }; + }; + EmptyDataResponse: components["schemas"]["BusinessEnvelopeBase"] & { + data?: { + [key: string]: unknown; + }; + }; + PostCommentsResponse: components["schemas"]["BusinessEnvelopeBase"] & { + data?: { + items?: components["schemas"]["CommentThread"][]; + /** Format: int32 */ + count?: number; + }; + }; + CommentRepliesResponse: components["schemas"]["BusinessEnvelopeBase"] & { + data?: { + items?: components["schemas"]["CommentItem"][]; + hasMore?: boolean; + cursor?: string; + /** Format: int32 */ + count?: number; + }; + }; + }; + responses: { + /** @description 访问令牌缺失、非法或已过期。 */ + UnauthorizedResponse: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BusinessEnvelopeBase"]; + }; + }; + /** @description 请求引用的帖子或评论不存在。 */ + NotFoundResponse: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["BusinessEnvelopeBase"]; + }; + }; + /** @description 网关层错误。 */ + GatewayErrorResponse: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["GatewayErrorEnvelope"]; + }; + }; + /** @description 批量标记结果 */ + MarkBatchAddResponse: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["MarkBatchAddResponse"]; + }; + }; + /** @description 帖子数据(公开文档未定义 data 内部字段) */ + PostObjectResponse: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PostObjectResponse"]; + }; + }; + /** @description 创建评论或回复结果 */ + CommentCreateResponse: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommentCreateResponse"]; + }; + }; + /** @description 操作成功 */ + EmptyDataResponse: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["EmptyDataResponse"]; + }; + }; + /** @description 帖子评论 */ + PostCommentsResponse: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["PostCommentsResponse"]; + }; + }; + /** @description 评论回复 */ + CommentRepliesResponse: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CommentRepliesResponse"]; + }; + }; }; - responses: never; parameters: { /** @description 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 */ AccessTokenHeader: string; @@ -563,6 +903,20 @@ export interface components { GenaiAccessTokenHeader: string; /** @description GenAI 接口专用应用 ID。 */ GenaiAppIdHeader: string; + /** @description 帖子 ID;源接口为 int64,在线格式为 string,值必须大于 0。 */ + PostIdQuery: string; + /** @description 帖子 ID;源接口为 int64,在线格式为 string,值必须大于 0。 */ + PostIdPath: string; + /** @description 评论 ID;源接口为 int64,在线格式为 string,值必须大于 0。 */ + CommentIdPath: string; + /** @description 从 0 开始的分页偏移量。 */ + OffsetQuery: string; + /** @description 帖子列表每页数量,默认 20,最大 100。 */ + Limit100Query: string; + /** @description 评论或回复列表每页数量,默认 10,最大 20。 */ + Limit20Query: string; + /** @description 回复列表游标;首次请求省略,后续请求使用上一页响应返回的 cursor。 */ + CursorQuery: string; }; requestBodies: never; headers: never; @@ -2090,4 +2444,231 @@ export interface operations { }; }; }; + markBatchAdd: { + parameters: { + query?: never; + header: { + /** @description 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 */ + "access-token": components["parameters"]["AccessTokenHeader"]; + /** @description qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 */ + "x-echo-qdmp-version": components["parameters"]["QdmpVersionHeader"]; + }; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["MarkBatchAddRequest"]; + }; + }; + responses: { + 200: components["responses"]["MarkBatchAddResponse"]; + 401: components["responses"]["UnauthorizedResponse"]; + default: components["responses"]["GatewayErrorResponse"]; + }; + }; + postDetail: { + parameters: { + query: { + /** @description 帖子 ID;源接口为 int64,在线格式为 string,值必须大于 0。 */ + postId: components["parameters"]["PostIdQuery"]; + }; + header: { + /** @description 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 */ + "access-token": components["parameters"]["AccessTokenHeader"]; + /** @description qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 */ + "x-echo-qdmp-version": components["parameters"]["QdmpVersionHeader"]; + }; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: components["responses"]["PostObjectResponse"]; + 401: components["responses"]["UnauthorizedResponse"]; + default: components["responses"]["GatewayErrorResponse"]; + }; + }; + postList: { + parameters: { + query?: { + /** @description 从 0 开始的分页偏移量。 */ + offset?: components["parameters"]["OffsetQuery"]; + /** @description 帖子列表每页数量,默认 20,最大 100。 */ + limit?: components["parameters"]["Limit100Query"]; + }; + header: { + /** @description 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 */ + "access-token": components["parameters"]["AccessTokenHeader"]; + /** @description qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 */ + "x-echo-qdmp-version": components["parameters"]["QdmpVersionHeader"]; + }; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: components["responses"]["PostObjectResponse"]; + 401: components["responses"]["UnauthorizedResponse"]; + default: components["responses"]["GatewayErrorResponse"]; + }; + }; + postMyList: { + parameters: { + query?: { + /** @description 从 0 开始的分页偏移量。 */ + offset?: components["parameters"]["OffsetQuery"]; + /** @description 帖子列表每页数量,默认 20,最大 100。 */ + limit?: components["parameters"]["Limit100Query"]; + }; + header: { + /** @description 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 */ + "access-token": components["parameters"]["AccessTokenHeader"]; + /** @description qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 */ + "x-echo-qdmp-version": components["parameters"]["QdmpVersionHeader"]; + }; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: components["responses"]["PostObjectResponse"]; + 401: components["responses"]["UnauthorizedResponse"]; + default: components["responses"]["GatewayErrorResponse"]; + }; + }; + commentCreate: { + parameters: { + query?: never; + header: { + /** @description 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 */ + "access-token": components["parameters"]["AccessTokenHeader"]; + /** @description qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 */ + "x-echo-qdmp-version": components["parameters"]["QdmpVersionHeader"]; + }; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CommentCreateRequest"]; + }; + }; + responses: { + 200: components["responses"]["CommentCreateResponse"]; + 401: components["responses"]["UnauthorizedResponse"]; + 404: components["responses"]["NotFoundResponse"]; + default: components["responses"]["GatewayErrorResponse"]; + }; + }; + commentReply: { + parameters: { + query?: never; + header: { + /** @description 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 */ + "access-token": components["parameters"]["AccessTokenHeader"]; + /** @description qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 */ + "x-echo-qdmp-version": components["parameters"]["QdmpVersionHeader"]; + }; + path: { + /** @description 评论 ID;源接口为 int64,在线格式为 string,值必须大于 0。 */ + commentId: components["parameters"]["CommentIdPath"]; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CommentReplyRequest"]; + }; + }; + responses: { + 200: components["responses"]["CommentCreateResponse"]; + 401: components["responses"]["UnauthorizedResponse"]; + 404: components["responses"]["NotFoundResponse"]; + default: components["responses"]["GatewayErrorResponse"]; + }; + }; + commentLike: { + parameters: { + query?: never; + header: { + /** @description 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 */ + "access-token": components["parameters"]["AccessTokenHeader"]; + /** @description qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 */ + "x-echo-qdmp-version": components["parameters"]["QdmpVersionHeader"]; + }; + path: { + /** @description 评论 ID;源接口为 int64,在线格式为 string,值必须大于 0。 */ + commentId: components["parameters"]["CommentIdPath"]; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CommentLikeRequest"]; + }; + }; + responses: { + 200: components["responses"]["EmptyDataResponse"]; + 401: components["responses"]["UnauthorizedResponse"]; + 404: components["responses"]["NotFoundResponse"]; + default: components["responses"]["GatewayErrorResponse"]; + }; + }; + postComments: { + parameters: { + query?: { + /** @description 评论或回复列表每页数量,默认 10,最大 20。 */ + limit?: components["parameters"]["Limit20Query"]; + /** @description 从 0 开始的分页偏移量。 */ + offset?: components["parameters"]["OffsetQuery"]; + }; + header: { + /** @description 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 */ + "access-token": components["parameters"]["AccessTokenHeader"]; + /** @description qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 */ + "x-echo-qdmp-version": components["parameters"]["QdmpVersionHeader"]; + }; + path: { + /** @description 帖子 ID;源接口为 int64,在线格式为 string,值必须大于 0。 */ + postId: components["parameters"]["PostIdPath"]; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: components["responses"]["PostCommentsResponse"]; + 401: components["responses"]["UnauthorizedResponse"]; + 404: components["responses"]["NotFoundResponse"]; + default: components["responses"]["GatewayErrorResponse"]; + }; + }; + commentReplies: { + parameters: { + query?: { + /** @description 评论或回复列表每页数量,默认 10,最大 20。 */ + limit?: components["parameters"]["Limit20Query"]; + /** @description 回复列表游标;首次请求省略,后续请求使用上一页响应返回的 cursor。 */ + cursor?: components["parameters"]["CursorQuery"]; + }; + header: { + /** @description 用户授权凭证或应用凭证的访问令牌,通过 /auth/v1/token 获取。standard 鉴权方案下必须携带;SDK 层面只要求“传了某个凭证”,不区分是 CLIENT_CREDENTIALS 换的应用凭证还是 AUTHORIZATION_CODE 换的用户授权凭证——见该 operation 上的 x-qdmp-token-required。 */ + "access-token": components["parameters"]["AccessTokenHeader"]; + /** @description qdmp 协议版本标识,可由 SDK 配置项覆盖,默认值 "1.0"。仅 standard 鉴权方案需要。 */ + "x-echo-qdmp-version": components["parameters"]["QdmpVersionHeader"]; + }; + path: { + /** @description 评论 ID;源接口为 int64,在线格式为 string,值必须大于 0。 */ + commentId: components["parameters"]["CommentIdPath"]; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: components["responses"]["CommentRepliesResponse"]; + 401: components["responses"]["UnauthorizedResponse"]; + 404: components["responses"]["NotFoundResponse"]; + default: components["responses"]["GatewayErrorResponse"]; + }; + }; } diff --git a/node/src/groups/comment.ts b/node/src/groups/comment.ts new file mode 100644 index 0000000..722287c --- /dev/null +++ b/node/src/groups/comment.ts @@ -0,0 +1,94 @@ +import {requireAccessToken} from '../context.js'; +import {QdmpValidationError} from '../errors.js'; +import {getRouteMeta} from '../generated/route-meta.js'; +import type { + CommentCreateParams, + CommentLikeParams, + CommentRepliesData, + CommentReplyParams, + CommentRepliesParams, + CreateCommentData, + PostCommentsParams, + PostCommentsData, + QdmpContext, +} from '../types.js'; +import type {GroupDeps} from './base.js'; +export class CommentGroup { + constructor(private readonly deps: GroupDeps) {} + async create( + ctx: QdmpContext, + params: CommentCreateParams, + ): Promise { + return this.call('commentCreate', ctx, {}, params); + } + async reply( + ctx: QdmpContext, + params: CommentReplyParams, + ): Promise { + return this.call( + 'commentReply', + ctx, + {commentId: params.commentId}, + {content: params.content}, + ); + } + async like(ctx: QdmpContext, params: CommentLikeParams): Promise { + await this.call( + 'commentLike', + ctx, + {commentId: params.commentId}, + {liked: params.liked}, + ); + } + async postComments( + ctx: QdmpContext, + params: PostCommentsParams, + ): Promise { + return this.call('postComments', ctx, {postId: params.postId}, undefined, { + limit: params.limit, + offset: params.offset, + }); + } + async replies( + ctx: QdmpContext, + params: CommentRepliesParams, + ): Promise { + return this.call( + 'commentReplies', + ctx, + {commentId: params.commentId}, + undefined, + {limit: params.limit, cursor: params.cursor}, + ); + } + private async call( + operationId: string, + ctx: QdmpContext, + pathParams: Record, + body?: unknown, + query?: Record, + ): Promise { + const route = getRouteMeta(operationId); + const accessToken = requireAccessToken(ctx); + let path = route.path; + for (const [key, value] of Object.entries(pathParams)) { + validatePositiveId(key, value); + path = path.replace(`{${key}}`, value); + } + return this.deps.http.request({ + method: route.method, + path, + body, + query, + authScheme: route.authScheme, + accessToken, + qdmpVersion: this.deps.qdmpVersion, + }); + } +} + +function validatePositiveId(name: string, value: string): void { + if (!/^[1-9][0-9]*$/.test(value)) { + throw new QdmpValidationError(`${name} must be a positive integer ID`); + } +} diff --git a/node/src/groups/mark.ts b/node/src/groups/mark.ts index 6daf298..67c5b6f 100644 --- a/node/src/groups/mark.ts +++ b/node/src/groups/mark.ts @@ -3,6 +3,8 @@ import {getRouteMeta} from '../generated/route-meta.js'; import type { MarkAddData, MarkAddParams, + MarkBatchAddData, + MarkBatchAddParams, MarkDetailData, MarkDetailParams, MarkListData, @@ -29,6 +31,22 @@ export class MarkGroup { }); } + async batchAdd( + ctx: QdmpContext, + params: MarkBatchAddParams, + ): Promise { + const accessToken = requireAccessToken(ctx); + const route = getRouteMeta('markBatchAdd'); + return this.deps.http.request({ + method: route.method, + path: route.path, + authScheme: route.authScheme, + accessToken, + qdmpVersion: this.deps.qdmpVersion, + body: {spuIds: params.spuIds}, + }); + } + async list(ctx: QdmpContext, params: MarkListParams): Promise { const accessToken = requireAccessToken(ctx); const route = getRouteMeta('markList'); diff --git a/node/src/groups/post.ts b/node/src/groups/post.ts new file mode 100644 index 0000000..59036a8 --- /dev/null +++ b/node/src/groups/post.ts @@ -0,0 +1,47 @@ +import {requireAccessToken} from '../context.js'; +import {getRouteMeta} from '../generated/route-meta.js'; +import type { + PostDetailParams, + PostListParams, + PostData, + QdmpContext, +} from '../types.js'; +import type {GroupDeps} from './base.js'; + +export class PostGroup { + constructor(private readonly deps: GroupDeps) {} + async detail(ctx: QdmpContext, params: PostDetailParams): Promise { + return this.get('postDetail', ctx, {postId: params.postId}); + } + async list(ctx: QdmpContext, params: PostListParams = {}): Promise { + return this.get('postList', ctx, { + offset: params.offset, + limit: params.limit, + }); + } + async myList( + ctx: QdmpContext, + params: PostListParams = {}, + ): Promise { + return this.get('postMyList', ctx, { + offset: params.offset, + limit: params.limit, + }); + } + private async get( + operationId: string, + ctx: QdmpContext, + query: Record, + ): Promise { + const route = getRouteMeta(operationId); + const accessToken = requireAccessToken(ctx); + return this.deps.http.request({ + method: route.method, + path: route.path, + query, + authScheme: route.authScheme, + accessToken, + qdmpVersion: this.deps.qdmpVersion, + }); + } +} diff --git a/node/src/types.ts b/node/src/types.ts index bf857dc..3ba8bb8 100644 --- a/node/src/types.ts +++ b/node/src/types.ts @@ -1,5 +1,5 @@ /** - * Hand-authored request/response shapes for the 17 qdmp OpenAPI operations, + * Hand-authored request/response shapes for the 26 qdmp OpenAPI operations, * mirroring shared/openapi.yaml (int64/uint64 fields are string on the * wire — see that file's field-level notes for the real-world evidence). * These are intentionally plain, narrow interfaces rather than derived from @@ -168,6 +168,67 @@ export interface MarkRating { value?: number; } +/** int64 ID 在 JavaScript 中统一以字符串传递,避免精度丢失。 */ +export interface PostDetailParams { + postId: string; +} +export interface PostListParams { + offset?: string; + limit?: string; +} +export type PostData = Record; +export interface CommentCreateParams { + postId: string; + content: string; +} +export interface CommentReplyParams { + commentId: string; + content: string; +} +export interface CommentLikeParams { + commentId: string; + liked: boolean; +} +export interface PostCommentsParams { + postId: string; + limit?: string; + offset?: string; +} +export interface CommentRepliesParams { + commentId: string; + limit?: string; + cursor?: string; +} +export interface CreateCommentData { + id: string; +} +export interface CommentItem { + id: string; + content?: string; + createdAt?: string; + creator?: Record; + replyToUser?: Record; + rootCommentId?: string; + replyCommentId?: string; + likeCount?: number; + liked?: boolean; +} +export interface CommentThread { + comment?: CommentItem; + replies?: CommentItem[]; + replyCount?: number; +} +export interface PostCommentsData { + items?: CommentThread[]; + count?: number; +} +export interface CommentRepliesData { + items?: CommentItem[]; + count?: number; + hasMore?: boolean; + cursor?: string; +} + export interface MarkSpuSummary { id?: string; name?: string; @@ -178,6 +239,12 @@ export interface MarkAddParams { spuId: string; rating?: MarkRating; } +export interface MarkBatchAddParams { + spuIds: string[]; +} +export interface MarkBatchAddData { + result?: Record; +} export interface MarkAddData { id?: string; diff --git a/node/test/groups/post-comment.test.ts b/node/test/groups/post-comment.test.ts new file mode 100644 index 0000000..8dc04fa --- /dev/null +++ b/node/test/groups/post-comment.test.ts @@ -0,0 +1,160 @@ +import assert from 'node:assert/strict'; +import {test} from 'node:test'; +import type {MockAgent} from 'undici'; + +import {QdmpClient} from '../../src/client.js'; +import {QdmpValidationError} from '../../src/errors.js'; +import { + businessSuccess, + createMockAgent, + expectFailure, +} from '../helpers/mock-http.js'; + +function makeClient(mockAgent: MockAgent): QdmpClient { + return new QdmpClient({ + appId: 'app-id', + appSecret: 'app-secret', + dispatcher: mockAgent, + }); +} + +void test('mark.batchAdd、post.detail、comment.create 映射请求并解析响应', async () => { + const {mockAgent, pool} = createMockAgent(); + pool + .intercept({ + path: '/mark/v1/batch/add', + method: 'POST', + body: JSON.stringify({spuIds: ['1']}), + }) + .reply(200, businessSuccess({result: {1: 'm1'}})); + pool + .intercept({path: '/post/v1/detail', method: 'GET', query: {postId: '1'}}) + .reply(200, businessSuccess({id: '1'})); + pool + .intercept({ + path: '/comment', + method: 'POST', + body: JSON.stringify({postId: '1', content: '评论'}), + }) + .reply(200, businessSuccess({id: 'c1'})); + const client = makeClient(mockAgent); + const ctx = {accessToken: 'user-token'}; + assert.equal( + (await client.mark.batchAdd(ctx, {spuIds: ['1']})).result?.['1'], + 'm1', + ); + assert.equal((await client.post.detail(ctx, {postId: '1'})).id, '1'); + assert.equal( + (await client.comment.create(ctx, {postId: '1', content: '评论'})).id, + 'c1', + ); +}); + +void test('comment 动态路径接口拒绝非法 ID,且不发请求', async () => { + const {mockAgent, pool} = createMockAgent(); + pool + .intercept({ + path: '/comment/1/reply', + method: 'POST', + body: JSON.stringify({content: '回复'}), + }) + .reply(200, businessSuccess({id: 'c2'})); + pool + .intercept({ + path: '/post/1/comments', + method: 'GET', + query: {limit: '10', offset: '0'}, + }) + .reply(200, businessSuccess({items: [], count: 0})); + const client = makeClient(mockAgent); + const ctx = {accessToken: 'user-token'}; + await assert.rejects( + () => client.comment.reply(ctx, {commentId: '..', content: '回复'}), + QdmpValidationError, + ); + await assert.rejects( + () => + client.comment.postComments(ctx, { + postId: '..', + limit: '10', + offset: '0', + }), + QdmpValidationError, + ); + await assert.rejects( + () => client.comment.like(ctx, {commentId: '..', liked: true}), + QdmpValidationError, + ); + await assert.rejects( + () => client.comment.replies(ctx, {commentId: '..'}), + QdmpValidationError, + ); + assert.equal(mockAgent.pendingInterceptors().length, 2); +}); + +void test('post 列表与 comment.like/replies 映射 method、path、query、body 和响应', async () => { + const {mockAgent, pool} = createMockAgent(); + pool + .intercept({ + path: '/post/v1/list', + method: 'GET', + query: {offset: '0', limit: '20'}, + }) + .reply(200, businessSuccess({items: [{id: 'p1'}]})); + pool + .intercept({ + path: '/post/v1/me/list', + method: 'GET', + }) + .reply(200, businessSuccess({items: []})); + pool + .intercept({ + path: '/comment/1/like', + method: 'POST', + body: JSON.stringify({liked: true}), + }) + .reply(200, {code: '0', message: 'ok'}); + pool + .intercept({ + path: '/comment/1/replies', + method: 'GET', + query: {limit: '10', cursor: 'next'}, + }) + .reply(200, businessSuccess({items: [{id: 'r1'}], cursor: 'next'})); + const client = makeClient(mockAgent); + const ctx = {accessToken: 'user-token'}; + assert.deepEqual(await client.post.list(ctx, {offset: '0', limit: '20'}), { + items: [{id: 'p1'}], + }); + assert.deepEqual(await client.post.myList(ctx), {items: []}); + assert.equal( + await client.comment.like(ctx, {commentId: '1', liked: true}), + undefined, + ); + assert.equal( + ( + await client.comment.replies(ctx, { + commentId: '1', + limit: '10', + cursor: 'next', + }) + ).items?.[0]?.id, + 'r1', + ); +}); + +void test('新增分组缺 token 时不发请求', async () => { + const {mockAgent, pool} = createMockAgent(); + pool + .intercept({path: '/post/v1/detail', method: 'GET'}) + .reply(200, businessSuccess({})); + await expectFailure(() => + // @ts-expect-error 故意验证运行时缺 token 检查 + makeClient(mockAgent).post.detail({}, {postId: '1'}), + ); + await expectFailure(() => + // @ts-expect-error 故意验证运行时缺 token 检查 + makeClient(mockAgent).comment.create({}, {postId: '1', content: '评论'}), + ); + assert.equal(mockAgent.pendingInterceptors().length, 1); +}); diff --git a/shared/generated/route-meta.json b/shared/generated/route-meta.json index ea3fded..8d04e7b 100644 --- a/shared/generated/route-meta.json +++ b/shared/generated/route-meta.json @@ -117,5 +117,68 @@ "path": "/genai/v1/detail", "authScheme": "genai", "tokenRequired": true + }, + { + "operationId": "markBatchAdd", + "method": "POST", + "path": "/mark/v1/batch/add", + "authScheme": "standard", + "tokenRequired": true + }, + { + "operationId": "postDetail", + "method": "GET", + "path": "/post/v1/detail", + "authScheme": "standard", + "tokenRequired": true + }, + { + "operationId": "postList", + "method": "GET", + "path": "/post/v1/list", + "authScheme": "standard", + "tokenRequired": true + }, + { + "operationId": "postMyList", + "method": "GET", + "path": "/post/v1/me/list", + "authScheme": "standard", + "tokenRequired": true + }, + { + "operationId": "commentCreate", + "method": "POST", + "path": "/comment", + "authScheme": "standard", + "tokenRequired": true + }, + { + "operationId": "commentReply", + "method": "POST", + "path": "/comment/{commentId}/reply", + "authScheme": "standard", + "tokenRequired": true + }, + { + "operationId": "commentLike", + "method": "POST", + "path": "/comment/{commentId}/like", + "authScheme": "standard", + "tokenRequired": true + }, + { + "operationId": "postComments", + "method": "GET", + "path": "/post/{postId}/comments", + "authScheme": "standard", + "tokenRequired": true + }, + { + "operationId": "commentReplies", + "method": "GET", + "path": "/comment/{commentId}/replies", + "authScheme": "standard", + "tokenRequired": true } ] diff --git a/shared/openapi.yaml b/shared/openapi.yaml index 96f6b81..fd71ea9 100644 --- a/shared/openapi.yaml +++ b/shared/openapi.yaml @@ -93,6 +93,14 @@ { "name": "genai", "description": "GenAI:异步 AI 生成任务(经上游 AI 网关调度)" + }, + { + "name": "post", + "description": "社区发帖:查询帖子详情和列表" + }, + { + "name": "comment", + "description": "评论:发表评论、回复、点赞和查询评论" } ], "paths": { @@ -3437,6 +3445,333 @@ } } } + }, + "/mark/v1/batch/add": { + "post": { + "operationId": "markBatchAdd", + "summary": "批量添加标记", + "description": "为多个 SPU 创建标记。", + "tags": [ + "marks" + ], + "x-qdmp-auth-scheme": "standard", + "x-qdmp-token-required": true, + "parameters": [ + { + "$ref": "#/components/parameters/AccessTokenHeader" + }, + { + "$ref": "#/components/parameters/QdmpVersionHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MarkBatchAddRequest" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/responses/MarkBatchAddResponse" + }, + "401": {"$ref": "#/components/responses/UnauthorizedResponse"}, + "default": {"$ref": "#/components/responses/GatewayErrorResponse"} + } + } + }, + "/post/v1/detail": { + "get": { + "operationId": "postDetail", + "summary": "获取帖子详情", + "description": "按帖子 ID 获取详情。", + "tags": [ + "post" + ], + "x-qdmp-auth-scheme": "standard", + "x-qdmp-token-required": true, + "parameters": [ + { + "$ref": "#/components/parameters/AccessTokenHeader" + }, + { + "$ref": "#/components/parameters/QdmpVersionHeader" + }, + { + "$ref": "#/components/parameters/PostIdQuery" + } + ], + "responses": { + "200": { + "$ref": "#/components/responses/PostObjectResponse" + }, + "401": {"$ref": "#/components/responses/UnauthorizedResponse"}, + "default": {"$ref": "#/components/responses/GatewayErrorResponse"} + } + } + }, + "/post/v1/list": { + "get": { + "operationId": "postList", + "summary": "获取帖子列表", + "description": "获取公开帖子列表;分页参数可省略。", + "tags": [ + "post" + ], + "x-qdmp-auth-scheme": "standard", + "x-qdmp-token-required": true, + "parameters": [ + { + "$ref": "#/components/parameters/AccessTokenHeader" + }, + { + "$ref": "#/components/parameters/QdmpVersionHeader" + }, + { + "$ref": "#/components/parameters/OffsetQuery" + }, + { + "$ref": "#/components/parameters/Limit100Query" + } + ], + "responses": { + "200": { + "$ref": "#/components/responses/PostObjectResponse" + }, + "401": {"$ref": "#/components/responses/UnauthorizedResponse"}, + "default": {"$ref": "#/components/responses/GatewayErrorResponse"} + } + } + }, + "/post/v1/me/list": { + "get": { + "operationId": "postMyList", + "summary": "获取我的帖子列表", + "description": "获取当前用户的帖子列表;分页参数可省略。", + "tags": [ + "post" + ], + "x-qdmp-auth-scheme": "standard", + "x-qdmp-token-required": true, + "parameters": [ + { + "$ref": "#/components/parameters/AccessTokenHeader" + }, + { + "$ref": "#/components/parameters/QdmpVersionHeader" + }, + { + "$ref": "#/components/parameters/OffsetQuery" + }, + { + "$ref": "#/components/parameters/Limit100Query" + } + ], + "responses": { + "200": { + "$ref": "#/components/responses/PostObjectResponse" + }, + "401": {"$ref": "#/components/responses/UnauthorizedResponse"}, + "default": {"$ref": "#/components/responses/GatewayErrorResponse"} + } + } + }, + "/comment": { + "post": { + "operationId": "commentCreate", + "summary": "创建帖子评论", + "description": "为帖子创建评论;帖子不存在时返回 HTTP 404。", + "tags": [ + "comment" + ], + "x-qdmp-auth-scheme": "standard", + "x-qdmp-token-required": true, + "parameters": [ + { + "$ref": "#/components/parameters/AccessTokenHeader" + }, + { + "$ref": "#/components/parameters/QdmpVersionHeader" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommentCreateRequest" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/responses/CommentCreateResponse" + }, + "401": {"$ref": "#/components/responses/UnauthorizedResponse"}, + "404": {"$ref": "#/components/responses/NotFoundResponse"}, + "default": {"$ref": "#/components/responses/GatewayErrorResponse"} + } + } + }, + "/comment/{commentId}/reply": { + "post": { + "operationId": "commentReply", + "summary": "回复评论", + "description": "回复指定评论;评论不存在时返回 HTTP 404。", + "tags": [ + "comment" + ], + "x-qdmp-auth-scheme": "standard", + "x-qdmp-token-required": true, + "parameters": [ + { + "$ref": "#/components/parameters/AccessTokenHeader" + }, + { + "$ref": "#/components/parameters/QdmpVersionHeader" + }, + { + "$ref": "#/components/parameters/CommentIdPath" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommentReplyRequest" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/responses/CommentCreateResponse" + }, + "401": {"$ref": "#/components/responses/UnauthorizedResponse"}, + "404": {"$ref": "#/components/responses/NotFoundResponse"}, + "default": {"$ref": "#/components/responses/GatewayErrorResponse"} + } + } + }, + "/comment/{commentId}/like": { + "post": { + "operationId": "commentLike", + "summary": "点赞或取消点赞评论", + "description": "设置评论点赞状态;评论不存在时返回 HTTP 404。", + "tags": [ + "comment" + ], + "x-qdmp-auth-scheme": "standard", + "x-qdmp-token-required": true, + "parameters": [ + { + "$ref": "#/components/parameters/AccessTokenHeader" + }, + { + "$ref": "#/components/parameters/QdmpVersionHeader" + }, + { + "$ref": "#/components/parameters/CommentIdPath" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommentLikeRequest" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/responses/EmptyDataResponse" + }, + "401": {"$ref": "#/components/responses/UnauthorizedResponse"}, + "404": {"$ref": "#/components/responses/NotFoundResponse"}, + "default": {"$ref": "#/components/responses/GatewayErrorResponse"} + } + } + }, + "/post/{postId}/comments": { + "get": { + "operationId": "postComments", + "summary": "获取帖子评论", + "description": "获取帖子顶级评论及首批回复;帖子不存在时返回 HTTP 404。", + "tags": [ + "comment" + ], + "x-qdmp-auth-scheme": "standard", + "x-qdmp-token-required": true, + "parameters": [ + { + "$ref": "#/components/parameters/AccessTokenHeader" + }, + { + "$ref": "#/components/parameters/QdmpVersionHeader" + }, + { + "$ref": "#/components/parameters/PostIdPath" + }, + { + "$ref": "#/components/parameters/Limit20Query" + }, + { + "$ref": "#/components/parameters/OffsetQuery" + } + ], + "responses": { + "200": { + "$ref": "#/components/responses/PostCommentsResponse" + }, + "401": {"$ref": "#/components/responses/UnauthorizedResponse"}, + "404": {"$ref": "#/components/responses/NotFoundResponse"}, + "default": {"$ref": "#/components/responses/GatewayErrorResponse"} + } + } + }, + "/comment/{commentId}/replies": { + "get": { + "operationId": "commentReplies", + "summary": "获取评论回复", + "description": "获取指定评论的回复;评论不存在时返回 HTTP 404。", + "tags": [ + "comment" + ], + "x-qdmp-auth-scheme": "standard", + "x-qdmp-token-required": true, + "parameters": [ + { + "$ref": "#/components/parameters/AccessTokenHeader" + }, + { + "$ref": "#/components/parameters/QdmpVersionHeader" + }, + { + "$ref": "#/components/parameters/CommentIdPath" + }, + { + "$ref": "#/components/parameters/Limit20Query" + }, + { + "$ref": "#/components/parameters/CursorQuery" + } + ], + "responses": { + "200": { + "$ref": "#/components/responses/CommentRepliesResponse" + }, + "401": {"$ref": "#/components/responses/UnauthorizedResponse"}, + "404": {"$ref": "#/components/responses/NotFoundResponse"}, + "default": {"$ref": "#/components/responses/GatewayErrorResponse"} + } + } } }, "components": { @@ -3477,6 +3812,77 @@ "type": "string" }, "description": "GenAI 接口专用应用 ID。" + }, + "PostIdQuery": { + "name": "postId", + "in": "query", + "required": true, + "description": "帖子 ID;源接口为 int64,在线格式为 string,值必须大于 0。", + "schema": { + "type": "string", + "pattern": "^[1-9][0-9]*$" + } + }, + "PostIdPath": { + "name": "postId", + "in": "path", + "required": true, + "description": "帖子 ID;源接口为 int64,在线格式为 string,值必须大于 0。", + "schema": { + "type": "string", + "pattern": "^[1-9][0-9]*$" + } + }, + "CommentIdPath": { + "name": "commentId", + "in": "path", + "required": true, + "description": "评论 ID;源接口为 int64,在线格式为 string,值必须大于 0。", + "schema": { + "type": "string", + "pattern": "^[1-9][0-9]*$" + } + }, + "OffsetQuery": { + "name": "offset", + "in": "query", + "required": false, + "description": "从 0 开始的分页偏移量。", + "schema": { + "type": "string", + "default": "0" + } + }, + "Limit100Query": { + "name": "limit", + "in": "query", + "required": false, + "description": "帖子列表每页数量,默认 20,最大 100。", + "schema": { + "type": "string", + "default": "20", + "pattern": "^(100|[1-9][0-9]?)$" + } + }, + "Limit20Query": { + "name": "limit", + "in": "query", + "required": false, + "description": "评论或回复列表每页数量,默认 10,最大 20。", + "schema": { + "type": "string", + "default": "10", + "pattern": "^(20|1?[1-9])$" + } + }, + "CursorQuery": { + "name": "cursor", + "in": "query", + "required": false, + "description": "回复列表游标;首次请求省略,后续请求使用上一页响应返回的 cursor。", + "schema": { + "type": "string" + } } }, "schemas": { @@ -3914,6 +4320,327 @@ } } } + }, + "MarkBatchAddRequest": { + "type": "object", + "description": "批量添加标记。", + "properties": { + "spuIds": { + "type": "array", + "description": "SPU ID 列表;源接口为 int64[],在线格式为 string[]。", + "items": { + "type": "string" + } + } + }, + "required": [ + "spuIds" + ] + }, + "CommentCreateRequest": { + "type": "object", + "description": "创建帖子评论。", + "properties": { + "postId": { + "type": "string", + "description": "帖子 ID;源接口为 int64,在线格式为 string,值必须大于 0。", + "pattern": "^[1-9][0-9]*$" + }, + "content": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "postId", + "content" + ] + }, + "CommentReplyRequest": { + "type": "object", + "description": "回复评论。", + "properties": { + "content": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "content" + ] + }, + "CommentLikeRequest": { + "type": "object", + "properties": { + "liked": { + "type": "boolean" + } + }, + "required": [ + "liked" + ] + }, + "CommentItem": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "content": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "creator": { + "type": "object", + "additionalProperties": true + }, + "replyToUser": { + "type": "object", + "additionalProperties": true + }, + "rootCommentId": { + "type": "string" + }, + "replyCommentId": { + "type": "string" + }, + "likeCount": { + "type": "integer", + "format": "int32" + }, + "liked": { + "type": "boolean" + } + } + }, + "CommentThread": { + "type": "object", + "properties": { + "comment": { + "$ref": "#/components/schemas/CommentItem" + }, + "replies": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CommentItem" + } + }, + "replyCount": { + "type": "integer", + "format": "int32" + } + } + }, + "MarkBatchAddResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/BusinessEnvelopeBase" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "result": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + } + ] + }, + "PostObjectResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/BusinessEnvelopeBase" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + } + } + } + ] + }, + "CommentCreateResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/BusinessEnvelopeBase" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + } + } + } + ] + }, + "EmptyDataResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/BusinessEnvelopeBase" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + } + } + } + ] + }, + "PostCommentsResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/BusinessEnvelopeBase" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CommentThread" + } + }, + "count": { + "type": "integer", + "format": "int32" + } + } + } + } + } + ] + }, + "CommentRepliesResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/BusinessEnvelopeBase" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CommentItem" + } + }, + "hasMore": { + "type": "boolean" + }, + "cursor": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "int32" + } + } + } + } + } + ] + } + }, + "responses": { + "UnauthorizedResponse": { + "description": "访问令牌缺失、非法或已过期。", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BusinessEnvelopeBase"}}} + }, + "NotFoundResponse": { + "description": "请求引用的帖子或评论不存在。", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BusinessEnvelopeBase"}}} + }, + "GatewayErrorResponse": { + "description": "网关层错误。", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GatewayErrorEnvelope"}}} + }, + "MarkBatchAddResponse": { + "description": "批量标记结果", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MarkBatchAddResponse" + } + } + } + }, + "PostObjectResponse": { + "description": "帖子数据(公开文档未定义 data 内部字段)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PostObjectResponse" + } + } + } + }, + "CommentCreateResponse": { + "description": "创建评论或回复结果", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommentCreateResponse" + } + } + } + }, + "EmptyDataResponse": { + "description": "操作成功", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmptyDataResponse" + } + } + } + }, + "PostCommentsResponse": { + "description": "帖子评论", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PostCommentsResponse" + } + } + } + }, + "CommentRepliesResponse": { + "description": "评论回复", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommentRepliesResponse" + } + } + } } } }