Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 759e8384dd | |||
| c85fad0d11 | |||
| 937527d657 | |||
| 99d643de39 | |||
| aa30b879ef | |||
| 9c01669ef2 | |||
| d495e168fd | |||
| 0639bc973f | |||
| a9368ce340 | |||
|
|
c18bd4372f | ||
|
|
0a14025092 | ||
| 687d4face8 | |||
| 24d0d1f8a5 | |||
| ae060d8901 | |||
| 2b3a0e0afa | |||
|
|
92c6089096 | ||
| bff4e13941 | |||
| 05c423cb6d | |||
| b73dd20458 | |||
| 6da16e7829 | |||
| 462c87b083 | |||
| afada2e43e | |||
| ae92d3d86a | |||
| 9faf31971c | |||
|
|
d53ace3306 | ||
|
|
5f9aad3732 | ||
|
|
16c6bae7d1 | ||
|
|
8398fc4a6f | ||
|
|
2413a185a2 | ||
|
|
5fe4be61b9 | ||
| 7bacad6415 | |||
| 94f34d9562 | |||
|
|
cfe6f2b756 | ||
|
|
0518b547d8 | ||
|
|
dea013471a | ||
|
|
a68502d957 | ||
| 27c26099e2 | |||
|
|
19fc4c0f77 | ||
|
|
eae2db4942 | ||
|
|
0d45477f93 | ||
|
|
a093ab9e9c | ||
|
|
a60132086d | ||
|
|
b152fbe01b | ||
|
|
796ebd33b9 | ||
|
|
7379c0b84e | ||
|
|
b6c071fcec | ||
|
|
665c3e3b6a | ||
|
|
6b63afbdff | ||
|
|
eb33d725eb | ||
|
|
d9233a0606 | ||
| 181135eae4 | |||
|
|
b9259f1300 | ||
|
|
a753595b12 | ||
| 771ef3125b | |||
|
|
2eae0aa1a5 | ||
| 5756c0ea83 | |||
| 7c832a5d54 | |||
| f54a42d0a0 | |||
| ce7228652d | |||
| 949f219932 | |||
| 76a5578396 | |||
| c4d39be8aa | |||
| 3a1db9b0ce | |||
|
|
2feceb8be7 | ||
|
|
cba61d3f07 | ||
|
|
b5084d7299 | ||
|
|
9f2ff6a440 | ||
|
|
91a7668afd | ||
|
|
389aabac31 | ||
|
|
6d947e21cc | ||
|
|
4c9bd2d0e8 | ||
|
|
28ac17d51a | ||
|
|
b1d3fbabf4 | ||
|
|
76c955838e | ||
|
|
c13b0d9d71 | ||
| 7cb1553174 | |||
| ccc553850c | |||
| 26825e6ebf | |||
| e46787512c | |||
| 5ecb8c5a3a | |||
| 95c805efec | |||
| 315911dc2d | |||
| 6c729bb8bd | |||
|
|
488eee0e9b | ||
|
|
8992b0c048 | ||
|
|
b86381b0b7 | ||
|
|
f3fd2ddcac | ||
| cf1a4e45db | |||
| 3847142b91 | |||
|
|
b20b2c4e3f | ||
| c0a1f135cd | |||
| 47b4750d6e |
3258
api/aryshare/ayrshare.pb.go
Normal file
3258
api/aryshare/ayrshare.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
194
api/aryshare/ayrshare.validator.pb.go
Normal file
194
api/aryshare/ayrshare.validator.pb.go
Normal file
@ -0,0 +1,194 @@
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: pb/ayrshare.proto
|
||||
|
||||
package aryshare
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
math "math"
|
||||
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
_ "github.com/mwitkow/go-proto-validators"
|
||||
github_com_mwitkow_go_proto_validators "github.com/mwitkow/go-proto-validators"
|
||||
_ "google.golang.org/protobuf/types/descriptorpb"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
func (this *UserTag) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *InstagramOptions) Validate() error {
|
||||
for _, item := range this.UserTags {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("UserTags", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *TikTokOptions) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *PostRequest) Validate() error {
|
||||
if this.Post == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Post", fmt.Errorf(`post内容不能为空`))
|
||||
}
|
||||
if len(this.Platforms) < 1 {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Platforms", fmt.Errorf(`platforms平台列表不能为空`))
|
||||
}
|
||||
if this.InstagramOptions != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.InstagramOptions); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("InstagramOptions", err)
|
||||
}
|
||||
}
|
||||
if this.TikTokOptions != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.TikTokOptions); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("TikTokOptions", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *PostId) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *PostItem) Validate() error {
|
||||
for _, item := range this.PostIds {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("PostIds", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *PostResponse) Validate() error {
|
||||
for _, item := range this.Posts {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Posts", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, item := range this.PostIds {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("PostIds", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *GetPostRequest) Validate() error {
|
||||
if this.Id == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Id", fmt.Errorf(`帖子ID不能为空`))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *GetPostResponse) Validate() error {
|
||||
for _, item := range this.PostIds {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("PostIds", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *GetUserRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *Timestamp) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *TwitterUsage) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *DisplayName) Validate() error {
|
||||
if this.TwitterUsage != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.TwitterUsage); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("TwitterUsage", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *GetUserResponse) Validate() error {
|
||||
if this.Created != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Created); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Created", err)
|
||||
}
|
||||
}
|
||||
for _, item := range this.DisplayNames {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("DisplayNames", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *CreateProfileRequest) Validate() error {
|
||||
if this.Title == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Title", fmt.Errorf(`title不能为空`))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *CreateProfileResponse) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *GetProfilesRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *ProfileItem) Validate() error {
|
||||
if this.Created != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Created); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Created", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *Pagination) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *GetProfilesResponse) Validate() error {
|
||||
for _, item := range this.Profiles {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Profiles", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if this.Pagination != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Pagination); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Pagination", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *Email) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *GenerateJWTRequest) Validate() error {
|
||||
if this.Domain == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Domain", fmt.Errorf(`domain不能为空`))
|
||||
}
|
||||
if this.PrivateKey == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("PrivateKey", fmt.Errorf(`privateKey不能为空`))
|
||||
}
|
||||
if this.ProfileKey == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("ProfileKey", fmt.Errorf(`profileKey不能为空`))
|
||||
}
|
||||
if this.Email != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Email); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Email", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *GenerateJWTResponse) Validate() error {
|
||||
return nil
|
||||
}
|
||||
378
api/aryshare/ayrshare_triple.pb.go
Normal file
378
api/aryshare/ayrshare_triple.pb.go
Normal file
@ -0,0 +1,378 @@
|
||||
// Code generated by protoc-gen-go-triple. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-triple v1.0.8
|
||||
// - protoc v3.21.1
|
||||
// source: pb/ayrshare.proto
|
||||
|
||||
package aryshare
|
||||
|
||||
import (
|
||||
context "context"
|
||||
protocol "dubbo.apache.org/dubbo-go/v3/protocol"
|
||||
dubbo3 "dubbo.apache.org/dubbo-go/v3/protocol/dubbo3"
|
||||
invocation "dubbo.apache.org/dubbo-go/v3/protocol/invocation"
|
||||
grpc_go "github.com/dubbogo/grpc-go"
|
||||
codes "github.com/dubbogo/grpc-go/codes"
|
||||
metadata "github.com/dubbogo/grpc-go/metadata"
|
||||
status "github.com/dubbogo/grpc-go/status"
|
||||
common "github.com/dubbogo/triple/pkg/common"
|
||||
constant "github.com/dubbogo/triple/pkg/common/constant"
|
||||
triple "github.com/dubbogo/triple/pkg/triple"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc_go.SupportPackageIsVersion7
|
||||
|
||||
// AyrshareClient is the client API for Ayrshare service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type AyrshareClient interface {
|
||||
// 帖子相关 api
|
||||
Post(ctx context.Context, in *PostRequest, opts ...grpc_go.CallOption) (*PostResponse, common.ErrorWithAttachment)
|
||||
GetPost(ctx context.Context, in *GetPostRequest, opts ...grpc_go.CallOption) (*GetPostResponse, common.ErrorWithAttachment)
|
||||
// 用户相关 api
|
||||
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc_go.CallOption) (*GetUserResponse, common.ErrorWithAttachment)
|
||||
// 用户配置相关 api
|
||||
CreateProfile(ctx context.Context, in *CreateProfileRequest, opts ...grpc_go.CallOption) (*CreateProfileResponse, common.ErrorWithAttachment)
|
||||
GetProfiles(ctx context.Context, in *GetProfilesRequest, opts ...grpc_go.CallOption) (*GetProfilesResponse, common.ErrorWithAttachment)
|
||||
GenerateJWT(ctx context.Context, in *GenerateJWTRequest, opts ...grpc_go.CallOption) (*GenerateJWTResponse, common.ErrorWithAttachment)
|
||||
}
|
||||
|
||||
type ayrshareClient struct {
|
||||
cc *triple.TripleConn
|
||||
}
|
||||
|
||||
type AyrshareClientImpl struct {
|
||||
Post func(ctx context.Context, in *PostRequest) (*PostResponse, error)
|
||||
GetPost func(ctx context.Context, in *GetPostRequest) (*GetPostResponse, error)
|
||||
GetUser func(ctx context.Context, in *GetUserRequest) (*GetUserResponse, error)
|
||||
CreateProfile func(ctx context.Context, in *CreateProfileRequest) (*CreateProfileResponse, error)
|
||||
GetProfiles func(ctx context.Context, in *GetProfilesRequest) (*GetProfilesResponse, error)
|
||||
GenerateJWT func(ctx context.Context, in *GenerateJWTRequest) (*GenerateJWTResponse, error)
|
||||
}
|
||||
|
||||
func (c *AyrshareClientImpl) GetDubboStub(cc *triple.TripleConn) AyrshareClient {
|
||||
return NewAyrshareClient(cc)
|
||||
}
|
||||
|
||||
func (c *AyrshareClientImpl) XXX_InterfaceName() string {
|
||||
return "aryshare.Ayrshare"
|
||||
}
|
||||
|
||||
func NewAyrshareClient(cc *triple.TripleConn) AyrshareClient {
|
||||
return &ayrshareClient{cc}
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) Post(ctx context.Context, in *PostRequest, opts ...grpc_go.CallOption) (*PostResponse, common.ErrorWithAttachment) {
|
||||
out := new(PostResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/Post", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) GetPost(ctx context.Context, in *GetPostRequest, opts ...grpc_go.CallOption) (*GetPostResponse, common.ErrorWithAttachment) {
|
||||
out := new(GetPostResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetPost", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc_go.CallOption) (*GetUserResponse, common.ErrorWithAttachment) {
|
||||
out := new(GetUserResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetUser", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) CreateProfile(ctx context.Context, in *CreateProfileRequest, opts ...grpc_go.CallOption) (*CreateProfileResponse, common.ErrorWithAttachment) {
|
||||
out := new(CreateProfileResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/CreateProfile", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) GetProfiles(ctx context.Context, in *GetProfilesRequest, opts ...grpc_go.CallOption) (*GetProfilesResponse, common.ErrorWithAttachment) {
|
||||
out := new(GetProfilesResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetProfiles", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) GenerateJWT(ctx context.Context, in *GenerateJWTRequest, opts ...grpc_go.CallOption) (*GenerateJWTResponse, common.ErrorWithAttachment) {
|
||||
out := new(GenerateJWTResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GenerateJWT", in, out)
|
||||
}
|
||||
|
||||
// AyrshareServer is the server API for Ayrshare service.
|
||||
// All implementations must embed UnimplementedAyrshareServer
|
||||
// for forward compatibility
|
||||
type AyrshareServer interface {
|
||||
// 帖子相关 api
|
||||
Post(context.Context, *PostRequest) (*PostResponse, error)
|
||||
GetPost(context.Context, *GetPostRequest) (*GetPostResponse, error)
|
||||
// 用户相关 api
|
||||
GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error)
|
||||
// 用户配置相关 api
|
||||
CreateProfile(context.Context, *CreateProfileRequest) (*CreateProfileResponse, error)
|
||||
GetProfiles(context.Context, *GetProfilesRequest) (*GetProfilesResponse, error)
|
||||
GenerateJWT(context.Context, *GenerateJWTRequest) (*GenerateJWTResponse, error)
|
||||
mustEmbedUnimplementedAyrshareServer()
|
||||
}
|
||||
|
||||
// UnimplementedAyrshareServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedAyrshareServer struct {
|
||||
proxyImpl protocol.Invoker
|
||||
}
|
||||
|
||||
func (UnimplementedAyrshareServer) Post(context.Context, *PostRequest) (*PostResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Post not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) GetPost(context.Context, *GetPostRequest) (*GetPostResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPost not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) CreateProfile(context.Context, *CreateProfileRequest) (*CreateProfileResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateProfile not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) GetProfiles(context.Context, *GetProfilesRequest) (*GetProfilesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetProfiles not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) GenerateJWT(context.Context, *GenerateJWTRequest) (*GenerateJWTResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GenerateJWT not implemented")
|
||||
}
|
||||
func (s *UnimplementedAyrshareServer) XXX_SetProxyImpl(impl protocol.Invoker) {
|
||||
s.proxyImpl = impl
|
||||
}
|
||||
|
||||
func (s *UnimplementedAyrshareServer) XXX_GetProxyImpl() protocol.Invoker {
|
||||
return s.proxyImpl
|
||||
}
|
||||
|
||||
func (s *UnimplementedAyrshareServer) XXX_ServiceDesc() *grpc_go.ServiceDesc {
|
||||
return &Ayrshare_ServiceDesc
|
||||
}
|
||||
func (s *UnimplementedAyrshareServer) XXX_InterfaceName() string {
|
||||
return "aryshare.Ayrshare"
|
||||
}
|
||||
|
||||
func (UnimplementedAyrshareServer) mustEmbedUnimplementedAyrshareServer() {}
|
||||
|
||||
// UnsafeAyrshareServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to AyrshareServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeAyrshareServer interface {
|
||||
mustEmbedUnimplementedAyrshareServer()
|
||||
}
|
||||
|
||||
func RegisterAyrshareServer(s grpc_go.ServiceRegistrar, srv AyrshareServer) {
|
||||
s.RegisterService(&Ayrshare_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _Ayrshare_Post_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(PostRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("Post", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_GetPost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPostRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("GetPost", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetUserRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("GetUser", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_CreateProfile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateProfileRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("CreateProfile", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_GetProfiles_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetProfilesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("GetProfiles", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_GenerateJWT_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GenerateJWTRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("GenerateJWT", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// Ayrshare_ServiceDesc is the grpc_go.ServiceDesc for Ayrshare service.
|
||||
// It's only intended for direct use with grpc_go.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var Ayrshare_ServiceDesc = grpc_go.ServiceDesc{
|
||||
ServiceName: "aryshare.Ayrshare",
|
||||
HandlerType: (*AyrshareServer)(nil),
|
||||
Methods: []grpc_go.MethodDesc{
|
||||
{
|
||||
MethodName: "Post",
|
||||
Handler: _Ayrshare_Post_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPost",
|
||||
Handler: _Ayrshare_GetPost_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetUser",
|
||||
Handler: _Ayrshare_GetUser_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CreateProfile",
|
||||
Handler: _Ayrshare_CreateProfile_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetProfiles",
|
||||
Handler: _Ayrshare_GetProfiles_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GenerateJWT",
|
||||
Handler: _Ayrshare_GenerateJWT_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc_go.StreamDesc{},
|
||||
Metadata: "pb/ayrshare.proto",
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -530,10 +530,23 @@ func (this *TaskAssignRequest) Validate() error {
|
||||
func (this *UpdatePendingCountRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *AddHiddenTaskAssigneeRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *RecentAssignRecordsRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *RecentAssigneeItem) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *RecentAssignRecordsResponse) Validate() error {
|
||||
for _, item := range this.OperatorList {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("OperatorList", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *EmployeeTaskQueryRequest) Validate() error {
|
||||
@ -639,6 +652,22 @@ func (this *PendingUploadBreakdownResponse) Validate() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *PendingAssignRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *PendingAssignItem) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *PendingAssignResponse) Validate() error {
|
||||
for _, item := range this.Items {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Items", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *ArtistBundleBalanceRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -105,7 +105,10 @@ type BundleClient interface {
|
||||
GetPendingTaskLayout(ctx context.Context, in *GetPendingTaskLayoutReq, opts ...grpc_go.CallOption) (*GetPendingTaskLayoutResp, common.ErrorWithAttachment)
|
||||
SetPendingTaskLayout(ctx context.Context, in *SetPendingTaskLayoutReq, opts ...grpc_go.CallOption) (*SetPendingTaskLayoutResp, common.ErrorWithAttachment)
|
||||
GetPendingUploadBreakdown(ctx context.Context, in *PendingUploadBreakdownRequest, opts ...grpc_go.CallOption) (*PendingUploadBreakdownResponse, common.ErrorWithAttachment)
|
||||
GetPendingAssign(ctx context.Context, in *PendingAssignRequest, opts ...grpc_go.CallOption) (*PendingAssignResponse, common.ErrorWithAttachment)
|
||||
RevertTaskCompletionByUUIDItem(ctx context.Context, in *RevertTaskCompletionByUUIDItemRequest, opts ...grpc_go.CallOption) (*ComResponse, common.ErrorWithAttachment)
|
||||
AddHiddenTaskAssignee(ctx context.Context, in *AddHiddenTaskAssigneeRequest, opts ...grpc_go.CallOption) (*ComResponse, common.ErrorWithAttachment)
|
||||
// 数据指标
|
||||
MetricsBusiness(ctx context.Context, in *MetricsBusinessReq, opts ...grpc_go.CallOption) (*MetricsBusinessResp, common.ErrorWithAttachment)
|
||||
MetricsOperatingCreate(ctx context.Context, in *MetricsOperatingCreateReq, opts ...grpc_go.CallOption) (*MetricsOperatingCreateResp, common.ErrorWithAttachment)
|
||||
MetricsOperatingStatus(ctx context.Context, in *MetricsOperatingStatusReq, opts ...grpc_go.CallOption) (*MetricsOperatingStatusResp, common.ErrorWithAttachment)
|
||||
@ -189,7 +192,9 @@ type BundleClientImpl struct {
|
||||
GetPendingTaskLayout func(ctx context.Context, in *GetPendingTaskLayoutReq) (*GetPendingTaskLayoutResp, error)
|
||||
SetPendingTaskLayout func(ctx context.Context, in *SetPendingTaskLayoutReq) (*SetPendingTaskLayoutResp, error)
|
||||
GetPendingUploadBreakdown func(ctx context.Context, in *PendingUploadBreakdownRequest) (*PendingUploadBreakdownResponse, error)
|
||||
GetPendingAssign func(ctx context.Context, in *PendingAssignRequest) (*PendingAssignResponse, error)
|
||||
RevertTaskCompletionByUUIDItem func(ctx context.Context, in *RevertTaskCompletionByUUIDItemRequest) (*ComResponse, error)
|
||||
AddHiddenTaskAssignee func(ctx context.Context, in *AddHiddenTaskAssigneeRequest) (*ComResponse, error)
|
||||
MetricsBusiness func(ctx context.Context, in *MetricsBusinessReq) (*MetricsBusinessResp, error)
|
||||
MetricsOperatingCreate func(ctx context.Context, in *MetricsOperatingCreateReq) (*MetricsOperatingCreateResp, error)
|
||||
MetricsOperatingStatus func(ctx context.Context, in *MetricsOperatingStatusReq) (*MetricsOperatingStatusResp, error)
|
||||
@ -630,12 +635,24 @@ func (c *bundleClient) GetPendingUploadBreakdown(ctx context.Context, in *Pendin
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetPendingUploadBreakdown", in, out)
|
||||
}
|
||||
|
||||
func (c *bundleClient) GetPendingAssign(ctx context.Context, in *PendingAssignRequest, opts ...grpc_go.CallOption) (*PendingAssignResponse, common.ErrorWithAttachment) {
|
||||
out := new(PendingAssignResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetPendingAssign", in, out)
|
||||
}
|
||||
|
||||
func (c *bundleClient) RevertTaskCompletionByUUIDItem(ctx context.Context, in *RevertTaskCompletionByUUIDItemRequest, opts ...grpc_go.CallOption) (*ComResponse, common.ErrorWithAttachment) {
|
||||
out := new(ComResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/RevertTaskCompletionByUUIDItem", in, out)
|
||||
}
|
||||
|
||||
func (c *bundleClient) AddHiddenTaskAssignee(ctx context.Context, in *AddHiddenTaskAssigneeRequest, opts ...grpc_go.CallOption) (*ComResponse, common.ErrorWithAttachment) {
|
||||
out := new(ComResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/AddHiddenTaskAssignee", in, out)
|
||||
}
|
||||
|
||||
func (c *bundleClient) MetricsBusiness(ctx context.Context, in *MetricsBusinessReq, opts ...grpc_go.CallOption) (*MetricsBusinessResp, common.ErrorWithAttachment) {
|
||||
out := new(MetricsBusinessResp)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
@ -753,7 +770,10 @@ type BundleServer interface {
|
||||
GetPendingTaskLayout(context.Context, *GetPendingTaskLayoutReq) (*GetPendingTaskLayoutResp, error)
|
||||
SetPendingTaskLayout(context.Context, *SetPendingTaskLayoutReq) (*SetPendingTaskLayoutResp, error)
|
||||
GetPendingUploadBreakdown(context.Context, *PendingUploadBreakdownRequest) (*PendingUploadBreakdownResponse, error)
|
||||
GetPendingAssign(context.Context, *PendingAssignRequest) (*PendingAssignResponse, error)
|
||||
RevertTaskCompletionByUUIDItem(context.Context, *RevertTaskCompletionByUUIDItemRequest) (*ComResponse, error)
|
||||
AddHiddenTaskAssignee(context.Context, *AddHiddenTaskAssigneeRequest) (*ComResponse, error)
|
||||
// 数据指标
|
||||
MetricsBusiness(context.Context, *MetricsBusinessReq) (*MetricsBusinessResp, error)
|
||||
MetricsOperatingCreate(context.Context, *MetricsOperatingCreateReq) (*MetricsOperatingCreateResp, error)
|
||||
MetricsOperatingStatus(context.Context, *MetricsOperatingStatusReq) (*MetricsOperatingStatusResp, error)
|
||||
@ -978,9 +998,15 @@ func (UnimplementedBundleServer) SetPendingTaskLayout(context.Context, *SetPendi
|
||||
func (UnimplementedBundleServer) GetPendingUploadBreakdown(context.Context, *PendingUploadBreakdownRequest) (*PendingUploadBreakdownResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPendingUploadBreakdown not implemented")
|
||||
}
|
||||
func (UnimplementedBundleServer) GetPendingAssign(context.Context, *PendingAssignRequest) (*PendingAssignResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPendingAssign not implemented")
|
||||
}
|
||||
func (UnimplementedBundleServer) RevertTaskCompletionByUUIDItem(context.Context, *RevertTaskCompletionByUUIDItemRequest) (*ComResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RevertTaskCompletionByUUIDItem not implemented")
|
||||
}
|
||||
func (UnimplementedBundleServer) AddHiddenTaskAssignee(context.Context, *AddHiddenTaskAssigneeRequest) (*ComResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddHiddenTaskAssignee not implemented")
|
||||
}
|
||||
func (UnimplementedBundleServer) MetricsBusiness(context.Context, *MetricsBusinessReq) (*MetricsBusinessResp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method MetricsBusiness not implemented")
|
||||
}
|
||||
@ -3057,6 +3083,35 @@ func _Bundle_GetPendingUploadBreakdown_Handler(srv interface{}, ctx context.Cont
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Bundle_GetPendingAssign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(PendingAssignRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("GetPendingAssign", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Bundle_RevertTaskCompletionByUUIDItem_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RevertTaskCompletionByUUIDItemRequest)
|
||||
if err := dec(in); err != nil {
|
||||
@ -3086,6 +3141,35 @@ func _Bundle_RevertTaskCompletionByUUIDItem_Handler(srv interface{}, ctx context
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Bundle_AddHiddenTaskAssignee_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AddHiddenTaskAssigneeRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("AddHiddenTaskAssignee", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Bundle_MetricsBusiness_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(MetricsBusinessReq)
|
||||
if err := dec(in); err != nil {
|
||||
@ -3547,10 +3631,18 @@ var Bundle_ServiceDesc = grpc_go.ServiceDesc{
|
||||
MethodName: "GetPendingUploadBreakdown",
|
||||
Handler: _Bundle_GetPendingUploadBreakdown_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPendingAssign",
|
||||
Handler: _Bundle_GetPendingAssign_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RevertTaskCompletionByUUIDItem",
|
||||
Handler: _Bundle_RevertTaskCompletionByUUIDItem_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddHiddenTaskAssignee",
|
||||
Handler: _Bundle_AddHiddenTaskAssignee_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "MetricsBusiness",
|
||||
Handler: _Bundle_MetricsBusiness_Handler,
|
||||
|
||||
8473
api/cast/cast.pb.go
8473
api/cast/cast.pb.go
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.29.1
|
||||
// protoc v3.20.3
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v5.26.0
|
||||
// source: files.proto
|
||||
|
||||
package files
|
||||
@ -25,9 +25,12 @@ type FileListReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` // 目标文件夹路径
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"` // 用户空间的路径
|
||||
Sorting *Sorting `protobuf:"bytes,3,opt,name=sorting,proto3" json:"sorting,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"` // 目标文件夹路径
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"` // 用户空间的路径
|
||||
Sorting *Sorting `protobuf:"bytes,3,opt,name=sorting,proto3" json:"sorting"`
|
||||
Page int32 `protobuf:"varint,4,opt,name=page,proto3" json:"page"`
|
||||
PageSize int32 `protobuf:"varint,5,opt,name=pageSize,proto3" json:"pageSize"`
|
||||
Total int32 `protobuf:"varint,6,opt,name=total,proto3" json:"total"`
|
||||
}
|
||||
|
||||
func (x *FileListReq) Reset() {
|
||||
@ -83,21 +86,42 @@ func (x *FileListReq) GetSorting() *Sorting {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *FileListReq) GetPage() int32 {
|
||||
if x != nil {
|
||||
return x.Page
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *FileListReq) GetPageSize() int32 {
|
||||
if x != nil {
|
||||
return x.PageSize
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *FileListReq) GetTotal() int32 {
|
||||
if x != nil {
|
||||
return x.Total
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Items struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Size int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"`
|
||||
Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty"`
|
||||
Modified string `protobuf:"bytes,5,opt,name=modified,proto3" json:"modified,omitempty"`
|
||||
ModTime int64 `protobuf:"varint,6,opt,name=modTime,proto3" json:"modTime,omitempty"`
|
||||
Mode string `protobuf:"bytes,7,opt,name=mode,proto3" json:"mode,omitempty"`
|
||||
IsDir bool `protobuf:"varint,8,opt,name=isDir,proto3" json:"isDir,omitempty"`
|
||||
IsSymlink bool `protobuf:"varint,9,opt,name=isSymlink,proto3" json:"isSymlink,omitempty"`
|
||||
Type string `protobuf:"bytes,10,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name"`
|
||||
Size int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size"`
|
||||
Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension"`
|
||||
Modified string `protobuf:"bytes,5,opt,name=modified,proto3" json:"modified"`
|
||||
ModTime int64 `protobuf:"varint,6,opt,name=modTime,proto3" json:"modTime"`
|
||||
Mode string `protobuf:"bytes,7,opt,name=mode,proto3" json:"mode"`
|
||||
IsDir bool `protobuf:"varint,8,opt,name=isDir,proto3" json:"isDir"`
|
||||
IsSymlink bool `protobuf:"varint,9,opt,name=isSymlink,proto3" json:"isSymlink"`
|
||||
Type string `protobuf:"bytes,10,opt,name=type,proto3" json:"type"`
|
||||
}
|
||||
|
||||
func (x *Items) Reset() {
|
||||
@ -207,8 +231,8 @@ type Sorting struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
By string `protobuf:"bytes,1,opt,name=by,proto3" json:"by,omitempty"`
|
||||
Asc bool `protobuf:"varint,2,opt,name=asc,proto3" json:"asc,omitempty"`
|
||||
By string `protobuf:"bytes,1,opt,name=by,proto3" json:"by"`
|
||||
Asc bool `protobuf:"varint,2,opt,name=asc,proto3" json:"asc"`
|
||||
}
|
||||
|
||||
func (x *Sorting) Reset() {
|
||||
@ -262,20 +286,23 @@ type FileListResp struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Items []*Items `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
|
||||
NumDirs int32 `protobuf:"varint,2,opt,name=numDirs,proto3" json:"numDirs,omitempty"`
|
||||
NumFiles int32 `protobuf:"varint,3,opt,name=numFiles,proto3" json:"numFiles,omitempty"`
|
||||
Sorting *Sorting `protobuf:"bytes,4,opt,name=sorting,proto3" json:"sorting,omitempty"`
|
||||
Path string `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"`
|
||||
Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Size int64 `protobuf:"varint,7,opt,name=size,proto3" json:"size,omitempty"`
|
||||
Extension string `protobuf:"bytes,8,opt,name=extension,proto3" json:"extension,omitempty"`
|
||||
Modified string `protobuf:"bytes,9,opt,name=modified,proto3" json:"modified,omitempty"`
|
||||
ModTime int64 `protobuf:"varint,10,opt,name=modTime,proto3" json:"modTime,omitempty"`
|
||||
Mode string `protobuf:"bytes,11,opt,name=mode,proto3" json:"mode,omitempty"`
|
||||
IsDir bool `protobuf:"varint,12,opt,name=isDir,proto3" json:"isDir,omitempty"`
|
||||
IsSymlink bool `protobuf:"varint,13,opt,name=isSymlink,proto3" json:"isSymlink,omitempty"`
|
||||
Type string `protobuf:"bytes,14,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Items []*Items `protobuf:"bytes,1,rep,name=items,proto3" json:"items"`
|
||||
NumDirs int32 `protobuf:"varint,2,opt,name=numDirs,proto3" json:"numDirs"`
|
||||
NumFiles int32 `protobuf:"varint,3,opt,name=numFiles,proto3" json:"numFiles"`
|
||||
Sorting *Sorting `protobuf:"bytes,4,opt,name=sorting,proto3" json:"sorting"`
|
||||
Path string `protobuf:"bytes,5,opt,name=path,proto3" json:"path"`
|
||||
Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name"`
|
||||
Size int64 `protobuf:"varint,7,opt,name=size,proto3" json:"size"`
|
||||
Extension string `protobuf:"bytes,8,opt,name=extension,proto3" json:"extension"`
|
||||
Modified string `protobuf:"bytes,9,opt,name=modified,proto3" json:"modified"`
|
||||
ModTime int64 `protobuf:"varint,10,opt,name=modTime,proto3" json:"modTime"`
|
||||
Mode string `protobuf:"bytes,11,opt,name=mode,proto3" json:"mode"`
|
||||
IsDir bool `protobuf:"varint,12,opt,name=isDir,proto3" json:"isDir"`
|
||||
IsSymlink bool `protobuf:"varint,13,opt,name=isSymlink,proto3" json:"isSymlink"`
|
||||
Type string `protobuf:"bytes,14,opt,name=type,proto3" json:"type"`
|
||||
Page int32 `protobuf:"varint,15,opt,name=page,proto3" json:"page"`
|
||||
PageSize int32 `protobuf:"varint,16,opt,name=pageSize,proto3" json:"pageSize"`
|
||||
Total int32 `protobuf:"varint,17,opt,name=total,proto3" json:"total"`
|
||||
}
|
||||
|
||||
func (x *FileListResp) Reset() {
|
||||
@ -408,13 +435,34 @@ func (x *FileListResp) GetType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *FileListResp) GetPage() int32 {
|
||||
if x != nil {
|
||||
return x.Page
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *FileListResp) GetPageSize() int32 {
|
||||
if x != nil {
|
||||
return x.PageSize
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *FileListResp) GetTotal() int32 {
|
||||
if x != nil {
|
||||
return x.Total
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type CreateReq struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
}
|
||||
|
||||
func (x *CreateReq) Reset() {
|
||||
@ -506,8 +554,8 @@ type DeleteReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
}
|
||||
|
||||
func (x *DeleteReq) Reset() {
|
||||
@ -599,9 +647,9 @@ type UploadReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
Content []byte `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
Content []byte `protobuf:"bytes,3,opt,name=content,proto3" json:"content"`
|
||||
}
|
||||
|
||||
func (x *UploadReq) Reset() {
|
||||
@ -700,9 +748,9 @@ type SearchReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
Query string `protobuf:"bytes,3,opt,name=query,proto3" json:"query,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
Query string `protobuf:"bytes,3,opt,name=query,proto3" json:"query"`
|
||||
}
|
||||
|
||||
func (x *SearchReq) Reset() {
|
||||
@ -763,7 +811,7 @@ type SearchResp struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Items []*SearchResp_Nested `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
|
||||
Items []*SearchResp_Nested `protobuf:"bytes,1,rep,name=items,proto3" json:"items"`
|
||||
}
|
||||
|
||||
func (x *SearchResp) Reset() {
|
||||
@ -810,9 +858,9 @@ type TusCreateReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
Override bool `protobuf:"varint,3,opt,name=override,proto3" json:"override,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
Override bool `protobuf:"varint,3,opt,name=override,proto3" json:"override"`
|
||||
}
|
||||
|
||||
func (x *TusCreateReq) Reset() {
|
||||
@ -873,8 +921,8 @@ type TusCreateResp struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
UploadLength int64 `protobuf:"varint,1,opt,name=uploadLength,proto3" json:"uploadLength,omitempty"`
|
||||
UploadOffset int64 `protobuf:"varint,2,opt,name=uploadOffset,proto3" json:"uploadOffset,omitempty"`
|
||||
UploadLength int64 `protobuf:"varint,1,opt,name=uploadLength,proto3" json:"uploadLength"`
|
||||
UploadOffset int64 `protobuf:"varint,2,opt,name=uploadOffset,proto3" json:"uploadOffset"`
|
||||
}
|
||||
|
||||
func (x *TusCreateResp) Reset() {
|
||||
@ -928,10 +976,10 @@ type TusUploadReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
UploadOffset int64 `protobuf:"varint,3,opt,name=uploadOffset,proto3" json:"uploadOffset,omitempty"`
|
||||
Content []byte `protobuf:"bytes,4,opt,name=content,proto3" json:"content,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
UploadOffset int64 `protobuf:"varint,3,opt,name=uploadOffset,proto3" json:"uploadOffset"`
|
||||
Content []byte `protobuf:"bytes,4,opt,name=content,proto3" json:"content"`
|
||||
}
|
||||
|
||||
func (x *TusUploadReq) Reset() {
|
||||
@ -999,7 +1047,7 @@ type TusUploadResp struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
UploadOffset int64 `protobuf:"varint,1,opt,name=uploadOffset,proto3" json:"uploadOffset,omitempty"`
|
||||
UploadOffset int64 `protobuf:"varint,1,opt,name=uploadOffset,proto3" json:"uploadOffset"`
|
||||
}
|
||||
|
||||
func (x *TusUploadResp) Reset() {
|
||||
@ -1046,10 +1094,10 @@ type ResumableTransferReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
Offset int64 `protobuf:"varint,3,opt,name=offset,proto3" json:"offset,omitempty"`
|
||||
Length int64 `protobuf:"varint,4,opt,name=length,proto3" json:"length,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
Offset int64 `protobuf:"varint,3,opt,name=offset,proto3" json:"offset"`
|
||||
Length int64 `protobuf:"varint,4,opt,name=length,proto3" json:"length"`
|
||||
}
|
||||
|
||||
func (x *ResumableTransferReq) Reset() {
|
||||
@ -1117,7 +1165,7 @@ type ResumableTransferResp struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Content []byte `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"`
|
||||
Content []byte `protobuf:"bytes,1,opt,name=content,proto3" json:"content"`
|
||||
}
|
||||
|
||||
func (x *ResumableTransferResp) Reset() {
|
||||
@ -1164,8 +1212,8 @@ type FileInfoReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
}
|
||||
|
||||
func (x *FileInfoReq) Reset() {
|
||||
@ -1219,16 +1267,16 @@ type FileInfoResp struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Size int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"`
|
||||
Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty"`
|
||||
Modified string `protobuf:"bytes,5,opt,name=modified,proto3" json:"modified,omitempty"`
|
||||
Mode string `protobuf:"bytes,6,opt,name=mode,proto3" json:"mode,omitempty"`
|
||||
ModTime int64 `protobuf:"varint,7,opt,name=modTime,proto3" json:"modTime,omitempty"`
|
||||
IsDir bool `protobuf:"varint,8,opt,name=isDir,proto3" json:"isDir,omitempty"`
|
||||
IsSymlink bool `protobuf:"varint,9,opt,name=isSymlink,proto3" json:"isSymlink,omitempty"`
|
||||
Type string `protobuf:"bytes,10,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name"`
|
||||
Size int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size"`
|
||||
Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension"`
|
||||
Modified string `protobuf:"bytes,5,opt,name=modified,proto3" json:"modified"`
|
||||
Mode string `protobuf:"bytes,6,opt,name=mode,proto3" json:"mode"`
|
||||
ModTime int64 `protobuf:"varint,7,opt,name=modTime,proto3" json:"modTime"`
|
||||
IsDir bool `protobuf:"varint,8,opt,name=isDir,proto3" json:"isDir"`
|
||||
IsSymlink bool `protobuf:"varint,9,opt,name=isSymlink,proto3" json:"isSymlink"`
|
||||
Type string `protobuf:"bytes,10,opt,name=type,proto3" json:"type"`
|
||||
}
|
||||
|
||||
func (x *FileInfoResp) Reset() {
|
||||
@ -1338,9 +1386,9 @@ type PreviewReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
Size uint32 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` // 预览大小 0:256x256, 1:1080x1080
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
Size uint32 `protobuf:"varint,3,opt,name=size,proto3" json:"size"` // 预览大小 0:256x256, 1:1080x1080
|
||||
}
|
||||
|
||||
func (x *PreviewReq) Reset() {
|
||||
@ -1401,9 +1449,9 @@ type PreviewResp struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Content []byte `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"`
|
||||
FileName string `protobuf:"bytes,2,opt,name=fileName,proto3" json:"fileName,omitempty"`
|
||||
ModTime int64 `protobuf:"varint,3,opt,name=modTime,proto3" json:"modTime,omitempty"`
|
||||
Content []byte `protobuf:"bytes,1,opt,name=content,proto3" json:"content"`
|
||||
FileName string `protobuf:"bytes,2,opt,name=fileName,proto3" json:"fileName"`
|
||||
ModTime int64 `protobuf:"varint,3,opt,name=modTime,proto3" json:"modTime"`
|
||||
}
|
||||
|
||||
func (x *PreviewResp) Reset() {
|
||||
@ -1464,12 +1512,12 @@ type ActionReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
Action string `protobuf:"bytes,3,opt,name=action,proto3" json:"action,omitempty"`
|
||||
Destination string `protobuf:"bytes,4,opt,name=destination,proto3" json:"destination,omitempty"`
|
||||
Override bool `protobuf:"varint,5,opt,name=override,proto3" json:"override,omitempty"`
|
||||
Rename bool `protobuf:"varint,6,opt,name=rename,proto3" json:"rename,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
Action string `protobuf:"bytes,3,opt,name=action,proto3" json:"action"`
|
||||
Destination string `protobuf:"bytes,4,opt,name=destination,proto3" json:"destination"`
|
||||
Override bool `protobuf:"varint,5,opt,name=override,proto3" json:"override"`
|
||||
Rename bool `protobuf:"varint,6,opt,name=rename,proto3" json:"rename"`
|
||||
}
|
||||
|
||||
func (x *ActionReq) Reset() {
|
||||
@ -1589,10 +1637,10 @@ type DirDownloadReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
Files []string `protobuf:"bytes,3,rep,name=files,proto3" json:"files,omitempty"`
|
||||
Algo string `protobuf:"bytes,4,opt,name=algo,proto3" json:"algo,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
Files []string `protobuf:"bytes,3,rep,name=files,proto3" json:"files"`
|
||||
Algo string `protobuf:"bytes,4,opt,name=algo,proto3" json:"algo"`
|
||||
}
|
||||
|
||||
func (x *DirDownloadReq) Reset() {
|
||||
@ -1660,7 +1708,7 @@ type DirDownloadResp struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Content []byte `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"`
|
||||
Content []byte `protobuf:"bytes,1,opt,name=content,proto3" json:"content"`
|
||||
}
|
||||
|
||||
func (x *DirDownloadResp) Reset() {
|
||||
@ -1707,8 +1755,8 @@ type UsageReq struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"`
|
||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path"`
|
||||
UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath"`
|
||||
}
|
||||
|
||||
func (x *UsageReq) Reset() {
|
||||
@ -1762,8 +1810,8 @@ type UsageResp struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
|
||||
Used int64 `protobuf:"varint,2,opt,name=used,proto3" json:"used,omitempty"`
|
||||
Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total"`
|
||||
Used int64 `protobuf:"varint,2,opt,name=used,proto3" json:"used"`
|
||||
}
|
||||
|
||||
func (x *UsageResp) Reset() {
|
||||
@ -1817,11 +1865,11 @@ type SearchResp_Nested struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
IsDir bool `protobuf:"varint,1,opt,name=isDir,proto3" json:"isDir,omitempty"`
|
||||
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
|
||||
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Size int64 `protobuf:"varint,4,opt,name=size,proto3" json:"size,omitempty"`
|
||||
ModTime int64 `protobuf:"varint,5,opt,name=modTime,proto3" json:"modTime,omitempty"`
|
||||
IsDir bool `protobuf:"varint,1,opt,name=isDir,proto3" json:"isDir"`
|
||||
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path"`
|
||||
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name"`
|
||||
Size int64 `protobuf:"varint,4,opt,name=size,proto3" json:"size"`
|
||||
ModTime int64 `protobuf:"varint,5,opt,name=modTime,proto3" json:"modTime"`
|
||||
}
|
||||
|
||||
func (x *SearchResp_Nested) Reset() {
|
||||
@ -1895,234 +1943,243 @@ var File_files_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_files_proto_rawDesc = []byte{
|
||||
0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x73, 0x22, 0x71, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x69, 0x6c, 0x65, 0x73, 0x22, 0xb7, 0x01, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72,
|
||||
0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x28,
|
||||
0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x0e, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x52,
|
||||
0x07, 0x73, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08,
|
||||
0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61,
|
||||
0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0xf3,
|
||||
0x01, 0x0a, 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04,
|
||||
0x73, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x07, 0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65,
|
||||
0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x69, 0x73, 0x44, 0x69, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x44,
|
||||
0x69, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x73, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x18,
|
||||
0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x74, 0x79, 0x70, 0x65, 0x22, 0x2b, 0x0a, 0x07, 0x53, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x62, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x62, 0x79, 0x12,
|
||||
0x10, 0x0a, 0x03, 0x61, 0x73, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x73,
|
||||
0x63, 0x22, 0xc4, 0x03, 0x0a, 0x0c, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x12, 0x22, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x0c, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x52,
|
||||
0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x75, 0x6d, 0x44, 0x69, 0x72,
|
||||
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6e, 0x75, 0x6d, 0x44, 0x69, 0x72, 0x73,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x75, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x07,
|
||||
0x73, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73,
|
||||
0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69,
|
||||
0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d,
|
||||
0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x0b,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73,
|
||||
0x44, 0x69, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72,
|
||||
0x12, 0x1c, 0x0a, 0x09, 0x69, 0x73, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x0d, 0x20,
|
||||
0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79,
|
||||
0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69,
|
||||
0x7a, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69,
|
||||
0x7a, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x11, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x45, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65,
|
||||
0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22,
|
||||
0x0c, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x45, 0x0a,
|
||||
0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61,
|
||||
0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24,
|
||||
0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65,
|
||||
0x50, 0x61, 0x74, 0x68, 0x22, 0x0c, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65,
|
||||
0x73, 0x70, 0x22, 0x5f, 0x0a, 0x09, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70,
|
||||
0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65,
|
||||
0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72,
|
||||
0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x65, 0x6e, 0x74, 0x22, 0x0c, 0x0a, 0x0a, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73,
|
||||
0x70, 0x22, 0x5b, 0x0a, 0x09, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61,
|
||||
0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50,
|
||||
0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53,
|
||||
0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72,
|
||||
0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0xb2,
|
||||
0x01, 0x0a, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2e, 0x0a,
|
||||
0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x2e,
|
||||
0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x1a, 0x74, 0x0a,
|
||||
0x06, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74,
|
||||
0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64,
|
||||
0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x54,
|
||||
0x69, 0x6d, 0x65, 0x22, 0x64, 0x0a, 0x0c, 0x54, 0x75, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53,
|
||||
0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
|
||||
0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x28, 0x0a,
|
||||
0x07, 0x73, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
|
||||
0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x07,
|
||||
0x73, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x22, 0xf3, 0x01, 0x0a, 0x05, 0x49, 0x74, 0x65, 0x6d,
|
||||
0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a,
|
||||
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6d,
|
||||
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d,
|
||||
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72, 0x18, 0x08,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x69,
|
||||
0x73, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09,
|
||||
0x69, 0x73, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70,
|
||||
0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2b, 0x0a,
|
||||
0x07, 0x53, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x62, 0x79, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x62, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x73, 0x63, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x73, 0x63, 0x22, 0xfe, 0x02, 0x0a, 0x0c, 0x46,
|
||||
0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a, 0x05, 0x69,
|
||||
0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x6e, 0x75, 0x6d, 0x44, 0x69, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x07, 0x6e, 0x75, 0x6d, 0x44, 0x69, 0x72, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x75, 0x6d,
|
||||
0x46, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6e, 0x75, 0x6d,
|
||||
0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x53,
|
||||
0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70,
|
||||
0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18,
|
||||
0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x65,
|
||||
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x6f, 0x64,
|
||||
0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f, 0x64,
|
||||
0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d,
|
||||
0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72, 0x18, 0x0c, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x73, 0x53,
|
||||
0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73,
|
||||
0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18,
|
||||
0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x45, 0x0a, 0x09, 0x43,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d,
|
||||
0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61,
|
||||
0x74, 0x68, 0x22, 0x0c, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x22, 0x45, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74,
|
||||
0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61,
|
||||
0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70,
|
||||
0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x0c, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x5f, 0x0a, 0x09, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52,
|
||||
0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70,
|
||||
0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75,
|
||||
0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x0c, 0x0a, 0x0a, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64,
|
||||
0x52, 0x65, 0x73, 0x70, 0x22, 0x5b, 0x0a, 0x09, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65,
|
||||
0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61,
|
||||
0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73,
|
||||
0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x71,
|
||||
0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72,
|
||||
0x79, 0x22, 0xb2, 0x01, 0x0a, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70,
|
||||
0x12, 0x2e, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x18, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65,
|
||||
0x73, 0x70, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73,
|
||||
0x1a, 0x74, 0x0a, 0x06, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73,
|
||||
0x44, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d,
|
||||
0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x64, 0x0a, 0x0c, 0x54, 0x75, 0x73, 0x43, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73,
|
||||
0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x08, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x22, 0x57, 0x0a, 0x0d,
|
||||
0x54, 0x75, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a,
|
||||
0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x65, 0x6e, 0x67, 0x74,
|
||||
0x68, 0x12, 0x22, 0x0a, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65,
|
||||
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f,
|
||||
0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x86, 0x01, 0x0a, 0x0c, 0x54, 0x75, 0x73, 0x55, 0x70, 0x6c,
|
||||
0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73,
|
||||
0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68,
|
||||
0x12, 0x22, 0x0a, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x66,
|
||||
0x66, 0x73, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x33,
|
||||
0x0a, 0x0d, 0x54, 0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12,
|
||||
0x22, 0x0a, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x66, 0x66,
|
||||
0x73, 0x65, 0x74, 0x22, 0x80, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68,
|
||||
0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74,
|
||||
0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61,
|
||||
0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
|
||||
0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x31, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61,
|
||||
0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
|
||||
0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x47, 0x0a, 0x0b, 0x46, 0x69, 0x6c,
|
||||
0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d,
|
||||
0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61,
|
||||
0x74, 0x68, 0x22, 0xfa, 0x01, 0x0a, 0x0c, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52,
|
||||
0x65, 0x73, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73,
|
||||
0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a,
|
||||
0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x08, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64,
|
||||
0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07,
|
||||
0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72,
|
||||
0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x69, 0x73, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x09, 0x69, 0x73, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74,
|
||||
0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22,
|
||||
0x5a, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74,
|
||||
0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61,
|
||||
0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70,
|
||||
0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x5d, 0x0a, 0x0b, 0x50,
|
||||
0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x73, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x09, 0x41,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d,
|
||||
0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61,
|
||||
0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65,
|
||||
0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08,
|
||||
0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x22, 0x0c, 0x0a, 0x0a, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x74,
|
||||
0x0a, 0x0e, 0x44, 0x69, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71,
|
||||
0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1a, 0x0a,
|
||||
0x08, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x08, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x22, 0x57, 0x0a, 0x0d, 0x54, 0x75, 0x73,
|
||||
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x75, 0x70,
|
||||
0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x22,
|
||||
0x0a, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x66, 0x66, 0x73,
|
||||
0x65, 0x74, 0x22, 0x86, 0x01, 0x0a, 0x0c, 0x54, 0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64,
|
||||
0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53,
|
||||
0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
|
||||
0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x22, 0x0a,
|
||||
0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65,
|
||||
0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x33, 0x0a, 0x0d, 0x54,
|
||||
0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x22, 0x0a, 0x0c,
|
||||
0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74,
|
||||
0x22, 0x80, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72,
|
||||
0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74,
|
||||
0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a,
|
||||
0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50,
|
||||
0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6c,
|
||||
0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6c, 0x65, 0x6e,
|
||||
0x67, 0x74, 0x68, 0x22, 0x31, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c, 0x65,
|
||||
0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x47, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65,
|
||||
0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22,
|
||||
0xfa, 0x01, 0x0a, 0x0c, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63,
|
||||
0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65,
|
||||
0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69,
|
||||
0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x61, 0x6c, 0x67, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x61, 0x6c, 0x67, 0x6f, 0x22, 0x2b, 0x0a, 0x0f, 0x44, 0x69, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c,
|
||||
0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65,
|
||||
0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x6f,
|
||||
0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f,
|
||||
0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f,
|
||||
0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x6f, 0x64,
|
||||
0x54, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72, 0x18, 0x08, 0x20,
|
||||
0x01, 0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x73,
|
||||
0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69,
|
||||
0x73, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
|
||||
0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x5a, 0x0a, 0x0a,
|
||||
0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61,
|
||||
0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24,
|
||||
0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65,
|
||||
0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x5d, 0x0a, 0x0b, 0x50, 0x72, 0x65, 0x76,
|
||||
0x69, 0x65, 0x77, 0x52, 0x65, 0x73, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65,
|
||||
0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
|
||||
0x74, 0x22, 0x44, 0x0a, 0x08, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a,
|
||||
0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07,
|
||||
0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x09, 0x41, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65,
|
||||
0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69,
|
||||
0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,
|
||||
0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x76, 0x65,
|
||||
0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x76, 0x65,
|
||||
0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x0c, 0x0a,
|
||||
0x0a, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x74, 0x0a, 0x0e, 0x44,
|
||||
0x69, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74,
|
||||
0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61,
|
||||
0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70,
|
||||
0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x35, 0x0a, 0x09, 0x55, 0x73, 0x61, 0x67, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73,
|
||||
0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x75, 0x73, 0x65, 0x64, 0x32, 0xcb,
|
||||
0x05, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x31, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12,
|
||||
0x12, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73,
|
||||
0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x61, 0x6c, 0x67, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x6c, 0x67,
|
||||
0x6f, 0x22, 0x2b, 0x0a, 0x0f, 0x44, 0x69, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64,
|
||||
0x52, 0x65, 0x73, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x44,
|
||||
0x0a, 0x08, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61,
|
||||
0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24,
|
||||
0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65,
|
||||
0x50, 0x61, 0x74, 0x68, 0x22, 0x35, 0x0a, 0x09, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x64, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x75, 0x73, 0x65, 0x64, 0x32, 0xcb, 0x05, 0x0a, 0x04,
|
||||
0x46, 0x69, 0x6c, 0x65, 0x12, 0x31, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71,
|
||||
0x1a, 0x13, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12,
|
||||
0x12, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f,
|
||||
0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x04, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x12, 0x12, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x49,
|
||||
0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x46,
|
||||
0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2f, 0x0a,
|
||||
0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e,
|
||||
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2f,
|
||||
0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73,
|
||||
0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12,
|
||||
0x2f, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69,
|
||||
0x6c, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00,
|
||||
0x12, 0x2f, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22,
|
||||
0x00, 0x12, 0x38, 0x0a, 0x09, 0x54, 0x75, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x13,
|
||||
0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, 0x43,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x09, 0x54,
|
||||
0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x13, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73,
|
||||
0x2e, 0x54, 0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52,
|
||||
0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x6e,
|
||||
0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x43,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x06, 0x44,
|
||||
0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x44, 0x65,
|
||||
0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e,
|
||||
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x06,
|
||||
0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73,
|
||||
0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73,
|
||||
0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2f, 0x0a,
|
||||
0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e,
|
||||
0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x38,
|
||||
0x0a, 0x09, 0x54, 0x75, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x66, 0x69,
|
||||
0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
|
||||
0x1a, 0x14, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x09, 0x54, 0x75, 0x73, 0x55,
|
||||
0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x13, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75,
|
||||
0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70,
|
||||
0x22, 0x00, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x54,
|
||||
0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e,
|
||||
0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65,
|
||||
0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x76, 0x69,
|
||||
0x65, 0x77, 0x12, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x76, 0x69,
|
||||
0x65, 0x77, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x50, 0x72,
|
||||
0x65, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x06, 0x41,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x41, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e,
|
||||
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0b,
|
||||
0x44, 0x69, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x15, 0x2e, 0x66, 0x69,
|
||||
0x6c, 0x65, 0x73, 0x2e, 0x44, 0x69, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52,
|
||||
0x65, 0x71, 0x1a, 0x16, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x44, 0x69, 0x72, 0x44, 0x6f,
|
||||
0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2c,
|
||||
0x0a, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0f, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e,
|
||||
0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73,
|
||||
0x2e, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08,
|
||||
0x2e, 0x2f, 0x3b, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x72, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x73,
|
||||
0x75, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65,
|
||||
0x73, 0x70, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x12,
|
||||
0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x52,
|
||||
0x65, 0x71, 0x1a, 0x12, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x76, 0x69,
|
||||
0x65, 0x77, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0b, 0x44, 0x69, 0x72,
|
||||
0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x15, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73,
|
||||
0x2e, 0x44, 0x69, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a,
|
||||
0x16, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x44, 0x69, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c,
|
||||
0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2c, 0x0a, 0x05, 0x55,
|
||||
0x73, 0x61, 0x67, 0x65, 0x12, 0x0f, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x55, 0x73, 0x61,
|
||||
0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x55, 0x73,
|
||||
0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x3b,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@ -1,194 +0,0 @@
|
||||
syntax = "proto3";
|
||||
package files;
|
||||
|
||||
option go_package = "./;files";
|
||||
|
||||
service File {
|
||||
rpc List(FileListReq) returns (FileListResp) {} // 获取当前路径下的文件列表
|
||||
rpc Info(FileInfoReq) returns (FileInfoResp) {} // 获取文件信息
|
||||
rpc Create(CreateReq) returns (CreateResp) {} // 创建文件夹
|
||||
rpc Delete(DeleteReq) returns (DeleteResp) {} // 删除文件或文件夹
|
||||
rpc Search(searchReq) returns (searchResp) {} // 搜索
|
||||
rpc Upload(UploadReq) returns (UploadResp) {} // 文件上传
|
||||
rpc TusCreate(TusCreateReq) returns (TusCreateResp) {
|
||||
} // 分块文件上传:创建文件
|
||||
rpc TusUpload(TusUploadReq) returns (TusUploadResp) {
|
||||
} // 分块文件上传:上传文件块
|
||||
rpc ResumableTransfer(ResumableTransferReq) returns (ResumableTransferResp) {
|
||||
} // 断点续传的grpc实现
|
||||
rpc Preview(PreviewReq) returns (PreviewResp) {} // 文件预览
|
||||
rpc Action(ActionReq) returns (ActionResp) {} // 移动文件或重命名文件
|
||||
rpc DirDownload(DirDownloadReq) returns (stream DirDownloadResp) {
|
||||
} // 文件夹压缩下载
|
||||
rpc Usage(UsageReq) returns (UsageResp) {} //查看磁盘使用率
|
||||
}
|
||||
|
||||
message FileListReq {
|
||||
string path = 1; // 目标文件夹路径
|
||||
string userSpacePath = 2; // 用户空间的路径
|
||||
Sorting sorting = 3;
|
||||
}
|
||||
|
||||
message Items {
|
||||
string path = 1;
|
||||
string name = 2;
|
||||
int64 size = 3;
|
||||
string extension = 4;
|
||||
string modified = 5;
|
||||
int64 modTime = 6;
|
||||
string mode = 7;
|
||||
bool isDir = 8;
|
||||
bool isSymlink = 9;
|
||||
string type = 10;
|
||||
}
|
||||
|
||||
message Sorting {
|
||||
string by = 1;
|
||||
bool asc = 2;
|
||||
}
|
||||
|
||||
message FileListResp {
|
||||
repeated Items items = 1;
|
||||
int32 numDirs = 2;
|
||||
int32 numFiles = 3;
|
||||
Sorting sorting = 4;
|
||||
string path = 5;
|
||||
string name = 6;
|
||||
int64 size = 7;
|
||||
string extension = 8;
|
||||
string modified = 9;
|
||||
int64 modTime = 10;
|
||||
string mode = 11;
|
||||
bool isDir = 12;
|
||||
bool isSymlink = 13;
|
||||
string type = 14;
|
||||
}
|
||||
|
||||
message CreateReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
}
|
||||
|
||||
message CreateResp {}
|
||||
|
||||
message DeleteReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
}
|
||||
|
||||
message DeleteResp {}
|
||||
|
||||
message UploadReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
bytes content = 3;
|
||||
}
|
||||
|
||||
message UploadResp {}
|
||||
|
||||
message searchReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
string query = 3;
|
||||
}
|
||||
|
||||
message searchResp {
|
||||
message Nested {
|
||||
bool isDir = 1;
|
||||
string path = 2;
|
||||
string name = 3;
|
||||
int64 size = 4;
|
||||
int64 modTime = 5;
|
||||
}
|
||||
|
||||
repeated Nested items = 1;
|
||||
}
|
||||
|
||||
message TusCreateReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
bool override = 3;
|
||||
}
|
||||
|
||||
message TusCreateResp {
|
||||
int64 uploadLength = 1;
|
||||
int64 uploadOffset = 2;
|
||||
}
|
||||
|
||||
message TusUploadReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
int64 uploadOffset = 3;
|
||||
bytes content = 4;
|
||||
}
|
||||
|
||||
message TusUploadResp { int64 uploadOffset = 1; }
|
||||
|
||||
message ResumableTransferReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
int64 offset = 3;
|
||||
int64 length = 4;
|
||||
}
|
||||
|
||||
message ResumableTransferResp { bytes content = 1; }
|
||||
|
||||
message FileInfoReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
}
|
||||
|
||||
message FileInfoResp {
|
||||
string path = 1;
|
||||
string name = 2;
|
||||
int64 size = 3;
|
||||
string extension = 4;
|
||||
string modified = 5;
|
||||
string mode = 6;
|
||||
int64 modTime = 7;
|
||||
bool isDir = 8;
|
||||
bool isSymlink = 9;
|
||||
string type = 10;
|
||||
}
|
||||
|
||||
message PreviewReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
uint32 size = 3; // 预览大小 0:256x256, 1:1080x1080
|
||||
}
|
||||
|
||||
message PreviewResp {
|
||||
bytes content = 1;
|
||||
string fileName = 2;
|
||||
int64 modTime = 3;
|
||||
}
|
||||
|
||||
message ActionReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
string action = 3;
|
||||
string destination = 4;
|
||||
bool override = 5;
|
||||
bool rename = 6;
|
||||
}
|
||||
|
||||
message ActionResp {}
|
||||
|
||||
message DirDownloadReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
repeated string files = 3;
|
||||
string algo = 4;
|
||||
}
|
||||
|
||||
message DirDownloadResp { bytes content = 1; }
|
||||
|
||||
message UsageReq {
|
||||
string path = 1;
|
||||
string userSpacePath = 2;
|
||||
}
|
||||
|
||||
message UsageResp {
|
||||
int64 total = 1;
|
||||
int64 used = 2;
|
||||
}
|
||||
@ -1,14 +1,13 @@
|
||||
// Code generated by protoc-gen-go-triple. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-triple v1.0.8
|
||||
// - protoc v3.20.3
|
||||
// - protoc-gen-go-triple v1.0.5
|
||||
// - protoc v5.26.0
|
||||
// source: files.proto
|
||||
|
||||
package files
|
||||
|
||||
import (
|
||||
context "context"
|
||||
constant1 "dubbo.apache.org/dubbo-go/v3/common/constant"
|
||||
protocol "dubbo.apache.org/dubbo-go/v3/protocol"
|
||||
dubbo3 "dubbo.apache.org/dubbo-go/v3/protocol/dubbo3"
|
||||
invocation "dubbo.apache.org/dubbo-go/v3/protocol/invocation"
|
||||
@ -595,13 +594,6 @@ func _File_Action_Handler(srv interface{}, ctx context.Context, dec func(interfa
|
||||
|
||||
func _File_DirDownload_Handler(srv interface{}, stream grpc_go.ServerStream) error {
|
||||
_, ok := srv.(dubbo3.Dubbo3GrpcService)
|
||||
ctx := stream.Context()
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
stream.(grpc_go.CtxSetterStream).SetContext(context.WithValue(ctx, constant1.AttachmentKey, invAttachment))
|
||||
invo := invocation.NewRPCInvocation("DirDownload", nil, nil)
|
||||
if !ok {
|
||||
fmt.Println(invo)
|
||||
|
||||
3239
api/pb/aryshare/ayrshare.pb.go
Normal file
3239
api/pb/aryshare/ayrshare.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
194
api/pb/aryshare/ayrshare.validator.pb.go
Normal file
194
api/pb/aryshare/ayrshare.validator.pb.go
Normal file
@ -0,0 +1,194 @@
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: pb/ayrshare.proto
|
||||
|
||||
package aryshare
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
math "math"
|
||||
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
_ "github.com/mwitkow/go-proto-validators"
|
||||
github_com_mwitkow_go_proto_validators "github.com/mwitkow/go-proto-validators"
|
||||
_ "google.golang.org/protobuf/types/descriptorpb"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
func (this *UserTag) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *InstagramOptions) Validate() error {
|
||||
for _, item := range this.UserTags {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("UserTags", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *TikTokOptions) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *PostRequest) Validate() error {
|
||||
if this.Post == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Post", fmt.Errorf(`post内容不能为空`))
|
||||
}
|
||||
if len(this.Platforms) < 1 {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Platforms", fmt.Errorf(`platforms平台列表不能为空`))
|
||||
}
|
||||
if this.InstagramOptions != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.InstagramOptions); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("InstagramOptions", err)
|
||||
}
|
||||
}
|
||||
if this.TikTokOptions != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.TikTokOptions); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("TikTokOptions", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *PostId) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *PostItem) Validate() error {
|
||||
for _, item := range this.PostIds {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("PostIds", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *PostResponse) Validate() error {
|
||||
for _, item := range this.Posts {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Posts", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, item := range this.PostIds {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("PostIds", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *GetPostRequest) Validate() error {
|
||||
if this.Id == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Id", fmt.Errorf(`帖子ID不能为空`))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *GetPostResponse) Validate() error {
|
||||
for _, item := range this.PostIds {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("PostIds", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *GetUserRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *Timestamp) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *TwitterUsage) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *DisplayName) Validate() error {
|
||||
if this.TwitterUsage != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.TwitterUsage); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("TwitterUsage", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *GetUserResponse) Validate() error {
|
||||
if this.Created != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Created); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Created", err)
|
||||
}
|
||||
}
|
||||
for _, item := range this.DisplayNames {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("DisplayNames", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *CreateProfileRequest) Validate() error {
|
||||
if this.Title == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Title", fmt.Errorf(`title不能为空`))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *CreateProfileResponse) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *GetProfilesRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *ProfileItem) Validate() error {
|
||||
if this.Created != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Created); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Created", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *Pagination) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *GetProfilesResponse) Validate() error {
|
||||
for _, item := range this.Profiles {
|
||||
if item != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Profiles", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if this.Pagination != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Pagination); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Pagination", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *Email) Validate() error {
|
||||
return nil
|
||||
}
|
||||
func (this *GenerateJWTRequest) Validate() error {
|
||||
if this.Domain == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Domain", fmt.Errorf(`domain不能为空`))
|
||||
}
|
||||
if this.PrivateKey == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("PrivateKey", fmt.Errorf(`privateKey不能为空`))
|
||||
}
|
||||
if this.ProfileKey == "" {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("ProfileKey", fmt.Errorf(`profileKey不能为空`))
|
||||
}
|
||||
if this.Email != nil {
|
||||
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Email); err != nil {
|
||||
return github_com_mwitkow_go_proto_validators.FieldError("Email", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *GenerateJWTResponse) Validate() error {
|
||||
return nil
|
||||
}
|
||||
378
api/pb/aryshare/ayrshare_triple.pb.go
Normal file
378
api/pb/aryshare/ayrshare_triple.pb.go
Normal file
@ -0,0 +1,378 @@
|
||||
// Code generated by protoc-gen-go-triple. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-triple v1.0.8
|
||||
// - protoc v3.21.1
|
||||
// source: pb/ayrshare.proto
|
||||
|
||||
package aryshare
|
||||
|
||||
import (
|
||||
context "context"
|
||||
protocol "dubbo.apache.org/dubbo-go/v3/protocol"
|
||||
dubbo3 "dubbo.apache.org/dubbo-go/v3/protocol/dubbo3"
|
||||
invocation "dubbo.apache.org/dubbo-go/v3/protocol/invocation"
|
||||
grpc_go "github.com/dubbogo/grpc-go"
|
||||
codes "github.com/dubbogo/grpc-go/codes"
|
||||
metadata "github.com/dubbogo/grpc-go/metadata"
|
||||
status "github.com/dubbogo/grpc-go/status"
|
||||
common "github.com/dubbogo/triple/pkg/common"
|
||||
constant "github.com/dubbogo/triple/pkg/common/constant"
|
||||
triple "github.com/dubbogo/triple/pkg/triple"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc_go.SupportPackageIsVersion7
|
||||
|
||||
// AyrshareClient is the client API for Ayrshare service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type AyrshareClient interface {
|
||||
// 帖子相关 api
|
||||
Post(ctx context.Context, in *PostRequest, opts ...grpc_go.CallOption) (*PostResponse, common.ErrorWithAttachment)
|
||||
GetPost(ctx context.Context, in *GetPostRequest, opts ...grpc_go.CallOption) (*GetPostResponse, common.ErrorWithAttachment)
|
||||
// 用户相关 api
|
||||
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc_go.CallOption) (*GetUserResponse, common.ErrorWithAttachment)
|
||||
// 用户配置相关 api
|
||||
CreateProfile(ctx context.Context, in *CreateProfileRequest, opts ...grpc_go.CallOption) (*CreateProfileResponse, common.ErrorWithAttachment)
|
||||
GetProfiles(ctx context.Context, in *GetProfilesRequest, opts ...grpc_go.CallOption) (*GetProfilesResponse, common.ErrorWithAttachment)
|
||||
GenerateJWT(ctx context.Context, in *GenerateJWTRequest, opts ...grpc_go.CallOption) (*GenerateJWTResponse, common.ErrorWithAttachment)
|
||||
}
|
||||
|
||||
type ayrshareClient struct {
|
||||
cc *triple.TripleConn
|
||||
}
|
||||
|
||||
type AyrshareClientImpl struct {
|
||||
Post func(ctx context.Context, in *PostRequest) (*PostResponse, error)
|
||||
GetPost func(ctx context.Context, in *GetPostRequest) (*GetPostResponse, error)
|
||||
GetUser func(ctx context.Context, in *GetUserRequest) (*GetUserResponse, error)
|
||||
CreateProfile func(ctx context.Context, in *CreateProfileRequest) (*CreateProfileResponse, error)
|
||||
GetProfiles func(ctx context.Context, in *GetProfilesRequest) (*GetProfilesResponse, error)
|
||||
GenerateJWT func(ctx context.Context, in *GenerateJWTRequest) (*GenerateJWTResponse, error)
|
||||
}
|
||||
|
||||
func (c *AyrshareClientImpl) GetDubboStub(cc *triple.TripleConn) AyrshareClient {
|
||||
return NewAyrshareClient(cc)
|
||||
}
|
||||
|
||||
func (c *AyrshareClientImpl) XXX_InterfaceName() string {
|
||||
return "aryshare.Ayrshare"
|
||||
}
|
||||
|
||||
func NewAyrshareClient(cc *triple.TripleConn) AyrshareClient {
|
||||
return &ayrshareClient{cc}
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) Post(ctx context.Context, in *PostRequest, opts ...grpc_go.CallOption) (*PostResponse, common.ErrorWithAttachment) {
|
||||
out := new(PostResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/Post", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) GetPost(ctx context.Context, in *GetPostRequest, opts ...grpc_go.CallOption) (*GetPostResponse, common.ErrorWithAttachment) {
|
||||
out := new(GetPostResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetPost", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc_go.CallOption) (*GetUserResponse, common.ErrorWithAttachment) {
|
||||
out := new(GetUserResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetUser", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) CreateProfile(ctx context.Context, in *CreateProfileRequest, opts ...grpc_go.CallOption) (*CreateProfileResponse, common.ErrorWithAttachment) {
|
||||
out := new(CreateProfileResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/CreateProfile", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) GetProfiles(ctx context.Context, in *GetProfilesRequest, opts ...grpc_go.CallOption) (*GetProfilesResponse, common.ErrorWithAttachment) {
|
||||
out := new(GetProfilesResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetProfiles", in, out)
|
||||
}
|
||||
|
||||
func (c *ayrshareClient) GenerateJWT(ctx context.Context, in *GenerateJWTRequest, opts ...grpc_go.CallOption) (*GenerateJWTResponse, common.ErrorWithAttachment) {
|
||||
out := new(GenerateJWTResponse)
|
||||
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
|
||||
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GenerateJWT", in, out)
|
||||
}
|
||||
|
||||
// AyrshareServer is the server API for Ayrshare service.
|
||||
// All implementations must embed UnimplementedAyrshareServer
|
||||
// for forward compatibility
|
||||
type AyrshareServer interface {
|
||||
// 帖子相关 api
|
||||
Post(context.Context, *PostRequest) (*PostResponse, error)
|
||||
GetPost(context.Context, *GetPostRequest) (*GetPostResponse, error)
|
||||
// 用户相关 api
|
||||
GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error)
|
||||
// 用户配置相关 api
|
||||
CreateProfile(context.Context, *CreateProfileRequest) (*CreateProfileResponse, error)
|
||||
GetProfiles(context.Context, *GetProfilesRequest) (*GetProfilesResponse, error)
|
||||
GenerateJWT(context.Context, *GenerateJWTRequest) (*GenerateJWTResponse, error)
|
||||
mustEmbedUnimplementedAyrshareServer()
|
||||
}
|
||||
|
||||
// UnimplementedAyrshareServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedAyrshareServer struct {
|
||||
proxyImpl protocol.Invoker
|
||||
}
|
||||
|
||||
func (UnimplementedAyrshareServer) Post(context.Context, *PostRequest) (*PostResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Post not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) GetPost(context.Context, *GetPostRequest) (*GetPostResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPost not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) CreateProfile(context.Context, *CreateProfileRequest) (*CreateProfileResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateProfile not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) GetProfiles(context.Context, *GetProfilesRequest) (*GetProfilesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetProfiles not implemented")
|
||||
}
|
||||
func (UnimplementedAyrshareServer) GenerateJWT(context.Context, *GenerateJWTRequest) (*GenerateJWTResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GenerateJWT not implemented")
|
||||
}
|
||||
func (s *UnimplementedAyrshareServer) XXX_SetProxyImpl(impl protocol.Invoker) {
|
||||
s.proxyImpl = impl
|
||||
}
|
||||
|
||||
func (s *UnimplementedAyrshareServer) XXX_GetProxyImpl() protocol.Invoker {
|
||||
return s.proxyImpl
|
||||
}
|
||||
|
||||
func (s *UnimplementedAyrshareServer) XXX_ServiceDesc() *grpc_go.ServiceDesc {
|
||||
return &Ayrshare_ServiceDesc
|
||||
}
|
||||
func (s *UnimplementedAyrshareServer) XXX_InterfaceName() string {
|
||||
return "aryshare.Ayrshare"
|
||||
}
|
||||
|
||||
func (UnimplementedAyrshareServer) mustEmbedUnimplementedAyrshareServer() {}
|
||||
|
||||
// UnsafeAyrshareServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to AyrshareServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeAyrshareServer interface {
|
||||
mustEmbedUnimplementedAyrshareServer()
|
||||
}
|
||||
|
||||
func RegisterAyrshareServer(s grpc_go.ServiceRegistrar, srv AyrshareServer) {
|
||||
s.RegisterService(&Ayrshare_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _Ayrshare_Post_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(PostRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("Post", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_GetPost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPostRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("GetPost", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetUserRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("GetUser", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_CreateProfile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateProfileRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("CreateProfile", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_GetProfiles_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetProfilesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("GetProfiles", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Ayrshare_GenerateJWT_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GenerateJWTRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base := srv.(dubbo3.Dubbo3GrpcService)
|
||||
args := []interface{}{}
|
||||
args = append(args, in)
|
||||
md, _ := metadata.FromIncomingContext(ctx)
|
||||
invAttachment := make(map[string]interface{}, len(md))
|
||||
for k, v := range md {
|
||||
invAttachment[k] = v
|
||||
}
|
||||
invo := invocation.NewRPCInvocation("GenerateJWT", args, invAttachment)
|
||||
if interceptor == nil {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
info := &grpc_go.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
|
||||
return result, result.Error()
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// Ayrshare_ServiceDesc is the grpc_go.ServiceDesc for Ayrshare service.
|
||||
// It's only intended for direct use with grpc_go.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var Ayrshare_ServiceDesc = grpc_go.ServiceDesc{
|
||||
ServiceName: "aryshare.Ayrshare",
|
||||
HandlerType: (*AyrshareServer)(nil),
|
||||
Methods: []grpc_go.MethodDesc{
|
||||
{
|
||||
MethodName: "Post",
|
||||
Handler: _Ayrshare_Post_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPost",
|
||||
Handler: _Ayrshare_GetPost_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetUser",
|
||||
Handler: _Ayrshare_GetUser_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CreateProfile",
|
||||
Handler: _Ayrshare_CreateProfile_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetProfiles",
|
||||
Handler: _Ayrshare_GetProfiles_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GenerateJWT",
|
||||
Handler: _Ayrshare_GenerateJWT_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc_go.StreamDesc{},
|
||||
Metadata: "pb/ayrshare.proto",
|
||||
}
|
||||
297
api/pb/ayrshare.proto
Normal file
297
api/pb/ayrshare.proto
Normal file
@ -0,0 +1,297 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package aryshare;
|
||||
option go_package = "./aryshare";
|
||||
|
||||
import "pb/descriptor.proto";
|
||||
import "pb/validator.proto";
|
||||
|
||||
service Ayrshare {
|
||||
// 帖子相关 api
|
||||
rpc Post(PostRequest) returns (PostResponse);
|
||||
rpc GetPost(GetPostRequest) returns (GetPostResponse);
|
||||
|
||||
// 用户相关 api
|
||||
rpc GetUser(GetUserRequest) returns (GetUserResponse);
|
||||
|
||||
// 用户配置相关 api
|
||||
rpc CreateProfile(CreateProfileRequest) returns (CreateProfileResponse);
|
||||
rpc GetProfiles(GetProfilesRequest) returns (GetProfilesResponse);
|
||||
rpc GenerateJWT(GenerateJWTRequest) returns (GenerateJWTResponse);
|
||||
}
|
||||
|
||||
// Instagram 用户标签(带坐标)
|
||||
message UserTag {
|
||||
string username = 1 [json_name = "username"];
|
||||
double x = 2 [json_name = "x"]; // Required for images, cannot be used with Reels
|
||||
double y = 3 [json_name = "y"]; // Required for images, cannot be used with Reels
|
||||
}
|
||||
|
||||
// Instagram 特定发布选项
|
||||
message InstagramOptions {
|
||||
bool shareReelsFeed = 1 [json_name = "shareReelsFeed"]; // Whether Reel can appear in both Feed and Reels tabs
|
||||
string audioName = 2 [json_name = "audioName"]; // Name of the audio music for Reels
|
||||
string thumbNail = 3 [json_name = "thumbNail"]; // URL of the Reel cover image (thumbnail)
|
||||
int32 thumbNailOffset = 4 [json_name = "thumbNailOffset"]; // Offset in milliseconds of the thumbnail frame
|
||||
bool stories = 5 [json_name = "stories"]; // Whether to post as Instagram Story
|
||||
repeated string altText = 6 [json_name = "altText"]; // Array of alternative text for images (up to 1000 chars per image)
|
||||
string locationId = 7 [json_name = "locationId"]; // Facebook Page ID or Page name
|
||||
repeated UserTag userTags = 8 [json_name = "userTags"]; // Array of user tags with username and coordinates
|
||||
repeated string collaborators = 9 [json_name = "collaborators"]; // Array of Instagram usernames (up to 3)
|
||||
bool autoResize = 10 [json_name = "autoResize"]; // Auto resize images to 1080x1080px (Max Pack required)
|
||||
bool disableComments = 11 [json_name = "disableComments"]; // Disable comments on the published post
|
||||
}
|
||||
|
||||
// TikTok 特定发布选项
|
||||
message TikTokOptions {
|
||||
bool autoAddMusic = 1 [json_name = "autoAddMusic"]; // Whether to automatically add recommended music (image only)
|
||||
bool disableComments = 2 [json_name = "disableComments"]; // Whether to disable comments on the published post
|
||||
bool disableDuet = 3 [json_name = "disableDuet"]; // Disable duets on the published video (video only)
|
||||
bool disableStitch = 4 [json_name = "disableStitch"]; // Disable stitch on the published video (video only)
|
||||
bool draft = 5 [json_name = "draft"]; // Whether to create a draft post
|
||||
bool isAIGenerated = 6 [json_name = "isAIGenerated"]; // Whether to enable AI-generated content toggle (video only)
|
||||
bool isBrandedContent = 7 [json_name = "isBrandedContent"]; // Whether to enable Branded Content toggle
|
||||
bool isBrandOrganic = 8 [json_name = "isBrandOrganic"]; // Whether to enable Brand Organic Content toggle
|
||||
int32 imageCoverIndex = 9 [json_name = "imageCoverIndex"]; // Index of mediaUrls to be used as cover (image only, default 0)
|
||||
string title = 10 [json_name = "title"]; // Title of the post (image only)
|
||||
int32 thumbNailOffset = 11 [json_name = "thumbNailOffset"]; // Frame to use for video cover in milliseconds (video only)
|
||||
string thumbNail = 12 [json_name = "thumbNail"]; // URL of thumbnail image for video (video only)
|
||||
string visibility = 13 [json_name = "visibility"]; // How the post is shared: "public", "private", "followers", "friends" (image only, default "public")
|
||||
}
|
||||
|
||||
// 发布帖子到社交媒体平台
|
||||
message PostRequest {
|
||||
string post = 1 [json_name = "post", (validator.field) = {string_not_empty: true, human_error: "post内容不能为空"}];
|
||||
repeated string platforms = 2 [json_name = "platforms", (validator.field) = {repeated_count_min: 1, human_error: "platforms平台列表不能为空"}];
|
||||
repeated string mediaUrls = 3 [json_name = "mediaUrls"];
|
||||
bool isVideo = 4 [json_name = "isVideo"];
|
||||
string scheduleDate = 5 [json_name = "scheduleDate"];
|
||||
bool validateScheduled = 6 [json_name = "validateScheduled"];
|
||||
bool shortenLinks = 7 [json_name = "shortenLinks"];
|
||||
bool disableComments = 8 [json_name = "disableComments"];
|
||||
InstagramOptions instagramOptions = 9 [json_name = "instagramOptions"];
|
||||
TikTokOptions tikTokOptions = 10 [json_name = "tikTokOptions"];
|
||||
string profileKey = 11 [json_name = "profileKey"];
|
||||
}
|
||||
|
||||
// 单个平台的帖子ID响应
|
||||
message PostId {
|
||||
string status = 1 [json_name = "status"];
|
||||
string id = 2 [json_name = "id"];
|
||||
string cid = 3 [json_name = "cid"];
|
||||
string postUrl = 4 [json_name = "postUrl"];
|
||||
string platform = 5 [json_name = "platform"];
|
||||
string type = 6 [json_name = "type"];
|
||||
string owner = 7 [json_name = "owner"];
|
||||
string mediaId = 8 [json_name = "mediaId"];
|
||||
string ended = 9 [json_name = "ended"];
|
||||
string idShare = 10 [json_name = "idShare"];
|
||||
bool isVideo = 11 [json_name = "isVideo"];
|
||||
int32 usedQuota = 12 [json_name = "usedQuota"];
|
||||
}
|
||||
|
||||
// 帖子项(使用 profile key 时的响应格式)
|
||||
message PostItem {
|
||||
string status = 1 [json_name = "status"];
|
||||
repeated string errors = 2 [json_name = "errors"];
|
||||
repeated PostId postIds = 3 [json_name = "postIds"];
|
||||
string id = 4 [json_name = "id"];
|
||||
string refId = 5 [json_name = "refId"];
|
||||
string profileTitle = 6 [json_name = "profileTitle"];
|
||||
string post = 7 [json_name = "post"];
|
||||
}
|
||||
|
||||
// 发布帖子响应
|
||||
message PostResponse {
|
||||
string status = 1 [json_name = "status"];
|
||||
repeated PostItem posts = 2 [json_name = "posts"];
|
||||
// 兼容旧版本响应格式(不使用 profile key 时)
|
||||
repeated string errors = 3 [json_name = "errors"];
|
||||
repeated PostId postIds = 4 [json_name = "postIds"];
|
||||
string id = 5 [json_name = "id"];
|
||||
}
|
||||
|
||||
// 获取帖子请求
|
||||
message GetPostRequest {
|
||||
string id = 1 [json_name = "id", (validator.field) = {string_not_empty: true, human_error: "帖子ID不能为空"}];
|
||||
string profileKey = 2 [json_name = "profileKey"];
|
||||
}
|
||||
|
||||
// 获取帖子响应
|
||||
message GetPostResponse {
|
||||
string created = 1 [json_name = "created"];
|
||||
repeated string errors = 2 [json_name = "errors"];
|
||||
string id = 3 [json_name = "id"];
|
||||
repeated string mediaUrls = 4 [json_name = "mediaUrls"];
|
||||
repeated string platforms = 5 [json_name = "platforms"];
|
||||
string post = 6 [json_name = "post"];
|
||||
repeated PostId postIds = 7 [json_name = "postIds"];
|
||||
string profileTitle = 8 [json_name = "profileTitle"];
|
||||
string refId = 9 [json_name = "refId"];
|
||||
string scheduleDate = 10 [json_name = "scheduleDate"];
|
||||
bool shortenLinks = 11 [json_name = "shortenLinks"];
|
||||
string status = 12 [json_name = "status"];
|
||||
string type = 13 [json_name = "type"];
|
||||
}
|
||||
|
||||
// 获取用户详情请求
|
||||
message GetUserRequest {
|
||||
string profileKey = 1 [json_name = "profileKey"];
|
||||
bool instagramDetails = 2 [json_name = "instagramDetails"];
|
||||
}
|
||||
|
||||
// 时间戳
|
||||
message Timestamp {
|
||||
int64 seconds = 1 [json_name = "_seconds"];
|
||||
int64 nanoseconds = 2 [json_name = "_nanoseconds"];
|
||||
string utc = 3 [json_name = "utc"];
|
||||
}
|
||||
|
||||
// Twitter 使用情况
|
||||
message TwitterUsage {
|
||||
int32 monthlyUsage = 1 [json_name = "monthlyUsage"];
|
||||
int32 monthlyLimit = 2 [json_name = "monthlyLimit"];
|
||||
string monthlyReset = 3 [json_name = "monthlyReset"];
|
||||
}
|
||||
|
||||
// 社交媒体账户显示名称和详情
|
||||
message DisplayName {
|
||||
string created = 1 [json_name = "created"];
|
||||
string displayName = 2 [json_name = "displayName"];
|
||||
string id = 3 [json_name = "id"];
|
||||
string platform = 4 [json_name = "platform"];
|
||||
string profileUrl = 5 [json_name = "profileUrl"];
|
||||
string userImage = 6 [json_name = "userImage"];
|
||||
string username = 7 [json_name = "username"];
|
||||
string description = 8 [json_name = "description"];
|
||||
bool messagingActive = 9 [json_name = "messagingActive"];
|
||||
string pageName = 10 [json_name = "pageName"];
|
||||
string userId = 11 [json_name = "userId"];
|
||||
string mapsUrl = 12 [json_name = "mapsUrl"];
|
||||
string placeId = 13 [json_name = "placeId"];
|
||||
string reviewUrl = 14 [json_name = "reviewUrl"];
|
||||
string igId = 15 [json_name = "igId"];
|
||||
string type = 16 [json_name = "type"];
|
||||
int32 usedQuota = 17 [json_name = "usedQuota"];
|
||||
int32 refreshDaysRemaining = 18 [json_name = "refreshDaysRemaining"];
|
||||
string refreshRequired = 19 [json_name = "refreshRequired"];
|
||||
bool isEligibleForGeoRestrictions = 20 [json_name = "isEligibleForGeoRestrictions"];
|
||||
bool isVerified = 21 [json_name = "isVerified"];
|
||||
string subscriptionType = 22 [json_name = "subscriptionType"];
|
||||
TwitterUsage twitterUsage = 23 [json_name = "twitterUsage"];
|
||||
string verifiedType = 24 [json_name = "verifiedType"];
|
||||
}
|
||||
|
||||
// 获取用户详情响应
|
||||
message GetUserResponse {
|
||||
repeated string activeSocialAccounts = 1 [json_name = "activeSocialAccounts"];
|
||||
Timestamp created = 2 [json_name = "created"];
|
||||
repeated DisplayName displayNames = 3 [json_name = "displayNames"];
|
||||
string email = 4 [json_name = "email"];
|
||||
string lastApiCall = 5 [json_name = "lastApiCall"];
|
||||
int32 messagingConversationMonthlyCount = 6 [json_name = "messagingConversationMonthlyCount"];
|
||||
bool messagingEnabled = 7 [json_name = "messagingEnabled"];
|
||||
int32 monthlyApiCalls = 8 [json_name = "monthlyApiCalls"];
|
||||
int32 monthlyPostCount = 9 [json_name = "monthlyPostCount"];
|
||||
int32 monthlyPostQuota = 10 [json_name = "monthlyPostQuota"];
|
||||
int32 monthlyApiCallsQuota = 11 [json_name = "monthlyApiCallsQuota"];
|
||||
string refId = 12 [json_name = "refId"];
|
||||
string title = 13 [json_name = "title"];
|
||||
string lastUpdated = 14 [json_name = "lastUpdated"];
|
||||
string nextUpdate = 15 [json_name = "nextUpdate"];
|
||||
}
|
||||
|
||||
// 创建用户配置请求
|
||||
message CreateProfileRequest {
|
||||
string title = 1 [json_name = "title", (validator.field) = {string_not_empty: true, human_error: "title不能为空"}];
|
||||
bool messagingActive = 2 [json_name = "messagingActive"];
|
||||
bool hideTopHeader = 3 [json_name = "hideTopHeader"];
|
||||
string topHeader = 4 [json_name = "topHeader"];
|
||||
repeated string disableSocial = 5 [json_name = "disableSocial"];
|
||||
bool team = 6 [json_name = "team"];
|
||||
string email = 7 [json_name = "email"];
|
||||
string subHeader = 8 [json_name = "subHeader"];
|
||||
repeated string tags = 9 [json_name = "tags"];
|
||||
}
|
||||
|
||||
// 创建用户配置响应
|
||||
message CreateProfileResponse {
|
||||
string status = 1 [json_name = "status"];
|
||||
string title = 2 [json_name = "title"];
|
||||
string refId = 3 [json_name = "refId"];
|
||||
string profileKey = 4 [json_name = "profileKey"];
|
||||
bool messagingActive = 5 [json_name = "messagingActive"];
|
||||
}
|
||||
|
||||
// 获取用户配置列表请求
|
||||
message GetProfilesRequest {
|
||||
string title = 1 [json_name = "title"];
|
||||
string refId = 2 [json_name = "refId"];
|
||||
bool hasActiveSocialAccounts = 3 [json_name = "hasActiveSocialAccounts"];
|
||||
repeated string includesActiveSocialAccounts = 4 [json_name = "includesActiveSocialAccounts"];
|
||||
oneof actionLog {
|
||||
bool actionLogBool = 5 [json_name = "actionLogBool"];
|
||||
int32 actionLogInt = 6 [json_name = "actionLogInt"];
|
||||
}
|
||||
int32 limit = 7 [json_name = "limit"];
|
||||
string cursor = 8 [json_name = "cursor"];
|
||||
}
|
||||
|
||||
// 用户配置项
|
||||
message ProfileItem {
|
||||
string status = 1 [json_name = "status"];
|
||||
string title = 2 [json_name = "title"];
|
||||
string displayTitle = 3 [json_name = "displayTitle"];
|
||||
Timestamp created = 4 [json_name = "created"];
|
||||
string createdUTC = 5 [json_name = "createdUTC"];
|
||||
string refId = 6 [json_name = "refId"];
|
||||
repeated string activeSocialAccounts = 7 [json_name = "activeSocialAccounts"];
|
||||
bool suspended = 8 [json_name = "suspended"];
|
||||
}
|
||||
|
||||
// 分页信息
|
||||
message Pagination {
|
||||
bool hasMore = 1 [json_name = "hasMore"];
|
||||
string nextCursor = 2 [json_name = "nextCursor"];
|
||||
int32 limit = 3 [json_name = "limit"];
|
||||
}
|
||||
|
||||
// 获取用户配置列表响应
|
||||
message GetProfilesResponse {
|
||||
repeated ProfileItem profiles = 1 [json_name = "profiles"];
|
||||
int32 count = 2 [json_name = "count"];
|
||||
string lastUpdated = 3 [json_name = "lastUpdated"];
|
||||
string nextUpdate = 4 [json_name = "nextUpdate"];
|
||||
Pagination pagination = 5 [json_name = "pagination"];
|
||||
}
|
||||
|
||||
// 邮件配置对象
|
||||
message Email {
|
||||
string to = 1 [json_name = "to"];
|
||||
string subject = 2 [json_name = "subject"];
|
||||
string body = 3 [json_name = "body"];
|
||||
}
|
||||
|
||||
// 生成JWT请求
|
||||
message GenerateJWTRequest {
|
||||
string domain = 1 [json_name = "domain", (validator.field) = {string_not_empty: true, human_error: "domain不能为空"}];
|
||||
string privateKey = 2 [json_name = "privateKey", (validator.field) = {string_not_empty: true, human_error: "privateKey不能为空"}];
|
||||
string profileKey = 3 [json_name = "profileKey", (validator.field) = {string_not_empty: true, human_error: "profileKey不能为空"}];
|
||||
bool logout = 4 [json_name = "logout"];
|
||||
string redirect = 5 [json_name = "redirect"];
|
||||
repeated string allowedSocial = 6 [json_name = "allowedSocial"];
|
||||
bool verify = 7 [json_name = "verify"];
|
||||
bool base64 = 8 [json_name = "base64"];
|
||||
int32 expiresIn = 9 [json_name = "expiresIn"];
|
||||
Email email = 10 [json_name = "email"];
|
||||
}
|
||||
|
||||
// 生成JWT响应
|
||||
message GenerateJWTResponse {
|
||||
string status = 1 [json_name = "status"];
|
||||
string title = 2 [json_name = "title"];
|
||||
string token = 3 [json_name = "token"];
|
||||
string url = 4 [json_name = "url"];
|
||||
bool emailSent = 5 [json_name = "emailSent"];
|
||||
string expiresIn = 6 [json_name = "expiresIn"];
|
||||
}
|
||||
923
api/pb/descriptor.proto
Normal file
923
api/pb/descriptor.proto
Normal file
@ -0,0 +1,923 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// The messages in this file describe the definitions found in .proto files.
|
||||
// A valid .proto file can be translated directly to a FileDescriptorProto
|
||||
// without any other information (e.g. without reading its imports).
|
||||
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option go_package = "google.golang.org/protobuf/types/descriptorpb";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "DescriptorProtos";
|
||||
option csharp_namespace = "Google.Protobuf.Reflection";
|
||||
option objc_class_prefix = "GPB";
|
||||
option cc_enable_arenas = true;
|
||||
|
||||
// descriptor.proto must be optimized for speed because reflection-based
|
||||
// algorithms don't work during bootstrapping.
|
||||
option optimize_for = SPEED;
|
||||
|
||||
// The protocol compiler can output a FileDescriptorSet containing the .proto
|
||||
// files it parses.
|
||||
message FileDescriptorSet {
|
||||
repeated FileDescriptorProto file = 1;
|
||||
}
|
||||
|
||||
// Describes a complete .proto file.
|
||||
message FileDescriptorProto {
|
||||
optional string name = 1; // file name, relative to root of source tree
|
||||
optional string package = 2; // e.g. "foo", "foo.bar", etc.
|
||||
|
||||
// Names of files imported by this file.
|
||||
repeated string dependency = 3;
|
||||
// Indexes of the public imported files in the dependency list above.
|
||||
repeated int32 public_dependency = 10;
|
||||
// Indexes of the weak imported files in the dependency list.
|
||||
// For Google-internal migration only. Do not use.
|
||||
repeated int32 weak_dependency = 11;
|
||||
|
||||
// All top-level definitions in this file.
|
||||
repeated DescriptorProto message_type = 4;
|
||||
repeated EnumDescriptorProto enum_type = 5;
|
||||
repeated ServiceDescriptorProto service = 6;
|
||||
repeated FieldDescriptorProto extension = 7;
|
||||
|
||||
optional FileOptions options = 8;
|
||||
|
||||
// This field contains optional information about the original source code.
|
||||
// You may safely remove this entire field without harming runtime
|
||||
// functionality of the descriptors -- the information is needed only by
|
||||
// development tools.
|
||||
optional SourceCodeInfo source_code_info = 9;
|
||||
|
||||
// The syntax of the proto file.
|
||||
// The supported values are "proto2", "proto3", and "editions".
|
||||
//
|
||||
// If `edition` is present, this value must be "editions".
|
||||
optional string syntax = 12;
|
||||
|
||||
// The edition of the proto file, which is an opaque string.
|
||||
optional string edition = 13;
|
||||
}
|
||||
|
||||
// Describes a message type.
|
||||
message DescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
repeated FieldDescriptorProto field = 2;
|
||||
repeated FieldDescriptorProto extension = 6;
|
||||
|
||||
repeated DescriptorProto nested_type = 3;
|
||||
repeated EnumDescriptorProto enum_type = 4;
|
||||
|
||||
message ExtensionRange {
|
||||
optional int32 start = 1; // Inclusive.
|
||||
optional int32 end = 2; // Exclusive.
|
||||
|
||||
optional ExtensionRangeOptions options = 3;
|
||||
}
|
||||
repeated ExtensionRange extension_range = 5;
|
||||
|
||||
repeated OneofDescriptorProto oneof_decl = 8;
|
||||
|
||||
optional MessageOptions options = 7;
|
||||
|
||||
// Range of reserved tag numbers. Reserved tag numbers may not be used by
|
||||
// fields or extension ranges in the same message. Reserved ranges may
|
||||
// not overlap.
|
||||
message ReservedRange {
|
||||
optional int32 start = 1; // Inclusive.
|
||||
optional int32 end = 2; // Exclusive.
|
||||
}
|
||||
repeated ReservedRange reserved_range = 9;
|
||||
// Reserved field names, which may not be used by fields in the same message.
|
||||
// A given name may only be reserved once.
|
||||
repeated string reserved_name = 10;
|
||||
}
|
||||
|
||||
message ExtensionRangeOptions {
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
// Describes a field within a message.
|
||||
message FieldDescriptorProto {
|
||||
enum Type {
|
||||
// 0 is reserved for errors.
|
||||
// Order is weird for historical reasons.
|
||||
TYPE_DOUBLE = 1;
|
||||
TYPE_FLOAT = 2;
|
||||
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
|
||||
// negative values are likely.
|
||||
TYPE_INT64 = 3;
|
||||
TYPE_UINT64 = 4;
|
||||
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
|
||||
// negative values are likely.
|
||||
TYPE_INT32 = 5;
|
||||
TYPE_FIXED64 = 6;
|
||||
TYPE_FIXED32 = 7;
|
||||
TYPE_BOOL = 8;
|
||||
TYPE_STRING = 9;
|
||||
// Tag-delimited aggregate.
|
||||
// Group type is deprecated and not supported in proto3. However, Proto3
|
||||
// implementations should still be able to parse the group wire format and
|
||||
// treat group fields as unknown fields.
|
||||
TYPE_GROUP = 10;
|
||||
TYPE_MESSAGE = 11; // Length-delimited aggregate.
|
||||
|
||||
// New in version 2.
|
||||
TYPE_BYTES = 12;
|
||||
TYPE_UINT32 = 13;
|
||||
TYPE_ENUM = 14;
|
||||
TYPE_SFIXED32 = 15;
|
||||
TYPE_SFIXED64 = 16;
|
||||
TYPE_SINT32 = 17; // Uses ZigZag encoding.
|
||||
TYPE_SINT64 = 18; // Uses ZigZag encoding.
|
||||
}
|
||||
|
||||
enum Label {
|
||||
// 0 is reserved for errors
|
||||
LABEL_OPTIONAL = 1;
|
||||
LABEL_REQUIRED = 2;
|
||||
LABEL_REPEATED = 3;
|
||||
}
|
||||
|
||||
optional string name = 1;
|
||||
optional int32 number = 3;
|
||||
optional Label label = 4;
|
||||
|
||||
// If type_name is set, this need not be set. If both this and type_name
|
||||
// are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
|
||||
optional Type type = 5;
|
||||
|
||||
// For message and enum types, this is the name of the type. If the name
|
||||
// starts with a '.', it is fully-qualified. Otherwise, C++-like scoping
|
||||
// rules are used to find the type (i.e. first the nested types within this
|
||||
// message are searched, then within the parent, on up to the root
|
||||
// namespace).
|
||||
optional string type_name = 6;
|
||||
|
||||
// For extensions, this is the name of the type being extended. It is
|
||||
// resolved in the same manner as type_name.
|
||||
optional string extendee = 2;
|
||||
|
||||
// For numeric types, contains the original text representation of the value.
|
||||
// For booleans, "true" or "false".
|
||||
// For strings, contains the default text contents (not escaped in any way).
|
||||
// For bytes, contains the C escaped value. All bytes >= 128 are escaped.
|
||||
optional string default_value = 7;
|
||||
|
||||
// If set, gives the index of a oneof in the containing type's oneof_decl
|
||||
// list. This field is a member of that oneof.
|
||||
optional int32 oneof_index = 9;
|
||||
|
||||
// JSON name of this field. The value is set by protocol compiler. If the
|
||||
// user has set a "json_name" option on this field, that option's value
|
||||
// will be used. Otherwise, it's deduced from the field's name by converting
|
||||
// it to camelCase.
|
||||
optional string json_name = 10;
|
||||
|
||||
optional FieldOptions options = 8;
|
||||
|
||||
// If true, this is a proto3 "optional". When a proto3 field is optional, it
|
||||
// tracks presence regardless of field type.
|
||||
//
|
||||
// When proto3_optional is true, this field must be belong to a oneof to
|
||||
// signal to old proto3 clients that presence is tracked for this field. This
|
||||
// oneof is known as a "synthetic" oneof, and this field must be its sole
|
||||
// member (each proto3 optional field gets its own synthetic oneof). Synthetic
|
||||
// oneofs exist in the descriptor only, and do not generate any API. Synthetic
|
||||
// oneofs must be ordered after all "real" oneofs.
|
||||
//
|
||||
// For message fields, proto3_optional doesn't create any semantic change,
|
||||
// since non-repeated message fields always track presence. However it still
|
||||
// indicates the semantic detail of whether the user wrote "optional" or not.
|
||||
// This can be useful for round-tripping the .proto file. For consistency we
|
||||
// give message fields a synthetic oneof also, even though it is not required
|
||||
// to track presence. This is especially important because the parser can't
|
||||
// tell if a field is a message or an enum, so it must always create a
|
||||
// synthetic oneof.
|
||||
//
|
||||
// Proto2 optional fields do not set this flag, because they already indicate
|
||||
// optional with `LABEL_OPTIONAL`.
|
||||
optional bool proto3_optional = 17;
|
||||
}
|
||||
|
||||
// Describes a oneof.
|
||||
message OneofDescriptorProto {
|
||||
optional string name = 1;
|
||||
optional OneofOptions options = 2;
|
||||
}
|
||||
|
||||
// Describes an enum type.
|
||||
message EnumDescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
repeated EnumValueDescriptorProto value = 2;
|
||||
|
||||
optional EnumOptions options = 3;
|
||||
|
||||
// Range of reserved numeric values. Reserved values may not be used by
|
||||
// entries in the same enum. Reserved ranges may not overlap.
|
||||
//
|
||||
// Note that this is distinct from DescriptorProto.ReservedRange in that it
|
||||
// is inclusive such that it can appropriately represent the entire int32
|
||||
// domain.
|
||||
message EnumReservedRange {
|
||||
optional int32 start = 1; // Inclusive.
|
||||
optional int32 end = 2; // Inclusive.
|
||||
}
|
||||
|
||||
// Range of reserved numeric values. Reserved numeric values may not be used
|
||||
// by enum values in the same enum declaration. Reserved ranges may not
|
||||
// overlap.
|
||||
repeated EnumReservedRange reserved_range = 4;
|
||||
|
||||
// Reserved enum value names, which may not be reused. A given name may only
|
||||
// be reserved once.
|
||||
repeated string reserved_name = 5;
|
||||
}
|
||||
|
||||
// Describes a value within an enum.
|
||||
message EnumValueDescriptorProto {
|
||||
optional string name = 1;
|
||||
optional int32 number = 2;
|
||||
|
||||
optional EnumValueOptions options = 3;
|
||||
}
|
||||
|
||||
// Describes a service.
|
||||
message ServiceDescriptorProto {
|
||||
optional string name = 1;
|
||||
repeated MethodDescriptorProto method = 2;
|
||||
|
||||
optional ServiceOptions options = 3;
|
||||
}
|
||||
|
||||
// Describes a method of a service.
|
||||
message MethodDescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
// Input and output type names. These are resolved in the same way as
|
||||
// FieldDescriptorProto.type_name, but must refer to a message type.
|
||||
optional string input_type = 2;
|
||||
optional string output_type = 3;
|
||||
|
||||
optional MethodOptions options = 4;
|
||||
|
||||
// Identifies if client streams multiple client messages
|
||||
optional bool client_streaming = 5 [default = false];
|
||||
// Identifies if server streams multiple server messages
|
||||
optional bool server_streaming = 6 [default = false];
|
||||
}
|
||||
|
||||
|
||||
// ===================================================================
|
||||
// Options
|
||||
|
||||
// Each of the definitions above may have "options" attached. These are
|
||||
// just annotations which may cause code to be generated slightly differently
|
||||
// or may contain hints for code that manipulates protocol messages.
|
||||
//
|
||||
// Clients may define custom options as extensions of the *Options messages.
|
||||
// These extensions may not yet be known at parsing time, so the parser cannot
|
||||
// store the values in them. Instead it stores them in a field in the *Options
|
||||
// message called uninterpreted_option. This field must have the same name
|
||||
// across all *Options messages. We then use this field to populate the
|
||||
// extensions when we build a descriptor, at which point all protos have been
|
||||
// parsed and so all extensions are known.
|
||||
//
|
||||
// Extension numbers for custom options may be chosen as follows:
|
||||
// * For options which will only be used within a single application or
|
||||
// organization, or for experimental options, use field numbers 50000
|
||||
// through 99999. It is up to you to ensure that you do not use the
|
||||
// same number for multiple options.
|
||||
// * For options which will be published and used publicly by multiple
|
||||
// independent entities, e-mail protobuf-global-extension-registry@google.com
|
||||
// to reserve extension numbers. Simply provide your project name (e.g.
|
||||
// Objective-C plugin) and your project website (if available) -- there's no
|
||||
// need to explain how you intend to use them. Usually you only need one
|
||||
// extension number. You can declare multiple options with only one extension
|
||||
// number by putting them in a sub-message. See the Custom Options section of
|
||||
// the docs for examples:
|
||||
// https://developers.google.com/protocol-buffers/docs/proto#options
|
||||
// If this turns out to be popular, a web service will be set up
|
||||
// to automatically assign option numbers.
|
||||
|
||||
message FileOptions {
|
||||
|
||||
// Sets the Java package where classes generated from this .proto will be
|
||||
// placed. By default, the proto package is used, but this is often
|
||||
// inappropriate because proto packages do not normally start with backwards
|
||||
// domain names.
|
||||
optional string java_package = 1;
|
||||
|
||||
|
||||
// Controls the name of the wrapper Java class generated for the .proto file.
|
||||
// That class will always contain the .proto file's getDescriptor() method as
|
||||
// well as any top-level extensions defined in the .proto file.
|
||||
// If java_multiple_files is disabled, then all the other classes from the
|
||||
// .proto file will be nested inside the single wrapper outer class.
|
||||
optional string java_outer_classname = 8;
|
||||
|
||||
// If enabled, then the Java code generator will generate a separate .java
|
||||
// file for each top-level message, enum, and service defined in the .proto
|
||||
// file. Thus, these types will *not* be nested inside the wrapper class
|
||||
// named by java_outer_classname. However, the wrapper class will still be
|
||||
// generated to contain the file's getDescriptor() method as well as any
|
||||
// top-level extensions defined in the file.
|
||||
optional bool java_multiple_files = 10 [default = false];
|
||||
|
||||
// This option does nothing.
|
||||
optional bool java_generate_equals_and_hash = 20 [deprecated=true];
|
||||
|
||||
// If set true, then the Java2 code generator will generate code that
|
||||
// throws an exception whenever an attempt is made to assign a non-UTF-8
|
||||
// byte sequence to a string field.
|
||||
// Message reflection will do the same.
|
||||
// However, an extension field still accepts non-UTF-8 byte sequences.
|
||||
// This option has no effect on when used with the lite runtime.
|
||||
optional bool java_string_check_utf8 = 27 [default = false];
|
||||
|
||||
|
||||
// Generated classes can be optimized for speed or code size.
|
||||
enum OptimizeMode {
|
||||
SPEED = 1; // Generate complete code for parsing, serialization,
|
||||
// etc.
|
||||
CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
|
||||
LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
|
||||
}
|
||||
optional OptimizeMode optimize_for = 9 [default = SPEED];
|
||||
|
||||
// Sets the Go package where structs generated from this .proto will be
|
||||
// placed. If omitted, the Go package will be derived from the following:
|
||||
// - The basename of the package import path, if provided.
|
||||
// - Otherwise, the package statement in the .proto file, if present.
|
||||
// - Otherwise, the basename of the .proto file, without extension.
|
||||
optional string go_package = 11;
|
||||
|
||||
|
||||
|
||||
|
||||
// Should generic services be generated in each language? "Generic" services
|
||||
// are not specific to any particular RPC system. They are generated by the
|
||||
// main code generators in each language (without additional plugins).
|
||||
// Generic services were the only kind of service generation supported by
|
||||
// early versions of google.protobuf.
|
||||
//
|
||||
// Generic services are now considered deprecated in favor of using plugins
|
||||
// that generate code specific to your particular RPC system. Therefore,
|
||||
// these default to false. Old code which depends on generic services should
|
||||
// explicitly set them to true.
|
||||
optional bool cc_generic_services = 16 [default = false];
|
||||
optional bool java_generic_services = 17 [default = false];
|
||||
optional bool py_generic_services = 18 [default = false];
|
||||
optional bool php_generic_services = 42 [default = false];
|
||||
|
||||
// Is this file deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for everything in the file, or it will be completely ignored; in the very
|
||||
// least, this is a formalization for deprecating files.
|
||||
optional bool deprecated = 23 [default = false];
|
||||
|
||||
// Enables the use of arenas for the proto messages in this file. This applies
|
||||
// only to generated classes for C++.
|
||||
optional bool cc_enable_arenas = 31 [default = true];
|
||||
|
||||
|
||||
// Sets the objective c class prefix which is prepended to all objective c
|
||||
// generated classes from this .proto. There is no default.
|
||||
optional string objc_class_prefix = 36;
|
||||
|
||||
// Namespace for generated classes; defaults to the package.
|
||||
optional string csharp_namespace = 37;
|
||||
|
||||
// By default Swift generators will take the proto package and CamelCase it
|
||||
// replacing '.' with underscore and use that to prefix the types/symbols
|
||||
// defined. When this options is provided, they will use this value instead
|
||||
// to prefix the types/symbols defined.
|
||||
optional string swift_prefix = 39;
|
||||
|
||||
// Sets the php class prefix which is prepended to all php generated classes
|
||||
// from this .proto. Default is empty.
|
||||
optional string php_class_prefix = 40;
|
||||
|
||||
// Use this option to change the namespace of php generated classes. Default
|
||||
// is empty. When this option is empty, the package name will be used for
|
||||
// determining the namespace.
|
||||
optional string php_namespace = 41;
|
||||
|
||||
// Use this option to change the namespace of php generated metadata classes.
|
||||
// Default is empty. When this option is empty, the proto file name will be
|
||||
// used for determining the namespace.
|
||||
optional string php_metadata_namespace = 44;
|
||||
|
||||
// Use this option to change the package of ruby generated classes. Default
|
||||
// is empty. When this option is not set, the package name will be used for
|
||||
// determining the ruby package.
|
||||
optional string ruby_package = 45;
|
||||
|
||||
|
||||
// The parser stores options it doesn't recognize here.
|
||||
// See the documentation for the "Options" section above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message.
|
||||
// See the documentation for the "Options" section above.
|
||||
extensions 1000 to max;
|
||||
|
||||
reserved 38;
|
||||
}
|
||||
|
||||
message MessageOptions {
|
||||
// Set true to use the old proto1 MessageSet wire format for extensions.
|
||||
// This is provided for backwards-compatibility with the MessageSet wire
|
||||
// format. You should not use this for any other reason: It's less
|
||||
// efficient, has fewer features, and is more complicated.
|
||||
//
|
||||
// The message must be defined exactly as follows:
|
||||
// message Foo {
|
||||
// option message_set_wire_format = true;
|
||||
// extensions 4 to max;
|
||||
// }
|
||||
// Note that the message cannot have any defined fields; MessageSets only
|
||||
// have extensions.
|
||||
//
|
||||
// All extensions of your type must be singular messages; e.g. they cannot
|
||||
// be int32s, enums, or repeated messages.
|
||||
//
|
||||
// Because this is an option, the above two restrictions are not enforced by
|
||||
// the protocol compiler.
|
||||
optional bool message_set_wire_format = 1 [default = false];
|
||||
|
||||
// Disables the generation of the standard "descriptor()" accessor, which can
|
||||
// conflict with a field of the same name. This is meant to make migration
|
||||
// from proto1 easier; new code should avoid fields named "descriptor".
|
||||
optional bool no_standard_descriptor_accessor = 2 [default = false];
|
||||
|
||||
// Is this message deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the message, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating messages.
|
||||
optional bool deprecated = 3 [default = false];
|
||||
|
||||
reserved 4, 5, 6;
|
||||
|
||||
// Whether the message is an automatically generated map entry type for the
|
||||
// maps field.
|
||||
//
|
||||
// For maps fields:
|
||||
// map<KeyType, ValueType> map_field = 1;
|
||||
// The parsed descriptor looks like:
|
||||
// message MapFieldEntry {
|
||||
// option map_entry = true;
|
||||
// optional KeyType key = 1;
|
||||
// optional ValueType value = 2;
|
||||
// }
|
||||
// repeated MapFieldEntry map_field = 1;
|
||||
//
|
||||
// Implementations may choose not to generate the map_entry=true message, but
|
||||
// use a native map in the target language to hold the keys and values.
|
||||
// The reflection APIs in such implementations still need to work as
|
||||
// if the field is a repeated message field.
|
||||
//
|
||||
// NOTE: Do not set the option in .proto files. Always use the maps syntax
|
||||
// instead. The option should only be implicitly set by the proto compiler
|
||||
// parser.
|
||||
optional bool map_entry = 7;
|
||||
|
||||
reserved 8; // javalite_serializable
|
||||
reserved 9; // javanano_as_lite
|
||||
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message FieldOptions {
|
||||
// The ctype option instructs the C++ code generator to use a different
|
||||
// representation of the field than it normally would. See the specific
|
||||
// options below. This option is not yet implemented in the open source
|
||||
// release -- sorry, we'll try to include it in a future version!
|
||||
optional CType ctype = 1 [default = STRING];
|
||||
enum CType {
|
||||
// Default mode.
|
||||
STRING = 0;
|
||||
|
||||
CORD = 1;
|
||||
|
||||
STRING_PIECE = 2;
|
||||
}
|
||||
// The packed option can be enabled for repeated primitive fields to enable
|
||||
// a more efficient representation on the wire. Rather than repeatedly
|
||||
// writing the tag and type for each element, the entire array is encoded as
|
||||
// a single length-delimited blob. In proto3, only explicit setting it to
|
||||
// false will avoid using packed encoding.
|
||||
optional bool packed = 2;
|
||||
|
||||
// The jstype option determines the JavaScript type used for values of the
|
||||
// field. The option is permitted only for 64 bit integral and fixed types
|
||||
// (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING
|
||||
// is represented as JavaScript string, which avoids loss of precision that
|
||||
// can happen when a large value is converted to a floating point JavaScript.
|
||||
// Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
|
||||
// use the JavaScript "number" type. The behavior of the default option
|
||||
// JS_NORMAL is implementation dependent.
|
||||
//
|
||||
// This option is an enum to permit additional types to be added, e.g.
|
||||
// goog.math.Integer.
|
||||
optional JSType jstype = 6 [default = JS_NORMAL];
|
||||
enum JSType {
|
||||
// Use the default type.
|
||||
JS_NORMAL = 0;
|
||||
|
||||
// Use JavaScript strings.
|
||||
JS_STRING = 1;
|
||||
|
||||
// Use JavaScript numbers.
|
||||
JS_NUMBER = 2;
|
||||
}
|
||||
|
||||
// Should this field be parsed lazily? Lazy applies only to message-type
|
||||
// fields. It means that when the outer message is initially parsed, the
|
||||
// inner message's contents will not be parsed but instead stored in encoded
|
||||
// form. The inner message will actually be parsed when it is first accessed.
|
||||
//
|
||||
// This is only a hint. Implementations are free to choose whether to use
|
||||
// eager or lazy parsing regardless of the value of this option. However,
|
||||
// setting this option true suggests that the protocol author believes that
|
||||
// using lazy parsing on this field is worth the additional bookkeeping
|
||||
// overhead typically needed to implement it.
|
||||
//
|
||||
// This option does not affect the public interface of any generated code;
|
||||
// all method signatures remain the same. Furthermore, thread-safety of the
|
||||
// interface is not affected by this option; const methods remain safe to
|
||||
// call from multiple threads concurrently, while non-const methods continue
|
||||
// to require exclusive access.
|
||||
//
|
||||
//
|
||||
// Note that implementations may choose not to check required fields within
|
||||
// a lazy sub-message. That is, calling IsInitialized() on the outer message
|
||||
// may return true even if the inner message has missing required fields.
|
||||
// This is necessary because otherwise the inner message would have to be
|
||||
// parsed in order to perform the check, defeating the purpose of lazy
|
||||
// parsing. An implementation which chooses not to check required fields
|
||||
// must be consistent about it. That is, for any particular sub-message, the
|
||||
// implementation must either *always* check its required fields, or *never*
|
||||
// check its required fields, regardless of whether or not the message has
|
||||
// been parsed.
|
||||
//
|
||||
// As of May 2022, lazy verifies the contents of the byte stream during
|
||||
// parsing. An invalid byte stream will cause the overall parsing to fail.
|
||||
optional bool lazy = 5 [default = false];
|
||||
|
||||
// unverified_lazy does no correctness checks on the byte stream. This should
|
||||
// only be used where lazy with verification is prohibitive for performance
|
||||
// reasons.
|
||||
optional bool unverified_lazy = 15 [default = false];
|
||||
|
||||
// Is this field deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for accessors, or it will be completely ignored; in the very least, this
|
||||
// is a formalization for deprecating fields.
|
||||
optional bool deprecated = 3 [default = false];
|
||||
|
||||
// For Google-internal migration only. Do not use.
|
||||
optional bool weak = 10 [default = false];
|
||||
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
|
||||
reserved 4; // removed jtype
|
||||
}
|
||||
|
||||
message OneofOptions {
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message EnumOptions {
|
||||
|
||||
// Set this option to true to allow mapping different tag names to the same
|
||||
// value.
|
||||
optional bool allow_alias = 2;
|
||||
|
||||
// Is this enum deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the enum, or it will be completely ignored; in the very least, this
|
||||
// is a formalization for deprecating enums.
|
||||
optional bool deprecated = 3 [default = false];
|
||||
|
||||
reserved 5; // javanano_as_lite
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message EnumValueOptions {
|
||||
// Is this enum value deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the enum value, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating enum values.
|
||||
optional bool deprecated = 1 [default = false];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message ServiceOptions {
|
||||
|
||||
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
|
||||
// framework. We apologize for hoarding these numbers to ourselves, but
|
||||
// we were already using them long before we decided to release Protocol
|
||||
// Buffers.
|
||||
|
||||
// Is this service deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the service, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating services.
|
||||
optional bool deprecated = 33 [default = false];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message MethodOptions {
|
||||
|
||||
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
|
||||
// framework. We apologize for hoarding these numbers to ourselves, but
|
||||
// we were already using them long before we decided to release Protocol
|
||||
// Buffers.
|
||||
|
||||
// Is this method deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the method, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating methods.
|
||||
optional bool deprecated = 33 [default = false];
|
||||
|
||||
// Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
|
||||
// or neither? HTTP based RPC implementation may choose GET verb for safe
|
||||
// methods, and PUT verb for idempotent methods instead of the default POST.
|
||||
enum IdempotencyLevel {
|
||||
IDEMPOTENCY_UNKNOWN = 0;
|
||||
NO_SIDE_EFFECTS = 1; // implies idempotent
|
||||
IDEMPOTENT = 2; // idempotent, but may have side effects
|
||||
}
|
||||
optional IdempotencyLevel idempotency_level = 34
|
||||
[default = IDEMPOTENCY_UNKNOWN];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
|
||||
// A message representing a option the parser does not recognize. This only
|
||||
// appears in options protos created by the compiler::Parser class.
|
||||
// DescriptorPool resolves these when building Descriptor objects. Therefore,
|
||||
// options protos in descriptor objects (e.g. returned by Descriptor::options(),
|
||||
// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
|
||||
// in them.
|
||||
message UninterpretedOption {
|
||||
// The name of the uninterpreted option. Each string represents a segment in
|
||||
// a dot-separated name. is_extension is true iff a segment represents an
|
||||
// extension (denoted with parentheses in options specs in .proto files).
|
||||
// E.g.,{ ["foo", false], ["bar.baz", true], ["moo", false] } represents
|
||||
// "foo.(bar.baz).moo".
|
||||
message NamePart {
|
||||
required string name_part = 1;
|
||||
required bool is_extension = 2;
|
||||
}
|
||||
repeated NamePart name = 2;
|
||||
|
||||
// The value of the uninterpreted option, in whatever type the tokenizer
|
||||
// identified it as during parsing. Exactly one of these should be set.
|
||||
optional string identifier_value = 3;
|
||||
optional uint64 positive_int_value = 4;
|
||||
optional int64 negative_int_value = 5;
|
||||
optional double double_value = 6;
|
||||
optional bytes string_value = 7;
|
||||
optional string aggregate_value = 8;
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Optional source code info
|
||||
|
||||
// Encapsulates information about the original source file from which a
|
||||
// FileDescriptorProto was generated.
|
||||
message SourceCodeInfo {
|
||||
// A Location identifies a piece of source code in a .proto file which
|
||||
// corresponds to a particular definition. This information is intended
|
||||
// to be useful to IDEs, code indexers, documentation generators, and similar
|
||||
// tools.
|
||||
//
|
||||
// For example, say we have a file like:
|
||||
// message Foo {
|
||||
// optional string foo = 1;
|
||||
// }
|
||||
// Let's look at just the field definition:
|
||||
// optional string foo = 1;
|
||||
// ^ ^^ ^^ ^ ^^^
|
||||
// a bc de f ghi
|
||||
// We have the following locations:
|
||||
// span path represents
|
||||
// [a,i) [ 4, 0, 2, 0 ] The whole field definition.
|
||||
// [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
|
||||
// [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
|
||||
// [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
|
||||
// [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
|
||||
//
|
||||
// Notes:
|
||||
// - A location may refer to a repeated field itself (i.e. not to any
|
||||
// particular index within it). This is used whenever a set of elements are
|
||||
// logically enclosed in a single code segment. For example, an entire
|
||||
// extend block (possibly containing multiple extension definitions) will
|
||||
// have an outer location whose path refers to the "extensions" repeated
|
||||
// field without an index.
|
||||
// - Multiple locations may have the same path. This happens when a single
|
||||
// logical declaration is spread out across multiple places. The most
|
||||
// obvious example is the "extend" block again -- there may be multiple
|
||||
// extend blocks in the same scope, each of which will have the same path.
|
||||
// - A location's span is not always a subset of its parent's span. For
|
||||
// example, the "extendee" of an extension declaration appears at the
|
||||
// beginning of the "extend" block and is shared by all extensions within
|
||||
// the block.
|
||||
// - Just because a location's span is a subset of some other location's span
|
||||
// does not mean that it is a descendant. For example, a "group" defines
|
||||
// both a type and a field in a single declaration. Thus, the locations
|
||||
// corresponding to the type and field and their components will overlap.
|
||||
// - Code which tries to interpret locations should probably be designed to
|
||||
// ignore those that it doesn't understand, as more types of locations could
|
||||
// be recorded in the future.
|
||||
repeated Location location = 1;
|
||||
message Location {
|
||||
// Identifies which part of the FileDescriptorProto was defined at this
|
||||
// location.
|
||||
//
|
||||
// Each element is a field number or an index. They form a path from
|
||||
// the root FileDescriptorProto to the place where the definition occurs.
|
||||
// For example, this path:
|
||||
// [ 4, 3, 2, 7, 1 ]
|
||||
// refers to:
|
||||
// file.message_type(3) // 4, 3
|
||||
// .field(7) // 2, 7
|
||||
// .name() // 1
|
||||
// This is because FileDescriptorProto.message_type has field number 4:
|
||||
// repeated DescriptorProto message_type = 4;
|
||||
// and DescriptorProto.field has field number 2:
|
||||
// repeated FieldDescriptorProto field = 2;
|
||||
// and FieldDescriptorProto.name has field number 1:
|
||||
// optional string name = 1;
|
||||
//
|
||||
// Thus, the above path gives the location of a field name. If we removed
|
||||
// the last element:
|
||||
// [ 4, 3, 2, 7 ]
|
||||
// this path refers to the whole field declaration (from the beginning
|
||||
// of the label to the terminating semicolon).
|
||||
repeated int32 path = 1 [packed = true];
|
||||
|
||||
// Always has exactly three or four elements: start line, start column,
|
||||
// end line (optional, otherwise assumed same as start line), end column.
|
||||
// These are packed into a single field for efficiency. Note that line
|
||||
// and column numbers are zero-based -- typically you will want to add
|
||||
// 1 to each before displaying to a user.
|
||||
repeated int32 span = 2 [packed = true];
|
||||
|
||||
// If this SourceCodeInfo represents a complete declaration, these are any
|
||||
// comments appearing before and after the declaration which appear to be
|
||||
// attached to the declaration.
|
||||
//
|
||||
// A series of line comments appearing on consecutive lines, with no other
|
||||
// tokens appearing on those lines, will be treated as a single comment.
|
||||
//
|
||||
// leading_detached_comments will keep paragraphs of comments that appear
|
||||
// before (but not connected to) the current element. Each paragraph,
|
||||
// separated by empty lines, will be one comment element in the repeated
|
||||
// field.
|
||||
//
|
||||
// Only the comment content is provided; comment markers (e.g. //) are
|
||||
// stripped out. For block comments, leading whitespace and an asterisk
|
||||
// will be stripped from the beginning of each line other than the first.
|
||||
// Newlines are included in the output.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// optional int32 foo = 1; // Comment attached to foo.
|
||||
// // Comment attached to bar.
|
||||
// optional int32 bar = 2;
|
||||
//
|
||||
// optional string baz = 3;
|
||||
// // Comment attached to baz.
|
||||
// // Another line attached to baz.
|
||||
//
|
||||
// // Comment attached to moo.
|
||||
// //
|
||||
// // Another line attached to moo.
|
||||
// optional double moo = 4;
|
||||
//
|
||||
// // Detached comment for corge. This is not leading or trailing comments
|
||||
// // to moo or corge because there are blank lines separating it from
|
||||
// // both.
|
||||
//
|
||||
// // Detached comment for corge paragraph 2.
|
||||
//
|
||||
// optional string corge = 5;
|
||||
// /* Block comment attached
|
||||
// * to corge. Leading asterisks
|
||||
// * will be removed. */
|
||||
// /* Block comment attached to
|
||||
// * grault. */
|
||||
// optional int32 grault = 6;
|
||||
//
|
||||
// // ignored detached comments.
|
||||
optional string leading_comments = 3;
|
||||
optional string trailing_comments = 4;
|
||||
repeated string leading_detached_comments = 6;
|
||||
}
|
||||
}
|
||||
|
||||
// Describes the relationship between generated code and its original source
|
||||
// file. A GeneratedCodeInfo message is associated with only one generated
|
||||
// source file, but may contain references to different source .proto files.
|
||||
message GeneratedCodeInfo {
|
||||
// An Annotation connects some span of text in generated code to an element
|
||||
// of its generating .proto file.
|
||||
repeated Annotation annotation = 1;
|
||||
message Annotation {
|
||||
// Identifies the element in the original source .proto file. This field
|
||||
// is formatted the same as SourceCodeInfo.Location.path.
|
||||
repeated int32 path = 1 [packed = true];
|
||||
|
||||
// Identifies the filesystem path to the original source .proto.
|
||||
optional string source_file = 2;
|
||||
|
||||
// Identifies the starting offset in bytes in the generated code
|
||||
// that relates to the identified object.
|
||||
optional int32 begin = 3;
|
||||
|
||||
// Identifies the ending offset in bytes in the generated code that
|
||||
// relates to the identified offset. The end offset should be one past
|
||||
// the last relevant byte (so the length of the text = end - begin).
|
||||
optional int32 end = 4;
|
||||
}
|
||||
}
|
||||
862
api/pb/validate.proto
Normal file
862
api/pb/validate.proto
Normal file
@ -0,0 +1,862 @@
|
||||
syntax = "proto2";
|
||||
package validate;
|
||||
|
||||
option go_package = "github.com/envoyproxy/protoc-gen-validate/validate";
|
||||
option java_package = "io.envoyproxy.pgv.validate";
|
||||
|
||||
import "google/protobuf/descriptor.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
// Validation rules applied at the message level
|
||||
extend google.protobuf.MessageOptions {
|
||||
// Disabled nullifies any validation rules for this message, including any
|
||||
// message fields associated with it that do support validation.
|
||||
optional bool disabled = 1071;
|
||||
// Ignore skips generation of validation methods for this message.
|
||||
optional bool ignored = 1072;
|
||||
}
|
||||
|
||||
// Validation rules applied at the oneof level
|
||||
extend google.protobuf.OneofOptions {
|
||||
// Required ensures that exactly one the field options in a oneof is set;
|
||||
// validation fails if no fields in the oneof are set.
|
||||
optional bool required = 1071;
|
||||
}
|
||||
|
||||
// Validation rules applied at the field level
|
||||
extend google.protobuf.FieldOptions {
|
||||
// Rules specify the validations to be performed on this field. By default,
|
||||
// no validation is performed against a field.
|
||||
optional FieldRules rules = 1071;
|
||||
}
|
||||
|
||||
// FieldRules encapsulates the rules for each type of field. Depending on the
|
||||
// field, the correct set should be used to ensure proper validations.
|
||||
message FieldRules {
|
||||
optional MessageRules message = 17;
|
||||
oneof type {
|
||||
// Scalar Field Types
|
||||
FloatRules float = 1;
|
||||
DoubleRules double = 2;
|
||||
Int32Rules int32 = 3;
|
||||
Int64Rules int64 = 4;
|
||||
UInt32Rules uint32 = 5;
|
||||
UInt64Rules uint64 = 6;
|
||||
SInt32Rules sint32 = 7;
|
||||
SInt64Rules sint64 = 8;
|
||||
Fixed32Rules fixed32 = 9;
|
||||
Fixed64Rules fixed64 = 10;
|
||||
SFixed32Rules sfixed32 = 11;
|
||||
SFixed64Rules sfixed64 = 12;
|
||||
BoolRules bool = 13;
|
||||
StringRules string = 14;
|
||||
BytesRules bytes = 15;
|
||||
|
||||
// Complex Field Types
|
||||
EnumRules enum = 16;
|
||||
RepeatedRules repeated = 18;
|
||||
MapRules map = 19;
|
||||
|
||||
// Well-Known Field Types
|
||||
AnyRules any = 20;
|
||||
DurationRules duration = 21;
|
||||
TimestampRules timestamp = 22;
|
||||
}
|
||||
}
|
||||
|
||||
// FloatRules describes the constraints applied to `float` values
|
||||
message FloatRules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional float const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional float lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional float lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional float gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional float gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated float in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated float not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// DoubleRules describes the constraints applied to `double` values
|
||||
message DoubleRules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional double const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional double lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional double lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional double gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional double gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated double in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated double not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// Int32Rules describes the constraints applied to `int32` values
|
||||
message Int32Rules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional int32 const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional int32 lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional int32 lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional int32 gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional int32 gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated int32 in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated int32 not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// Int64Rules describes the constraints applied to `int64` values
|
||||
message Int64Rules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional int64 const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional int64 lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional int64 lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional int64 gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional int64 gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated int64 in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated int64 not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// UInt32Rules describes the constraints applied to `uint32` values
|
||||
message UInt32Rules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional uint32 const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional uint32 lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional uint32 lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional uint32 gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional uint32 gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated uint32 in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated uint32 not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// UInt64Rules describes the constraints applied to `uint64` values
|
||||
message UInt64Rules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional uint64 const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional uint64 lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional uint64 lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional uint64 gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional uint64 gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated uint64 in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated uint64 not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// SInt32Rules describes the constraints applied to `sint32` values
|
||||
message SInt32Rules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional sint32 const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional sint32 lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional sint32 lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional sint32 gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional sint32 gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated sint32 in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated sint32 not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// SInt64Rules describes the constraints applied to `sint64` values
|
||||
message SInt64Rules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional sint64 const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional sint64 lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional sint64 lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional sint64 gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional sint64 gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated sint64 in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated sint64 not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// Fixed32Rules describes the constraints applied to `fixed32` values
|
||||
message Fixed32Rules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional fixed32 const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional fixed32 lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional fixed32 lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional fixed32 gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional fixed32 gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated fixed32 in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated fixed32 not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// Fixed64Rules describes the constraints applied to `fixed64` values
|
||||
message Fixed64Rules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional fixed64 const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional fixed64 lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional fixed64 lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional fixed64 gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional fixed64 gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated fixed64 in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated fixed64 not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// SFixed32Rules describes the constraints applied to `sfixed32` values
|
||||
message SFixed32Rules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional sfixed32 const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional sfixed32 lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional sfixed32 lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional sfixed32 gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional sfixed32 gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated sfixed32 in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated sfixed32 not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// SFixed64Rules describes the constraints applied to `sfixed64` values
|
||||
message SFixed64Rules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional sfixed64 const = 1;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional sfixed64 lt = 2;
|
||||
|
||||
// Lte specifies that this field must be less than or equal to the
|
||||
// specified value, inclusive
|
||||
optional sfixed64 lte = 3;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive. If the value of Gt is larger than a specified Lt or Lte, the
|
||||
// range is reversed.
|
||||
optional sfixed64 gt = 4;
|
||||
|
||||
// Gte specifies that this field must be greater than or equal to the
|
||||
// specified value, inclusive. If the value of Gte is larger than a
|
||||
// specified Lt or Lte, the range is reversed.
|
||||
optional sfixed64 gte = 5;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated sfixed64 in = 6;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated sfixed64 not_in = 7;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 8;
|
||||
}
|
||||
|
||||
// BoolRules describes the constraints applied to `bool` values
|
||||
message BoolRules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional bool const = 1;
|
||||
}
|
||||
|
||||
// StringRules describe the constraints applied to `string` values
|
||||
message StringRules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional string const = 1;
|
||||
|
||||
// Len specifies that this field must be the specified number of
|
||||
// characters (Unicode code points). Note that the number of
|
||||
// characters may differ from the number of bytes in the string.
|
||||
optional uint64 len = 19;
|
||||
|
||||
// MinLen specifies that this field must be the specified number of
|
||||
// characters (Unicode code points) at a minimum. Note that the number of
|
||||
// characters may differ from the number of bytes in the string.
|
||||
optional uint64 min_len = 2;
|
||||
|
||||
// MaxLen specifies that this field must be the specified number of
|
||||
// characters (Unicode code points) at a maximum. Note that the number of
|
||||
// characters may differ from the number of bytes in the string.
|
||||
optional uint64 max_len = 3;
|
||||
|
||||
// LenBytes specifies that this field must be the specified number of bytes
|
||||
optional uint64 len_bytes = 20;
|
||||
|
||||
// MinBytes specifies that this field must be the specified number of bytes
|
||||
// at a minimum
|
||||
optional uint64 min_bytes = 4;
|
||||
|
||||
// MaxBytes specifies that this field must be the specified number of bytes
|
||||
// at a maximum
|
||||
optional uint64 max_bytes = 5;
|
||||
|
||||
// Pattern specifes that this field must match against the specified
|
||||
// regular expression (RE2 syntax). The included expression should elide
|
||||
// any delimiters.
|
||||
optional string pattern = 6;
|
||||
|
||||
// Prefix specifies that this field must have the specified substring at
|
||||
// the beginning of the string.
|
||||
optional string prefix = 7;
|
||||
|
||||
// Suffix specifies that this field must have the specified substring at
|
||||
// the end of the string.
|
||||
optional string suffix = 8;
|
||||
|
||||
// Contains specifies that this field must have the specified substring
|
||||
// anywhere in the string.
|
||||
optional string contains = 9;
|
||||
|
||||
// NotContains specifies that this field cannot have the specified substring
|
||||
// anywhere in the string.
|
||||
optional string not_contains = 23;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated string in = 10;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated string not_in = 11;
|
||||
|
||||
// WellKnown rules provide advanced constraints against common string
|
||||
// patterns
|
||||
oneof well_known {
|
||||
// Email specifies that the field must be a valid email address as
|
||||
// defined by RFC 5322
|
||||
bool email = 12;
|
||||
|
||||
// Hostname specifies that the field must be a valid hostname as
|
||||
// defined by RFC 1034. This constraint does not support
|
||||
// internationalized domain names (IDNs).
|
||||
bool hostname = 13;
|
||||
|
||||
// Ip specifies that the field must be a valid IP (v4 or v6) address.
|
||||
// Valid IPv6 addresses should not include surrounding square brackets.
|
||||
bool ip = 14;
|
||||
|
||||
// Ipv4 specifies that the field must be a valid IPv4 address.
|
||||
bool ipv4 = 15;
|
||||
|
||||
// Ipv6 specifies that the field must be a valid IPv6 address. Valid
|
||||
// IPv6 addresses should not include surrounding square brackets.
|
||||
bool ipv6 = 16;
|
||||
|
||||
// Uri specifies that the field must be a valid, absolute URI as defined
|
||||
// by RFC 3986
|
||||
bool uri = 17;
|
||||
|
||||
// UriRef specifies that the field must be a valid URI as defined by RFC
|
||||
// 3986 and may be relative or absolute.
|
||||
bool uri_ref = 18;
|
||||
|
||||
// Address specifies that the field must be either a valid hostname as
|
||||
// defined by RFC 1034 (which does not support internationalized domain
|
||||
// names or IDNs), or it can be a valid IP (v4 or v6).
|
||||
bool address = 21;
|
||||
|
||||
// Uuid specifies that the field must be a valid UUID as defined by
|
||||
// RFC 4122
|
||||
bool uuid = 22;
|
||||
|
||||
// WellKnownRegex specifies a common well known pattern defined as a regex.
|
||||
KnownRegex well_known_regex = 24;
|
||||
}
|
||||
|
||||
// This applies to regexes HTTP_HEADER_NAME and HTTP_HEADER_VALUE to enable
|
||||
// strict header validation.
|
||||
// By default, this is true, and HTTP header validations are RFC-compliant.
|
||||
// Setting to false will enable a looser validations that only disallows
|
||||
// \r\n\0 characters, which can be used to bypass header matching rules.
|
||||
optional bool strict = 25 [default = true];
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 26;
|
||||
}
|
||||
|
||||
// WellKnownRegex contain some well-known patterns.
|
||||
enum KnownRegex {
|
||||
UNKNOWN = 0;
|
||||
|
||||
// HTTP header name as defined by RFC 7230.
|
||||
HTTP_HEADER_NAME = 1;
|
||||
|
||||
// HTTP header value as defined by RFC 7230.
|
||||
HTTP_HEADER_VALUE = 2;
|
||||
}
|
||||
|
||||
// BytesRules describe the constraints applied to `bytes` values
|
||||
message BytesRules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional bytes const = 1;
|
||||
|
||||
// Len specifies that this field must be the specified number of bytes
|
||||
optional uint64 len = 13;
|
||||
|
||||
// MinLen specifies that this field must be the specified number of bytes
|
||||
// at a minimum
|
||||
optional uint64 min_len = 2;
|
||||
|
||||
// MaxLen specifies that this field must be the specified number of bytes
|
||||
// at a maximum
|
||||
optional uint64 max_len = 3;
|
||||
|
||||
// Pattern specifes that this field must match against the specified
|
||||
// regular expression (RE2 syntax). The included expression should elide
|
||||
// any delimiters.
|
||||
optional string pattern = 4;
|
||||
|
||||
// Prefix specifies that this field must have the specified bytes at the
|
||||
// beginning of the string.
|
||||
optional bytes prefix = 5;
|
||||
|
||||
// Suffix specifies that this field must have the specified bytes at the
|
||||
// end of the string.
|
||||
optional bytes suffix = 6;
|
||||
|
||||
// Contains specifies that this field must have the specified bytes
|
||||
// anywhere in the string.
|
||||
optional bytes contains = 7;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated bytes in = 8;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated bytes not_in = 9;
|
||||
|
||||
// WellKnown rules provide advanced constraints against common byte
|
||||
// patterns
|
||||
oneof well_known {
|
||||
// Ip specifies that the field must be a valid IP (v4 or v6) address in
|
||||
// byte format
|
||||
bool ip = 10;
|
||||
|
||||
// Ipv4 specifies that the field must be a valid IPv4 address in byte
|
||||
// format
|
||||
bool ipv4 = 11;
|
||||
|
||||
// Ipv6 specifies that the field must be a valid IPv6 address in byte
|
||||
// format
|
||||
bool ipv6 = 12;
|
||||
}
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 14;
|
||||
}
|
||||
|
||||
// EnumRules describe the constraints applied to enum values
|
||||
message EnumRules {
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional int32 const = 1;
|
||||
|
||||
// DefinedOnly specifies that this field must be only one of the defined
|
||||
// values for this enum, failing on any undefined value.
|
||||
optional bool defined_only = 2;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated int32 in = 3;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated int32 not_in = 4;
|
||||
}
|
||||
|
||||
// MessageRules describe the constraints applied to embedded message values.
|
||||
// For message-type fields, validation is performed recursively.
|
||||
message MessageRules {
|
||||
// Skip specifies that the validation rules of this field should not be
|
||||
// evaluated
|
||||
optional bool skip = 1;
|
||||
|
||||
// Required specifies that this field must be set
|
||||
optional bool required = 2;
|
||||
}
|
||||
|
||||
// RepeatedRules describe the constraints applied to `repeated` values
|
||||
message RepeatedRules {
|
||||
// MinItems specifies that this field must have the specified number of
|
||||
// items at a minimum
|
||||
optional uint64 min_items = 1;
|
||||
|
||||
// MaxItems specifies that this field must have the specified number of
|
||||
// items at a maximum
|
||||
optional uint64 max_items = 2;
|
||||
|
||||
// Unique specifies that all elements in this field must be unique. This
|
||||
// contraint is only applicable to scalar and enum types (messages are not
|
||||
// supported).
|
||||
optional bool unique = 3;
|
||||
|
||||
// Items specifies the contraints to be applied to each item in the field.
|
||||
// Repeated message fields will still execute validation against each item
|
||||
// unless skip is specified here.
|
||||
optional FieldRules items = 4;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 5;
|
||||
}
|
||||
|
||||
// MapRules describe the constraints applied to `map` values
|
||||
message MapRules {
|
||||
// MinPairs specifies that this field must have the specified number of
|
||||
// KVs at a minimum
|
||||
optional uint64 min_pairs = 1;
|
||||
|
||||
// MaxPairs specifies that this field must have the specified number of
|
||||
// KVs at a maximum
|
||||
optional uint64 max_pairs = 2;
|
||||
|
||||
// NoSparse specifies values in this field cannot be unset. This only
|
||||
// applies to map's with message value types.
|
||||
optional bool no_sparse = 3;
|
||||
|
||||
// Keys specifies the constraints to be applied to each key in the field.
|
||||
optional FieldRules keys = 4;
|
||||
|
||||
// Values specifies the constraints to be applied to the value of each key
|
||||
// in the field. Message values will still have their validations evaluated
|
||||
// unless skip is specified here.
|
||||
optional FieldRules values = 5;
|
||||
|
||||
// IgnoreEmpty specifies that the validation rules of this field should be
|
||||
// evaluated only if the field is not empty
|
||||
optional bool ignore_empty = 6;
|
||||
}
|
||||
|
||||
// AnyRules describe constraints applied exclusively to the
|
||||
// `google.protobuf.Any` well-known type
|
||||
message AnyRules {
|
||||
// Required specifies that this field must be set
|
||||
optional bool required = 1;
|
||||
|
||||
// In specifies that this field's `type_url` must be equal to one of the
|
||||
// specified values.
|
||||
repeated string in = 2;
|
||||
|
||||
// NotIn specifies that this field's `type_url` must not be equal to any of
|
||||
// the specified values.
|
||||
repeated string not_in = 3;
|
||||
}
|
||||
|
||||
// DurationRules describe the constraints applied exclusively to the
|
||||
// `google.protobuf.Duration` well-known type
|
||||
message DurationRules {
|
||||
// Required specifies that this field must be set
|
||||
optional bool required = 1;
|
||||
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional google.protobuf.Duration const = 2;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional google.protobuf.Duration lt = 3;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// inclusive
|
||||
optional google.protobuf.Duration lte = 4;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive
|
||||
optional google.protobuf.Duration gt = 5;
|
||||
|
||||
// Gte specifies that this field must be greater than the specified value,
|
||||
// inclusive
|
||||
optional google.protobuf.Duration gte = 6;
|
||||
|
||||
// In specifies that this field must be equal to one of the specified
|
||||
// values
|
||||
repeated google.protobuf.Duration in = 7;
|
||||
|
||||
// NotIn specifies that this field cannot be equal to one of the specified
|
||||
// values
|
||||
repeated google.protobuf.Duration not_in = 8;
|
||||
}
|
||||
|
||||
// TimestampRules describe the constraints applied exclusively to the
|
||||
// `google.protobuf.Timestamp` well-known type
|
||||
message TimestampRules {
|
||||
// Required specifies that this field must be set
|
||||
optional bool required = 1;
|
||||
|
||||
// Const specifies that this field must be exactly the specified value
|
||||
optional google.protobuf.Timestamp const = 2;
|
||||
|
||||
// Lt specifies that this field must be less than the specified value,
|
||||
// exclusive
|
||||
optional google.protobuf.Timestamp lt = 3;
|
||||
|
||||
// Lte specifies that this field must be less than the specified value,
|
||||
// inclusive
|
||||
optional google.protobuf.Timestamp lte = 4;
|
||||
|
||||
// Gt specifies that this field must be greater than the specified value,
|
||||
// exclusive
|
||||
optional google.protobuf.Timestamp gt = 5;
|
||||
|
||||
// Gte specifies that this field must be greater than the specified value,
|
||||
// inclusive
|
||||
optional google.protobuf.Timestamp gte = 6;
|
||||
|
||||
// LtNow specifies that this must be less than the current time. LtNow
|
||||
// can only be used with the Within rule.
|
||||
optional bool lt_now = 7;
|
||||
|
||||
// GtNow specifies that this must be greater than the current time. GtNow
|
||||
// can only be used with the Within rule.
|
||||
optional bool gt_now = 8;
|
||||
|
||||
// Within specifies that this field must be within this duration of the
|
||||
// current time. This constraint can be used alone or with the LtNow and
|
||||
// GtNow rules.
|
||||
optional google.protobuf.Duration within = 9;
|
||||
}
|
||||
78
api/pb/validator.proto
Normal file
78
api/pb/validator.proto
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright 2016 Michal Witkowski. All Rights Reserved.
|
||||
// See LICENSE for licensing terms.
|
||||
|
||||
// Protocol Buffers extensions for defining auto-generateable validators for messages.
|
||||
|
||||
|
||||
|
||||
syntax = "proto2";
|
||||
package validator;
|
||||
|
||||
import "pb/descriptor.proto";
|
||||
|
||||
option go_package = "github.com/mwitkow/go-proto-validators;validator";
|
||||
|
||||
|
||||
extend google.protobuf.FieldOptions {
|
||||
optional FieldValidator field = 65020;
|
||||
}
|
||||
|
||||
extend google.protobuf.OneofOptions {
|
||||
optional OneofValidator oneof = 65021;
|
||||
}
|
||||
|
||||
message FieldValidator {
|
||||
// Uses a Golang RE2-syntax regex to match the field contents.
|
||||
optional string regex = 1;
|
||||
// Field value of integer strictly greater than this value.
|
||||
optional int64 int_gt = 2;
|
||||
// Field value of integer strictly smaller than this value.
|
||||
optional int64 int_lt = 3;
|
||||
// Used for nested message types, requires that the message type exists.
|
||||
optional bool msg_exists = 4;
|
||||
// Human error specifies a user-customizable error that is visible to the user.
|
||||
optional string human_error = 5;
|
||||
// Field value of double strictly greater than this value.
|
||||
// Note that this value can only take on a valid floating point
|
||||
// value. Use together with float_epsilon if you need something more specific.
|
||||
optional double float_gt = 6;
|
||||
// Field value of double strictly smaller than this value.
|
||||
// Note that this value can only take on a valid floating point
|
||||
// value. Use together with float_epsilon if you need something more specific.
|
||||
optional double float_lt = 7;
|
||||
// Field value of double describing the epsilon within which
|
||||
// any comparison should be considered to be true. For example,
|
||||
// when using float_gt = 0.35, using a float_epsilon of 0.05
|
||||
// would mean that any value above 0.30 is acceptable. It can be
|
||||
// thought of as a {float_value_condition} +- {float_epsilon}.
|
||||
// If unset, no correction for floating point inaccuracies in
|
||||
// comparisons will be attempted.
|
||||
optional double float_epsilon = 8;
|
||||
// Floating-point value compared to which the field content should be greater or equal.
|
||||
optional double float_gte = 9;
|
||||
// Floating-point value compared to which the field content should be smaller or equal.
|
||||
optional double float_lte = 10;
|
||||
// Used for string fields, requires the string to be not empty (i.e different from "").
|
||||
optional bool string_not_empty = 11;
|
||||
// Repeated field with at least this number of elements.
|
||||
optional int64 repeated_count_min = 12;
|
||||
// Repeated field with at most this number of elements.
|
||||
optional int64 repeated_count_max = 13;
|
||||
// Field value of length greater than this value.
|
||||
optional int64 length_gt = 14;
|
||||
// Field value of length smaller than this value.
|
||||
optional int64 length_lt = 15;
|
||||
// Field value of length strictly equal to this value.
|
||||
optional int64 length_eq = 16;
|
||||
// Requires that the value is in the enum.
|
||||
optional bool is_in_enum = 17;
|
||||
// Ensures that a string value is in UUID format.
|
||||
// uuid_ver specifies the valid UUID versions. Valid values are: 0-5.
|
||||
// If uuid_ver is 0 all UUID versions are accepted.
|
||||
optional int32 uuid_ver = 18;
|
||||
}
|
||||
|
||||
message OneofValidator {
|
||||
// Require that one of the oneof fields is set.
|
||||
optional bool required = 1;
|
||||
}
|
||||
@ -119,7 +119,9 @@ type System struct {
|
||||
ErpHost string
|
||||
FieeHost string
|
||||
AuthRedirectUrl string
|
||||
AuthCallback string
|
||||
CronOpen bool
|
||||
ProxyUrl string
|
||||
}
|
||||
type Oss struct {
|
||||
AccessKeyId string
|
||||
|
||||
16
conf/alibabacloud.env
Normal file
16
conf/alibabacloud.env
Normal file
@ -0,0 +1,16 @@
|
||||
#=========== 阿里云内容安全配置 ===========
|
||||
# STS登录模式配置
|
||||
# RAM用户AccessKey ID(用于获取STS临时凭证)
|
||||
RAM_ACCESS_KEY_ID=LTAI5tNBzbeEbG1yCitvHsMb
|
||||
|
||||
# RAM用户AccessKey Secret
|
||||
RAM_ACCESS_KEY_SECRET=G1xAUB8G6WDVo0SLr6DJaJjNWIlpmO
|
||||
|
||||
# 要扮演的RAM角色ARN
|
||||
RAM_ROLE_ARN=acs:ram::5828544250383902:role/content-secret
|
||||
|
||||
# 阿里云区域(可选,默认为cn-shanghai)
|
||||
ALIBABA_CLOUD_REGION=ap-southeast-1
|
||||
|
||||
# 阿里云端点(可选,默认为green.cn-shanghai.aliyuncs.com)
|
||||
ALIBABA_CLOUD_ENDPOINT=green-cip.ap-southeast-1.aliyuncs.com
|
||||
@ -18,7 +18,7 @@ AccessKeyId = "${OSS_AK}"
|
||||
AccessKeySecret = "${OSS_SK}"
|
||||
Endpoint = "${OSS_ENDPOINTT}"
|
||||
BucketName = "${OSS_BUCKETNAME}"
|
||||
BaseDir = "fontree-fiee-test"
|
||||
BaseDir = "fonchain-main"
|
||||
CdnHost = "${OSS_CDN}"
|
||||
[redis]
|
||||
RedisDB = "2"
|
||||
|
||||
@ -27,7 +27,6 @@ dubbo:
|
||||
protocol: tri
|
||||
retries: 0
|
||||
interface: com.fontree.microservices.fiee.bundle # must be compatible with grpc or dubbo-java
|
||||
SecFilingsClientImpl:
|
||||
CastClientImpl:
|
||||
protocol: tri
|
||||
retries: 0
|
||||
interface: com.fontree.microservices.fiee.SecFiling
|
||||
interface: com.fontree.microservices.fiee.multicast
|
||||
BIN
data/图文导入模板.xlsx
Normal file
BIN
data/图文导入模板.xlsx
Normal file
Binary file not shown.
16
docs/dev/alibabacloud.env
Normal file
16
docs/dev/alibabacloud.env
Normal file
@ -0,0 +1,16 @@
|
||||
#=========== 阿里云内容安全配置 ===========
|
||||
# STS登录模式配置
|
||||
# RAM用户AccessKey ID(用于获取STS临时凭证)
|
||||
RAM_ACCESS_KEY_ID=LTAI5tNBzbeEbG1yCitvHsMb
|
||||
|
||||
# RAM用户AccessKey Secret
|
||||
RAM_ACCESS_KEY_SECRET=G1xAUB8G6WDVo0SLr6DJaJjNWIlpmO
|
||||
|
||||
# 要扮演的RAM角色ARN
|
||||
RAM_ROLE_ARN=acs:ram::5828544250383902:role/content-secret
|
||||
|
||||
# 阿里云区域(可选,默认为cn-shanghai)
|
||||
ALIBABA_CLOUD_REGION=ap-southeast-1
|
||||
|
||||
# 阿里云端点(可选,默认为green.cn-shanghai.aliyuncs.com)
|
||||
ALIBABA_CLOUD_ENDPOINT=green-cip.ap-southeast-1.aliyuncs.com
|
||||
@ -7,7 +7,9 @@ RedirectUri = "/api/redirect/url"
|
||||
ErpHost = "http://erpapi.test.fontree.cn:8081"
|
||||
FieeHost = "http://erpapi.test.fontree.cn:8081"
|
||||
AuthRedirectUrl = "http://saas-erp.test.fontree.cn:8081/media_account"
|
||||
AuthCallback = "https://saas-test.szjixun.cn/api/fiee/media/as-oauth2callback"
|
||||
CronOpen = false
|
||||
proxyUrl = "http://47.84.75.255:6785"
|
||||
[bos]
|
||||
Ak = "ALTAKxrqOQHnAN525Tb2GX4Bhe"
|
||||
Sk = "d2ecaa9d75114d3b9f42b99014198306"
|
||||
|
||||
@ -9,7 +9,7 @@ dubbo:
|
||||
# address: 114.218.158.24:2181
|
||||
consumer:
|
||||
filter: tracing
|
||||
request-timeout: 30s
|
||||
request-timeout: 300s
|
||||
references:
|
||||
OrderClientImpl:
|
||||
protocol: tri
|
||||
@ -47,6 +47,9 @@ dubbo:
|
||||
protocol: tri
|
||||
retries: 0
|
||||
interface: com.fontree.microservices.fiee.SecFiling
|
||||
AyrshareClientImpl:
|
||||
protocol: tri
|
||||
interface: com.fontree.microservices.fiee.ayrshare
|
||||
logger:
|
||||
zap-config:
|
||||
level: error # 日志级别
|
||||
|
||||
16
docs/prod/alibabacloud.env
Normal file
16
docs/prod/alibabacloud.env
Normal file
@ -0,0 +1,16 @@
|
||||
#=========== 阿里云内容安全配置 ===========
|
||||
# STS登录模式配置
|
||||
# RAM用户AccessKey ID(用于获取STS临时凭证)
|
||||
RAM_ACCESS_KEY_ID=LTAI5tNBzbeEbG1yCitvHsMb
|
||||
|
||||
# RAM用户AccessKey Secret
|
||||
RAM_ACCESS_KEY_SECRET=G1xAUB8G6WDVo0SLr6DJaJjNWIlpmO
|
||||
|
||||
# 要扮演的RAM角色ARN
|
||||
RAM_ROLE_ARN=acs:ram::5828544250383902:role/content-secret
|
||||
|
||||
# 阿里云区域(可选,默认为cn-shanghai)
|
||||
ALIBABA_CLOUD_REGION=ap-southeast-1
|
||||
|
||||
# 阿里云端点(可选,默认为green.cn-shanghai.aliyuncs.com)
|
||||
ALIBABA_CLOUD_ENDPOINT=green-cip.ap-southeast-1.aliyuncs.com
|
||||
@ -7,7 +7,9 @@ RedirectUri = "/api/redirect/url"
|
||||
ErpHost = "https://erpapi.fontree.cn"
|
||||
FieeHost = "https://erpapi.fiee.com"
|
||||
AuthRedirectUrl = "https://erp.fiee.com/media_account"
|
||||
AuthCallback = "https://erpapi.fiee.com/api/fiee/media/as-oauth2callback"
|
||||
CronOpen = true
|
||||
proxyUrl = ""
|
||||
[bos]
|
||||
Ak = "ALTAKxrqOQHnAN525Tb2GX4Bhe"
|
||||
Sk = "d2ecaa9d75114d3b9f42b99014198306"
|
||||
|
||||
@ -8,7 +8,7 @@ dubbo:
|
||||
# address: 114.218.158.24:2181
|
||||
consumer:
|
||||
filter: tracing
|
||||
request-timeout: 30s
|
||||
request-timeout: 300s
|
||||
references:
|
||||
OrderClientImpl:
|
||||
protocol: tri
|
||||
@ -49,6 +49,9 @@ dubbo:
|
||||
protocol: tri
|
||||
retries: 0
|
||||
interface: com.fontree.microservices.fiee.SecFiling
|
||||
AyrshareClientImpl:
|
||||
protocol: tri
|
||||
interface: com.fontree.microservices.fiee.ayrshare
|
||||
logger:
|
||||
zap-config:
|
||||
level: error # 日志级别
|
||||
|
||||
16
docs/test/alibabacloud.env
Normal file
16
docs/test/alibabacloud.env
Normal file
@ -0,0 +1,16 @@
|
||||
#=========== 阿里云内容安全配置 ===========
|
||||
# STS登录模式配置
|
||||
# RAM用户AccessKey ID(用于获取STS临时凭证)
|
||||
RAM_ACCESS_KEY_ID=LTAI5tNBzbeEbG1yCitvHsMb
|
||||
|
||||
# RAM用户AccessKey Secret
|
||||
RAM_ACCESS_KEY_SECRET=G1xAUB8G6WDVo0SLr6DJaJjNWIlpmO
|
||||
|
||||
# 要扮演的RAM角色ARN
|
||||
RAM_ROLE_ARN=acs:ram::5828544250383902:role/content-secret
|
||||
|
||||
# 阿里云区域(可选,默认为cn-shanghai)
|
||||
ALIBABA_CLOUD_REGION=ap-southeast-1
|
||||
|
||||
# 阿里云端点(可选,默认为green.cn-shanghai.aliyuncs.com)
|
||||
ALIBABA_CLOUD_ENDPOINT=green-cip.ap-southeast-1.aliyuncs.com
|
||||
@ -8,7 +8,9 @@ ErpHost = "http://erpapi.test.fontree.cn:8081"
|
||||
FieeHost = "http://erpapi.test.fontree.cn:8081"
|
||||
FieeApiHost = "https://saas-test.szjixun.cn"
|
||||
AuthRedirectUrl = "http://saas-erp.test.fontree.cn:8081/media_account"
|
||||
AuthCallback = "https://saas-test.szjixun.cn/api/fiee/media/as-oauth2callback"
|
||||
CronOpen = true
|
||||
proxyUrl = "http://taifeng:fontree008@8.220.199.204:1081"
|
||||
[bos]
|
||||
Ak = "ALTAKxrqOQHnAN525Tb2GX4Bhe"
|
||||
Sk = "d2ecaa9d75114d3b9f42b99014198306"
|
||||
|
||||
@ -9,7 +9,7 @@ dubbo:
|
||||
# address: 114.218.158.24:2181
|
||||
consumer:
|
||||
filter: tracing
|
||||
request-timeout: 30s
|
||||
request-timeout: 300s
|
||||
references:
|
||||
OrderClientImpl:
|
||||
protocol: tri
|
||||
@ -47,6 +47,9 @@ dubbo:
|
||||
protocol: tri
|
||||
retries: 0
|
||||
interface: com.fontree.microservices.fiee.SecFiling
|
||||
AyrshareClientImpl:
|
||||
protocol: tri
|
||||
interface: com.fontree.microservices.fiee.ayrshare
|
||||
logger:
|
||||
zap-config:
|
||||
level: error # 日志级别
|
||||
|
||||
20
go.mod
20
go.mod
@ -5,6 +5,7 @@ go 1.23.0
|
||||
toolchain go1.23.10
|
||||
|
||||
replace (
|
||||
github.com/fonchain/utils/security => ../utils/security
|
||||
//github.com/fonchain_enterprise/utils/objstorage => ../../tyfon-新/utils/objstorage
|
||||
github.com/fonchain/utils/voice => ../utils/voice
|
||||
github.com/fonchain_enterprise/utils/aes => ../utils/aes
|
||||
@ -71,7 +72,7 @@ require (
|
||||
github.com/mschoch/smat v0.2.0 // indirect
|
||||
github.com/nacos-group/nacos-sdk-go v1.1.1 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
|
||||
github.com/pelletier/go-toml v1.7.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/prometheus/client_golang v1.12.2 // indirect
|
||||
@ -82,7 +83,7 @@ require (
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b
|
||||
github.com/shirou/gopsutil v3.20.11+incompatible // indirect
|
||||
github.com/uber/jaeger-client-go v2.29.1+incompatible // indirect
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
@ -106,6 +107,7 @@ require (
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/duke-git/lancet/v2 v2.3.8
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0
|
||||
github.com/fonchain/utils/security v0.0.0-00010101000000-000000000000
|
||||
github.com/fonchain/utils/voice v0.0.0-00010101000000-000000000000
|
||||
github.com/fonchain_enterprise/utils/objstorage v0.0.0-00010101000000-000000000000
|
||||
github.com/gin-contrib/pprof v1.4.0
|
||||
@ -128,7 +130,14 @@ require (
|
||||
cloud.google.com/go v0.65.0 // indirect
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 // indirect
|
||||
github.com/alibaba/sentinel-golang v1.0.4 // indirect
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1376 // indirect
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.12 // indirect
|
||||
github.com/alibabacloud-go/debug v1.0.1 // indirect
|
||||
github.com/alibabacloud-go/green-20220302/v2 v2.23.0 // indirect
|
||||
github.com/alibabacloud-go/tea v1.3.13 // indirect
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 // indirect
|
||||
github.com/aliyun/credentials-go v1.4.5 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||
github.com/aws/aws-sdk-go v1.38.20 // indirect
|
||||
github.com/baidubce/bce-sdk-go v0.9.123 // indirect
|
||||
@ -136,6 +145,7 @@ require (
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
@ -153,15 +163,14 @@ require (
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-resty/resty/v2 v2.7.0 // indirect
|
||||
github.com/golang/mock v1.5.0 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
|
||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/vault/sdk v0.3.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
@ -184,6 +193,7 @@ require (
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
github.com/tiendc/go-deepcopy v1.6.0 // indirect
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.6 // indirect
|
||||
github.com/tklauser/numcpus v0.2.2 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
|
||||
130
go.sum
130
go.sum
@ -71,12 +71,59 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/alibaba/sentinel-golang v1.0.4 h1:i0wtMvNVdy7vM4DdzYrlC4r/Mpk1OKUUBurKKkWhEo8=
|
||||
github.com/alibaba/sentinel-golang v1.0.4/go.mod h1:Lag5rIYyJiPOylK8Kku2P+a23gdKMMqzQS7wTnjWEpk=
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 h1:eIf+iGJxdU4U9ypaUfbtOWCsZSbTb8AUHvyPrxu6mAA=
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6/go.mod h1:4EUIoxs/do24zMOGGqYVWgw0s9NtiylnJglOeEB5UJo=
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 h1:zE8vH9C7JiZLNJJQ5OwjU9mSi4T9ef9u3BURT6LCLC8=
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5/go.mod h1:tWnyE9AjF8J8qqLk645oUmVUnFybApTQWklQmi5tY6g=
|
||||
github.com/alibabacloud-go/darabonba-array v0.1.0 h1:vR8s7b1fWAQIjEjWnuF0JiKsCvclSRTfDzZHTYqfufY=
|
||||
github.com/alibabacloud-go/darabonba-array v0.1.0/go.mod h1:BLKxr0brnggqOJPqT09DFJ8g3fsDshapUD3C3aOEFaI=
|
||||
github.com/alibabacloud-go/darabonba-encode-util v0.0.2 h1:1uJGrbsGEVqWcWxrS9MyC2NG0Ax+GpOM5gtupki31XE=
|
||||
github.com/alibabacloud-go/darabonba-encode-util v0.0.2/go.mod h1:JiW9higWHYXm7F4PKuMgEUETNZasrDM6vqVr/Can7H8=
|
||||
github.com/alibabacloud-go/darabonba-map v0.0.2 h1:qvPnGB4+dJbJIxOOfawxzF3hzMnIpjmafa0qOTp6udc=
|
||||
github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+MtEzBunJwQGceGQlvaPGPc=
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.12 h1:e2yCrhtWd6Qcsy4he2OL+jIAU+93Lx9OcLlPRoFLT1w=
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.12/go.mod h1:f2wDpbM7hK9SvLIH09zSKVU1TsyemUNOqErMscMMl7c=
|
||||
github.com/alibabacloud-go/darabonba-signature-util v0.0.7 h1:UzCnKvsjPFzApvODDNEYqBHMFt1w98wC7FOo0InLyxg=
|
||||
github.com/alibabacloud-go/darabonba-signature-util v0.0.7/go.mod h1:oUzCYV2fcCH797xKdL6BDH8ADIHlzrtKVjeRtunBNTQ=
|
||||
github.com/alibabacloud-go/darabonba-string v1.0.2 h1:E714wms5ibdzCqGeYJ9JCFywE5nDyvIXIIQbZVFkkqo=
|
||||
github.com/alibabacloud-go/darabonba-string v1.0.2/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA=
|
||||
github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY=
|
||||
github.com/alibabacloud-go/debug v1.0.0/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc=
|
||||
github.com/alibabacloud-go/debug v1.0.1 h1:MsW9SmUtbb1Fnt3ieC6NNZi6aEwrXfDksD4QA6GSbPg=
|
||||
github.com/alibabacloud-go/debug v1.0.1/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc=
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q=
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
|
||||
github.com/alibabacloud-go/green-20220302/v2 v2.23.0 h1:t2WsqrKt/ztPq4X2Orh3cvG5PsFdes/IQDkxZmB/f5k=
|
||||
github.com/alibabacloud-go/green-20220302/v2 v2.23.0/go.mod h1:iZWuUEakwGct+e0NDnTBzOMaoblCUXH8Lf7S5v4kGKg=
|
||||
github.com/alibabacloud-go/openapi-util v0.1.0 h1:0z75cIULkDrdEhkLWgi9tnLe+KhAFE/r5Pb3312/eAY=
|
||||
github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
|
||||
github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg=
|
||||
github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
|
||||
github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
|
||||
github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
|
||||
github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
|
||||
github.com/alibabacloud-go/tea v1.1.20/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
|
||||
github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk=
|
||||
github.com/alibabacloud-go/tea v1.3.12/go.mod h1:A560v/JTQ1n5zklt2BEpurJzZTI8TUT+Psg2drWlxRg=
|
||||
github.com/alibabacloud-go/tea v1.3.13 h1:WhGy6LIXaMbBM6VBYcsDCz6K/TPsT1Ri2hPmmZffZ94=
|
||||
github.com/alibabacloud-go/tea v1.3.13/go.mod h1:A560v/JTQ1n5zklt2BEpurJzZTI8TUT+Psg2drWlxRg=
|
||||
github.com/alibabacloud-go/tea-utils v1.3.1 h1:iWQeRzRheqCMuiF3+XkfybB3kTgUXkXX+JMrqfLeB2I=
|
||||
github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.5/go.mod h1:dL6vbUT35E4F4bFTHL845eUloqaerYBYPsdWR2/jhe4=
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 h1:WDx5qW3Xa5ZgJ1c8NfqJkF6w+AU5wB8835UdhPr6Ax0=
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.7/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1376 h1:lExo7heZgdFn5AbaNJEllbA0KSJ/Z8T7MphvMREJOOo=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1376/go.mod h1:9CMdKNL3ynIGPpfTcdwTvIm8SGuAZYYC4jFVSSvE1YQ=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 h1:qagvUyrgOnBIlVRQWOyCZGVKUIYbMBdGdJ104vBpRFU=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.107/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.4+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible h1:KXeJoM1wo9I/6xPTyt6qCxoSZnmASiAjlrr0dyTUKt8=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
|
||||
github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0=
|
||||
github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM=
|
||||
github.com/aliyun/credentials-go v1.4.5 h1:O76WYKgdy1oQYYiJkERjlA2dxGuvLRrzuO2ScrtGWSk=
|
||||
github.com/aliyun/credentials-go v1.4.5/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
|
||||
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
||||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
@ -144,6 +191,8 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
|
||||
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
@ -394,8 +443,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@ -512,8 +561,9 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
@ -678,8 +728,9 @@ github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
|
||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
@ -805,6 +856,7 @@ github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||
github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfItdAd1r3cck=
|
||||
github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
@ -839,6 +891,7 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@ -865,6 +918,9 @@ github.com/tevid/gohamcrest v1.1.1 h1:ou+xSqlIw1xfGTg1uq1nif/htZ2S3EzRqLm2BP+tYU
|
||||
github.com/tevid/gohamcrest v1.1.1/go.mod h1:3UvtWlqm8j5JbwYZh80D/PVBt0mJ1eJiYgZMibh0H/k=
|
||||
github.com/tiendc/go-deepcopy v1.6.0 h1:0UtfV/imoCwlLxVsyfUd4hNHnB3drXsfle+wzSCA5Wo=
|
||||
github.com/tiendc/go-deepcopy v1.6.0/go.mod h1:toXoeQoUqXOOS/X4sKuiAoSk6elIdqc0pN7MTgOOo2I=
|
||||
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
|
||||
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
|
||||
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
|
||||
github.com/tklauser/go-sysconf v0.3.6 h1:oc1sJWvKkmvIxhDHeKWvZS4f6AW+YcoguSfRF2/Hmo4=
|
||||
github.com/tklauser/go-sysconf v0.3.6/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
|
||||
github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA=
|
||||
@ -882,8 +938,9 @@ github.com/u2takey/ffmpeg-go v0.5.0 h1:r7d86XuL7uLWJ5mzSeQ03uvjfIhiJYvsRAJFCW4uk
|
||||
github.com/u2takey/ffmpeg-go v0.5.0/go.mod h1:ruZWkvC1FEiUNjmROowOAps3ZcWxEiOpFoHCvk97kGc=
|
||||
github.com/u2takey/go-utils v0.3.1 h1:TaQTgmEZZeDHQFYfd+AdUT1cT4QJgJn/XVPELhHw4ys=
|
||||
github.com/u2takey/go-utils v0.3.1/go.mod h1:6e+v5vEZ/6gu12w/DC2ixZdZtCrNokVxD0JUklcqdCs=
|
||||
github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4=
|
||||
github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
@ -911,6 +968,7 @@ github.com/xuri/nfp v0.0.1 h1:MDamSGatIvp8uOmDP8FnmjuQpu90NzdJxo7242ANR9Q=
|
||||
github.com/xuri/nfp v0.0.1/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
@ -989,11 +1047,21 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
||||
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@ -1037,6 +1105,10 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -1075,6 +1147,7 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
@ -1088,7 +1161,16 @@ golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -1111,6 +1193,10 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -1155,6 +1241,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -1191,11 +1278,28 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -1206,6 +1310,11 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -1261,6 +1370,7 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
@ -1274,6 +1384,9 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -1406,7 +1519,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
@ -1429,6 +1542,7 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
package common
|
||||
|
||||
import "fonchain-fiee/pkg/utils"
|
||||
import (
|
||||
"fonchain-fiee/pkg/utils"
|
||||
)
|
||||
|
||||
func Init() {
|
||||
_ = utils.CreateDirPath("./runtime")
|
||||
utils.CopyFile("./data/policy.html", "./runtime")
|
||||
utils.CopyFile("./data/service.html", "./runtime")
|
||||
utils.CopyFile("../data/policy.html", "./runtime")
|
||||
utils.CopyFile("../data/service.html", "./runtime")
|
||||
//pkgSecurity.Init()
|
||||
//utils.CopyFile("./data/policy.html", "./runtime")
|
||||
//utils.CopyFile("./data/service.html", "./runtime")
|
||||
//utils.CopyFile("../data/policy.html", "./runtime")
|
||||
//utils.CopyFile("../data/service.html", "./runtime")
|
||||
}
|
||||
|
||||
32
pkg/common/qwen/chat.go
Normal file
32
pkg/common/qwen/chat.go
Normal file
@ -0,0 +1,32 @@
|
||||
package qwen
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
modelQwen "fonchain-fiee/pkg/model/qwen"
|
||||
"fonchain-fiee/pkg/utils"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func Chat(req modelQwen.ChatRequest) (resp *modelQwen.ChatResponse, err error) {
|
||||
jsonData, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
zap.L().Error("GenerateTextImage Marshal failed", zap.Error(err))
|
||||
return nil, errors.New("序列化请求失败")
|
||||
}
|
||||
body, err := utils.PostBytes("https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions", map[string]interface{}{
|
||||
"Authorization": "Bearer " + modelQwen.DashscopeAPIKey,
|
||||
"Content-Type": "application/json",
|
||||
}, jsonData)
|
||||
if err != nil {
|
||||
zap.L().Error("Chat Post err", zap.Error(err))
|
||||
return nil, errors.New("对话异常")
|
||||
}
|
||||
var result modelQwen.ChatResponse
|
||||
if err = json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("解析响应失败: %v", "")
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
@ -2,10 +2,13 @@ package qwen
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
modelQwen "fonchain-fiee/pkg/model/qwen"
|
||||
"fonchain-fiee/pkg/utils"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// GenerateTextImage 调用通义千问文生图API
|
||||
@ -19,12 +22,14 @@ func GenerateTextImage(prompt string, size string) (resp *modelQwen.QwenImageRes
|
||||
Watermark: false,
|
||||
PromptExtend: true,
|
||||
Size: size,
|
||||
N: 1,
|
||||
N: 4,
|
||||
Seed: time.Now().Unix(),
|
||||
},
|
||||
}
|
||||
jsonData, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("序列化请求失败: %v", err)
|
||||
zap.L().Error("GenerateTextImage Marshal failed", zap.Error(err))
|
||||
return nil, errors.New("序列化请求失败")
|
||||
}
|
||||
body, err := utils.PostBytes(modelQwen.DashscopeText2ImageURL, map[string]interface{}{
|
||||
"Authorization": "Bearer " + modelQwen.DashscopeAPIKey,
|
||||
@ -32,14 +37,15 @@ func GenerateTextImage(prompt string, size string) (resp *modelQwen.QwenImageRes
|
||||
"X-DashScope-Async": "enable",
|
||||
}, jsonData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("请求失败: %v", err)
|
||||
zap.L().Error("GenerateTextImage Post failed", zap.Error(err))
|
||||
return nil, errors.New("请求生图失败")
|
||||
}
|
||||
var result modelQwen.QwenImageResponse
|
||||
if err = json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("解析响应失败: %v", err)
|
||||
return nil, fmt.Errorf("解析响应失败: %v", "")
|
||||
}
|
||||
if result.Code != "" {
|
||||
return nil, fmt.Errorf("生成失败: %s", result.Message)
|
||||
return nil, fmt.Errorf("生成失败: %s", "")
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
@ -58,12 +64,13 @@ func GenerateEditImage(prompt string, images []string, size string) (*modelQwen.
|
||||
Size: size,
|
||||
N: 4,
|
||||
Watermark: false,
|
||||
Seed: 0,
|
||||
Seed: time.Now().Unix(),
|
||||
},
|
||||
}
|
||||
jsonData, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("序列化请求失败: %v", err)
|
||||
zap.L().Error("GenerateEditImage Marshal failed", zap.Error(err))
|
||||
return nil, errors.New("序列化请求失败")
|
||||
}
|
||||
body, err := utils.PostBytes(modelQwen.DashscopeEditImageURL, map[string]interface{}{
|
||||
"Authorization": "Bearer " + modelQwen.DashscopeAPIKey,
|
||||
@ -71,14 +78,16 @@ func GenerateEditImage(prompt string, images []string, size string) (*modelQwen.
|
||||
"X-DashScope-Async": "enable",
|
||||
}, jsonData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("请求失败: %v", err)
|
||||
zap.L().Error("GenerateEditImage PostBytes failed", zap.Error(err))
|
||||
return nil, errors.New("请求异常")
|
||||
}
|
||||
var result modelQwen.QwenImageResponse
|
||||
if err = json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("解析响应失败: %v", err)
|
||||
zap.L().Error("GenerateEditImage PostBytes failed", zap.Error(err))
|
||||
return nil, errors.New("解析响应失败")
|
||||
}
|
||||
if result.Code != "" {
|
||||
return nil, fmt.Errorf("生成失败: %s", result.Message)
|
||||
return nil, fmt.Errorf("生成失败: %s", "")
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
@ -90,20 +99,22 @@ func ImgTaskResult(taskID string) (*modelQwen.QwenImageResponse, error) {
|
||||
"Content-Type": "application/json",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("请求失败: %v", err)
|
||||
zap.L().Error("ImgTaskResult GetBytes failed", zap.Error(err))
|
||||
return nil, errors.New("请求失败")
|
||||
}
|
||||
var info modelQwen.QwenImageResponse
|
||||
if err = json.Unmarshal(body, &info); err != nil {
|
||||
return nil, fmt.Errorf("解析响应失败: %v", err)
|
||||
zap.L().Error("ImgTaskResult Unmarshal failed", zap.Error(err))
|
||||
return nil, errors.New("解析响应失败")
|
||||
}
|
||||
if info.Code != "" {
|
||||
return nil, fmt.Errorf("生成失败: %s", info.Message)
|
||||
return nil, fmt.Errorf("生成失败: %s", "")
|
||||
}
|
||||
if info.Output.TaskStatus == "FAILED" {
|
||||
return nil, fmt.Errorf("生成失败")
|
||||
}
|
||||
|
||||
if len(info.Output.Results) > 0 {
|
||||
zap.L().Info("ImgTaskResult GetBytes success", zap.String("taskID", taskID), zap.Any("results", info))
|
||||
return &info, nil
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
@ -2,6 +2,8 @@ package cron
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"fonchain-fiee/api/cast"
|
||||
"fonchain-fiee/pkg/cache"
|
||||
@ -20,10 +22,15 @@ func InitTasks() error {
|
||||
cm := GetCronManager()
|
||||
err := cm.AddTask("refreshWorkApprovalStatus", "0 */1 * * * *", RefreshWorkApprovalStatusTask)
|
||||
err = cm.AddTask("artistAutoConfirm", "0 */1 * * * *", ArtistAutoConfirmTask)
|
||||
err = cm.AddTask("refreshPublishStatus", "0 */1 * * * *", RefreshPublishStatusTask)
|
||||
if err != nil {
|
||||
log.Printf("添加测试任务失败: %v", err)
|
||||
log.Printf("添加定时任务失败: %v", err)
|
||||
}
|
||||
cm.Start()
|
||||
|
||||
// 启动队列消费者
|
||||
go WorkPublishQueueConsumer()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -63,3 +70,76 @@ func ArtistAutoConfirmTask() {
|
||||
serverCast.ProcessTask(context.Background(), workUuid)
|
||||
}
|
||||
}
|
||||
|
||||
func RefreshPublishStatusTask() {
|
||||
// 加上锁 万一上一批没有同步完
|
||||
lockKey := "refresh_publish_status:lock"
|
||||
reply := cache.RedisClient.SetNX(lockKey, "1", 5*time.Minute)
|
||||
if !reply.Val() {
|
||||
zap.L().Warn("任务正在被其他实例处理")
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
cache.RedisClient.Del(lockKey)
|
||||
}()
|
||||
err := serverCast.RefreshPublish()
|
||||
if err != nil {
|
||||
zap.L().Error("刷新发布状态失败", zap.Error(err))
|
||||
return
|
||||
}
|
||||
zap.L().Info("刷新发布状态成功")
|
||||
}
|
||||
|
||||
// WorkPublishQueueConsumer 监听work:publish:queue队列的消费者
|
||||
func WorkPublishQueueConsumer() {
|
||||
zap.L().Info("开始监听work:publish:queue队列")
|
||||
for {
|
||||
result, err := cache.RedisClient.BRPop(0*time.Second, modelCast.WorkPublishQueueKey).Result()
|
||||
if err != nil {
|
||||
zap.L().Error("监听work:publish:queue队列失败", zap.Error(err))
|
||||
time.Sleep(5 * time.Second) // 出错后等待5秒再重试
|
||||
continue
|
||||
}
|
||||
|
||||
if len(result) < 2 {
|
||||
zap.L().Warn("队列返回数据格式异常", zap.Any("result", result))
|
||||
continue
|
||||
}
|
||||
|
||||
workData := result[1] // BRPOP返回[key, value],value在第二个元素
|
||||
zap.L().Info("从work:publish:queue队列收到数据", zap.String("data", workData))
|
||||
|
||||
// 处理队列数据
|
||||
if err = processWorkPublishQueueData(workData); err != nil {
|
||||
zap.L().Error("处理work:publish:queue队列数据失败", zap.Error(err), zap.String("data", workData))
|
||||
continue
|
||||
}
|
||||
zap.L().Info("成功处理work:publish:queue队列数据", zap.String("data", workData))
|
||||
}
|
||||
}
|
||||
|
||||
// processWorkPublishQueueData 处理从work:publish:queue队列中取出的数据
|
||||
func processWorkPublishQueueData(data string) error {
|
||||
// 延时1秒消费
|
||||
time.Sleep(time.Second * 1)
|
||||
var workData map[string]string
|
||||
_ = json.Unmarshal([]byte(data), &workData)
|
||||
workUuid := workData["workUuid"]
|
||||
if workUuid == "" {
|
||||
zap.L().Error("队列数据为空", zap.String("raw_data", data))
|
||||
return errors.New("队列数据为空")
|
||||
}
|
||||
zap.L().Info("处理发布工作队列数据", zap.String("work_uuid", workUuid))
|
||||
// 调用发布工作逻辑
|
||||
err := serverCast.PublishWork(context.Background(), &cast.PublishReq{
|
||||
WorkUuids: []string{workUuid},
|
||||
})
|
||||
if err != nil {
|
||||
zap.L().Error("发布工作失败",
|
||||
zap.String("work_uuid", workUuid),
|
||||
zap.Error(err))
|
||||
return err
|
||||
}
|
||||
zap.L().Info("发布工作成功", zap.String("work_uuid", workUuid))
|
||||
return nil
|
||||
}
|
||||
|
||||
1
pkg/model/cast/ayrshare.go
Normal file
1
pkg/model/cast/ayrshare.go
Normal file
@ -0,0 +1 @@
|
||||
package cast
|
||||
@ -2,9 +2,31 @@ package cast
|
||||
|
||||
type BalanceTypeEnum int32
|
||||
|
||||
type SyncAsProfileReq struct {
|
||||
ID uint64 `json:"id"`
|
||||
}
|
||||
|
||||
// 定义枚举值
|
||||
const (
|
||||
BalanceTypeAccountValue BalanceTypeEnum = 1
|
||||
BalanceTypeImageValue BalanceTypeEnum = 2
|
||||
BalanceTypeVideoValue BalanceTypeEnum = 3
|
||||
BalanceTypeDataValue BalanceTypeEnum = 4
|
||||
)
|
||||
|
||||
var PlatformNameKv = map[uint32]string{
|
||||
1: "tiktok",
|
||||
3: "instagram",
|
||||
4: "DM",
|
||||
}
|
||||
|
||||
var NamePlatformIDKv = map[string]uint32{
|
||||
"tiktok": 1,
|
||||
"instagram": 3,
|
||||
"DM": 4,
|
||||
}
|
||||
var PlatformIDStrKv = map[string]uint8{
|
||||
"TIKTOK": 1,
|
||||
"INS": 2,
|
||||
"DM": 4,
|
||||
}
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
package cast
|
||||
|
||||
type OAuthPlatformReq struct {
|
||||
MediaAccountUuid string `json:"mediaAccountUuid" form:"mediaAccountUuid" binding:"required"`
|
||||
PlatformID int `json:"platformID" form:"platformID" binding:"required"`
|
||||
MediaAccountUuid string `json:"mediaAccountUuid" form:"mediaAccountUuid"`
|
||||
PlatformID int `json:"platformID" form:"platformID"`
|
||||
ArtistUuid string `json:"artistUuid" form:"artistUuid"`
|
||||
}
|
||||
|
||||
type OAuthPlatformResp struct {
|
||||
|
||||
@ -13,6 +13,7 @@ const (
|
||||
const (
|
||||
AutoConfirmQueueKey = "auto_confirm:queue"
|
||||
AutoConfirmLockKey = "auto_confirm:lock:%s"
|
||||
WorkPublishQueueKey = "work:publish:queue"
|
||||
)
|
||||
|
||||
var WorkCategoryMM = map[int]string{
|
||||
@ -43,3 +44,11 @@ var WorkStatusMM = map[int]string{
|
||||
8: "未知",
|
||||
9: "验收确认",
|
||||
}
|
||||
|
||||
type DMPost struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Url string `json:"url"`
|
||||
Published bool `json:"published"`
|
||||
Error interface{}
|
||||
}
|
||||
|
||||
43
pkg/model/qwen/chat.go
Normal file
43
pkg/model/qwen/chat.go
Normal file
@ -0,0 +1,43 @@
|
||||
package qwen
|
||||
|
||||
type ChatRequest struct {
|
||||
Model string `json:"model"`
|
||||
Messages []Message `json:"messages"`
|
||||
Seed int64 `json:"seed,omitempty"`
|
||||
EnableSearch bool `json:"enable_search,omitempty"`
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
Role string `json:"role"`
|
||||
Content []Content `json:"content"`
|
||||
}
|
||||
|
||||
type Content struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text,omitempty"` // 只有 type=text 时有
|
||||
ImageURL *ImageURL `json:"image_url,omitempty"` // 只有 type=image_url 时有
|
||||
}
|
||||
|
||||
type ImageURL struct {
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type ChatResponse struct {
|
||||
Choices []Choice `json:"choices"`
|
||||
}
|
||||
|
||||
type Choice struct {
|
||||
Message struct {
|
||||
Content string `json:"content"`
|
||||
ReasoningContent string `json:"reasoning_content"`
|
||||
Role string `json:"role"`
|
||||
} `json:"message"`
|
||||
FinishReason string `json:"finish_reason"`
|
||||
}
|
||||
|
||||
type MoreTextReq struct {
|
||||
TitlePrompt string `json:"titlePrompt"`
|
||||
ContentPrompt string `json:"contentPrompt"`
|
||||
ImagePrompt string `json:"imagePrompt"`
|
||||
Images []string `json:"images"`
|
||||
}
|
||||
@ -11,6 +11,7 @@ type QwenImageRequest struct {
|
||||
Model string `json:"model"`
|
||||
Input QwenImageInput `json:"input"`
|
||||
Parameters QwenImageParameters `json:"parameters"`
|
||||
Seed int64 `json:"seed"`
|
||||
}
|
||||
|
||||
type QwenImageInput struct {
|
||||
@ -28,7 +29,7 @@ type QwenImageParameters struct {
|
||||
N int `json:"n,omitempty"`
|
||||
PromptExtend bool `json:"prompt_extend,omitempty"`
|
||||
Watermark bool `json:"watermark"` //水印
|
||||
Seed int `json:"seed,omitempty"`
|
||||
Seed int64 `json:"seed,omitempty"`
|
||||
}
|
||||
|
||||
// QwenImageResponse 通义千问文生图响应
|
||||
@ -71,7 +72,7 @@ type QwenEditImageParameters struct {
|
||||
Size string `json:"size"`
|
||||
N int `json:"n"`
|
||||
Watermark bool `json:"watermark"`
|
||||
Seed int `json:"seed"`
|
||||
Seed int64 `json:"seed"`
|
||||
}
|
||||
|
||||
type QwenEditImageResponse struct {
|
||||
|
||||
@ -22,10 +22,12 @@ func MediaRouter(r *gin.RouterGroup) {
|
||||
media.POST("oauth-account", serviceCast.OAuthAccount)
|
||||
media.POST("refresh-token", serviceCast.RefreshToken)
|
||||
media.POST("artist-info", serviceCast.ArtistInfo)
|
||||
media.POST("sync-as-profile", serviceCast.SyncAsProfile)
|
||||
}
|
||||
mediaNoLogin := r.Group("media")
|
||||
{
|
||||
mediaNoLogin.GET("oauth2callback", serviceCast.OAuth2Callback)
|
||||
mediaNoLogin.GET("as-oauth2callback", serviceCast.AsOAuth2Callback)
|
||||
mediaNoLogin.Any("test", serviceCast.Test)
|
||||
//mediaNoLogin.GET("dmoauth2callback", serviceCast.DMOAuth2Callback)
|
||||
}
|
||||
@ -43,7 +45,7 @@ func MediaRouter(r *gin.RouterGroup) {
|
||||
work.POST("delete", serviceCast.DelWork)
|
||||
work.POST("remind", serviceCast.Remind)
|
||||
work.POST("publish-info", serviceCast.PublishInfo)
|
||||
|
||||
work.POST("import-batch", serviceCast.ImportWorkBatch)
|
||||
}
|
||||
|
||||
script := auth.Group("script")
|
||||
@ -72,9 +74,15 @@ func MediaRouter(r *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
//AI 生图
|
||||
ai := auth.Group("ai")
|
||||
aiNoAuth := noAuth.Group("ai")
|
||||
{
|
||||
ai.POST("image-generate", serviceAI.AIImageGenerate)
|
||||
aiNoAuth.POST("image-generate", serviceAI.AIImageGenerate)
|
||||
aiNoAuth.POST("text-generate", serviceAI.AIChat)
|
||||
}
|
||||
aiAuth := auth.Group("ai")
|
||||
{
|
||||
aiAuth.POST("one-text", serviceAI.OneText)
|
||||
aiAuth.POST("more-text", serviceAI.MoreText)
|
||||
}
|
||||
|
||||
social := noAuth.Group("social")
|
||||
|
||||
@ -197,6 +197,14 @@ func NewRouter() *gin.Engine {
|
||||
importRoute.POST("data/publish3", imports.ImportPublishV3)
|
||||
importRoute.POST("data/publish4", imports.ImportPublishV4)
|
||||
importRoute.POST("data/confirm", imports.WorkConfirm)
|
||||
importRoute.POST("image-content/import", imports.ImageContentImport) // AI生成内容并导入系统
|
||||
importRoute.GET("image-content/result", imports.ImageContentGetResult) // 获取导入结果
|
||||
importRoute.GET("image-content/result/excel", imports.ImageContentGetResultExcel) // 导出错误的excel
|
||||
|
||||
importRoute.GET("generate/photo/test", imports.Test)
|
||||
importRoute.GET("generate/photo/test1", imports.Test1)
|
||||
importRoute.GET("generate/photo/test2", imports.Test2)
|
||||
|
||||
}
|
||||
//静态文件
|
||||
r.StaticFS("/api/fiee/static", http.Dir("./runtime"))
|
||||
|
||||
@ -73,6 +73,12 @@ func TaskBenchRouter(r *gin.RouterGroup) {
|
||||
|
||||
// 查询艺人待上传列表并导出Excel
|
||||
taskBenchRoute.POST("pending-upload-list-download", taskbench.GetArtistUploadStatsListDownload)
|
||||
|
||||
// 添加隐藏任务指派人
|
||||
taskBenchRoute.POST("hide", taskbench.AddHiddenTaskAssignee)
|
||||
|
||||
// 查询待指派数据
|
||||
taskBenchRoute.POST("pending-data-list", taskbench.GetPendingAssign)
|
||||
}
|
||||
|
||||
// 员工任务相关路由(需要App登录验证)
|
||||
|
||||
27
pkg/security/init.go
Normal file
27
pkg/security/init.go
Normal file
@ -0,0 +1,27 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"github.com/fonchain/utils/security"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var ImageScanner *security.ImageScanner
|
||||
|
||||
func Init() {
|
||||
config, err := security.LoadConfigFromFile("../conf/alibabacloud.env")
|
||||
if err != nil {
|
||||
zap.L().Error("load config fail", zap.Error(err))
|
||||
panic(err)
|
||||
//err = errors.New("加载黄反配置失败")
|
||||
//return false, err
|
||||
}
|
||||
if err = config.GetSTSToken(); err != nil {
|
||||
zap.L().Error("load sts token failed", zap.Error(err))
|
||||
panic(err)
|
||||
|
||||
}
|
||||
ImageScanner, err = security.NewImageScanner(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
28
pkg/service/ai/chat.go
Normal file
28
pkg/service/ai/chat.go
Normal file
@ -0,0 +1,28 @@
|
||||
package ai
|
||||
|
||||
import (
|
||||
"fonchain-fiee/pkg/common/qwen"
|
||||
modelQwen "fonchain-fiee/pkg/model/qwen"
|
||||
"fonchain-fiee/pkg/service"
|
||||
"time"
|
||||
|
||||
"errors"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func AIChat(ctx *gin.Context) {
|
||||
var req modelQwen.ChatRequest
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
service.Error(ctx, errors.New("参数错误 "))
|
||||
return
|
||||
}
|
||||
req.Seed = time.Now().Unix()
|
||||
resp, err := qwen.Chat(req)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
return
|
||||
}
|
||||
@ -8,20 +8,22 @@ import (
|
||||
"fonchain-fiee/pkg/model/login"
|
||||
modelQwen "fonchain-fiee/pkg/model/qwen"
|
||||
"fonchain-fiee/pkg/service"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// ImageGenerateRequest 文生图请求参数
|
||||
type ImageGenerateRequest struct {
|
||||
Prompt string `json:"prompt" binding:"required"`
|
||||
Size string `json:"size,omitempty"`
|
||||
NegativePrompt string `json:"negative_prompt,omitempty"`
|
||||
Watermark bool `json:"watermark,omitempty"`
|
||||
PromptExtend bool `json:"prompt_extend,omitempty"`
|
||||
Images []string `json:"images" binding:"required"`
|
||||
Prompt string `json:"prompt"`
|
||||
Size string `json:"size"`
|
||||
NegativePrompt string `json:"negative_prompt"`
|
||||
Watermark bool `json:"watermark"`
|
||||
PromptExtend bool `json:"prompt_extend"`
|
||||
Images []string `json:"images"`
|
||||
}
|
||||
|
||||
// ImageGenerateResponse 文生图响应数据
|
||||
@ -39,11 +41,29 @@ type ImageGenerateResponse struct {
|
||||
func AIImageGenerate(ctx *gin.Context) {
|
||||
var req ImageGenerateRequest
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
service.Error(ctx, errors.New("参数错误: "+err.Error()))
|
||||
service.Error(ctx, errors.New("参数错误: "))
|
||||
return
|
||||
}
|
||||
//检测之前是否有图片生成
|
||||
loginUserInfo := login.GetUserInfoFromC(ctx)
|
||||
//loginUserInfo := login.GetUserInfoFromC(ctx)
|
||||
loginUserInfo := login.Info{
|
||||
ID: 1,
|
||||
Status: 0,
|
||||
Name: "",
|
||||
Sex: "",
|
||||
Nationality: "",
|
||||
DocumentType: 0,
|
||||
CertificatePicture: "",
|
||||
Validity: "",
|
||||
PlaceOfResidence: "",
|
||||
GroupPhoto: "",
|
||||
Attachment: "",
|
||||
SubNum: "",
|
||||
NotPassRemarks: "",
|
||||
Domain: "",
|
||||
TelNum: "",
|
||||
SubscriberNumber: "",
|
||||
}
|
||||
if req.Prompt == "" {
|
||||
service.Error(ctx, errors.New("提示词不能为空"))
|
||||
return
|
||||
@ -99,3 +119,368 @@ func AIImageGenerate(ctx *gin.Context) {
|
||||
cache.RedisClient.Del(lockKey)
|
||||
service.Success(ctx, result)
|
||||
}
|
||||
|
||||
func OneText(ctx *gin.Context) {
|
||||
var req ImageGenerateRequest
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
service.Error(ctx, errors.New("参数错误: "))
|
||||
return
|
||||
}
|
||||
type ResultAll struct {
|
||||
Result []struct {
|
||||
Url string `json:"url"`
|
||||
OrigPrompt string `json:"orig_prompt"`
|
||||
ActualPrompt string `json:"actual_prompt"`
|
||||
} `json:"result"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Prompt string `json:"prompt"`
|
||||
}
|
||||
var resultAll ResultAll
|
||||
if req.Prompt == "" {
|
||||
service.Error(ctx, errors.New("提示词不能为空"))
|
||||
return
|
||||
}
|
||||
if len(req.Images) > 3 {
|
||||
service.Error(ctx, errors.New("最多只能上传3张图片"))
|
||||
return
|
||||
}
|
||||
loginUserInfo := login.GetUserInfoFromC(ctx)
|
||||
if req.Size == "" {
|
||||
req.Size = "1024*1024"
|
||||
}
|
||||
var lockKey, taskID, oldVal string
|
||||
if len(req.Images) == 0 {
|
||||
lockKey = "generate:text_image:" + fmt.Sprint(loginUserInfo.ID)
|
||||
} else {
|
||||
lockKey = "generate:edit_image:" + fmt.Sprint(loginUserInfo.ID)
|
||||
}
|
||||
reply := cache.RedisClient.SetNX(lockKey, time.Now().Format("2006-01-02 15:04:05"), time.Minute*60)
|
||||
if !reply.Val() {
|
||||
oldVal = cache.RedisClient.Get(lockKey).String()
|
||||
if len(oldVal) > 20 && strings.Index(oldVal, "_") != -1 {
|
||||
taskID = oldVal[strings.LastIndex(oldVal, "_")+1:]
|
||||
}
|
||||
} else {
|
||||
defer cache.RedisClient.Del(lockKey)
|
||||
}
|
||||
var resultTask, result *modelQwen.QwenImageResponse
|
||||
var err error
|
||||
if taskID == "" {
|
||||
// 先进行聊天获取上下文
|
||||
chatReq, err1 := ChatReqGet(req)
|
||||
if err1 != nil {
|
||||
service.Error(ctx, err1)
|
||||
return
|
||||
}
|
||||
chatResp, err2 := qwen.Chat(*chatReq)
|
||||
if err2 != nil {
|
||||
service.Error(ctx, err2)
|
||||
return
|
||||
}
|
||||
if len(chatResp.Choices) == 0 {
|
||||
service.Error(ctx, errors.New("聊天返回结果为空"))
|
||||
return
|
||||
}
|
||||
req.Prompt = chatResp.Choices[0].Message.Content
|
||||
resultAll.Prompt = req.Prompt
|
||||
if len(req.Images) == 0 {
|
||||
resultTask, err = qwen.GenerateTextImage(req.Prompt, req.Size)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
taskID = resultTask.Output.TaskID
|
||||
cache.RedisClient.Set(lockKey, time.Now().Format("2006-01-02 15:04:05")+"_"+taskID, time.Minute*5)
|
||||
} else {
|
||||
resultTask, err = qwen.GenerateEditImage(req.Prompt, req.Images, req.Size)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
if resultTask.Code != "" {
|
||||
service.Error(ctx, errors.New("文生图失败: "+resultTask.Message))
|
||||
return
|
||||
}
|
||||
taskID = resultTask.Output.TaskID
|
||||
cache.RedisClient.Set(lockKey, time.Now().Format("2006-01-02 15:04:05")+"_"+taskID, time.Minute*5)
|
||||
}
|
||||
}
|
||||
result, err = qwen.ImgTaskResult(taskID)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
cache.RedisClient.Del(lockKey)
|
||||
if len(result.Output.Results) == 0 {
|
||||
service.Error(ctx, errors.New("图片生成失败"))
|
||||
return
|
||||
}
|
||||
resultAll.Title, resultAll.Content = extractTitleAndContent(req.Prompt)
|
||||
for _, v := range result.Output.Results {
|
||||
resultAll.Result = append(resultAll.Result, struct {
|
||||
Url string `json:"url"`
|
||||
OrigPrompt string `json:"orig_prompt"`
|
||||
ActualPrompt string `json:"actual_prompt"`
|
||||
}{
|
||||
Url: v.URL,
|
||||
OrigPrompt: v.OrigPrompt,
|
||||
ActualPrompt: v.ActualPrompt,
|
||||
})
|
||||
}
|
||||
service.Success(ctx, resultAll)
|
||||
}
|
||||
|
||||
func MoreText(ctx *gin.Context) {
|
||||
var req modelQwen.MoreTextReq
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
service.Error(ctx, errors.New("参数错误 "))
|
||||
return
|
||||
}
|
||||
|
||||
type ResultAll struct {
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Result []struct {
|
||||
Url string `json:"url"`
|
||||
OrigPrompt string `json:"orig_prompt"`
|
||||
ActualPrompt string `json:"actual_prompt"`
|
||||
} `json:"result"`
|
||||
}
|
||||
|
||||
var resultAll ResultAll
|
||||
|
||||
// 三个协程:两个去请求聊天,一个去生成图片
|
||||
type chatResult struct {
|
||||
title string
|
||||
content string
|
||||
err error
|
||||
}
|
||||
|
||||
type imageResult struct {
|
||||
result *modelQwen.QwenImageResponse
|
||||
err error
|
||||
}
|
||||
|
||||
// 协程1:生成标题(标题和内容加附件图片都请求聊天生成文字)
|
||||
titleChan := make(chan chatResult, 1)
|
||||
go func() {
|
||||
chatReq, err := buildChatRequest(req.TitlePrompt, req.Images)
|
||||
if err != nil {
|
||||
titleChan <- chatResult{err: err}
|
||||
return
|
||||
}
|
||||
chatResp, err := qwen.Chat(*chatReq)
|
||||
if err != nil {
|
||||
titleChan <- chatResult{err: err}
|
||||
return
|
||||
}
|
||||
if len(chatResp.Choices) == 0 {
|
||||
titleChan <- chatResult{err: errors.New("标题聊天返回结果为空")}
|
||||
return
|
||||
}
|
||||
titleChan <- chatResult{title: chatResp.Choices[0].Message.Content}
|
||||
}()
|
||||
|
||||
// 协程2:生成内容(标题和内容加附件图片都请求聊天生成文字)
|
||||
contentChan := make(chan chatResult, 1)
|
||||
go func() {
|
||||
chatReq, err := buildChatRequest(req.ContentPrompt, req.Images)
|
||||
if err != nil {
|
||||
contentChan <- chatResult{err: err}
|
||||
return
|
||||
}
|
||||
chatResp, err := qwen.Chat(*chatReq)
|
||||
if err != nil {
|
||||
contentChan <- chatResult{err: err}
|
||||
return
|
||||
}
|
||||
if len(chatResp.Choices) == 0 {
|
||||
contentChan <- chatResult{err: errors.New("内容聊天返回结果为空")}
|
||||
return
|
||||
}
|
||||
contentChan <- chatResult{content: chatResp.Choices[0].Message.Content}
|
||||
}()
|
||||
|
||||
// 协程3:生成图片(图片要求加附件去生成图片)
|
||||
imageChan := make(chan imageResult, 1)
|
||||
go func() {
|
||||
// 先请求聊天获取图片提示词(图片要求加附件去生成图片)
|
||||
chatReq, err := buildChatRequest(req.ImagePrompt, req.Images)
|
||||
if err != nil {
|
||||
imageChan <- imageResult{err: err}
|
||||
return
|
||||
}
|
||||
fmt.Println("chat" + time.Now().Format("2006-01-02 15:04:05"))
|
||||
chatResp, err := qwen.Chat(*chatReq)
|
||||
if err != nil {
|
||||
imageChan <- imageResult{err: err}
|
||||
return
|
||||
}
|
||||
if len(chatResp.Choices) == 0 {
|
||||
imageChan <- imageResult{err: errors.New("图片提示词聊天返回结果为空")}
|
||||
return
|
||||
}
|
||||
imagePrompt := chatResp.Choices[0].Message.Content
|
||||
fmt.Println("chat ok" + time.Now().Format("2006-01-02 15:04:05"))
|
||||
// 生成图片(图片要求加附件去生成图片)
|
||||
size := "1024*1024"
|
||||
var resultTask *modelQwen.QwenImageResponse
|
||||
if len(req.Images) == 0 {
|
||||
resultTask, err = qwen.GenerateTextImage(imagePrompt, size)
|
||||
} else {
|
||||
resultTask, err = qwen.GenerateEditImage(imagePrompt, req.Images, size)
|
||||
}
|
||||
if err != nil {
|
||||
imageChan <- imageResult{err: err}
|
||||
return
|
||||
}
|
||||
if resultTask.Code != "" {
|
||||
imageChan <- imageResult{err: errors.New("文生图失败: " + resultTask.Message)}
|
||||
return
|
||||
}
|
||||
fmt.Println("task" + time.Now().Format("2006-01-02 15:04:05"))
|
||||
// 等待图片生成完成
|
||||
result, err := qwen.ImgTaskResult(resultTask.Output.TaskID)
|
||||
if err != nil {
|
||||
imageChan <- imageResult{err: err}
|
||||
return
|
||||
}
|
||||
fmt.Println("image" + time.Now().Format("2006-01-02 15:04:05"))
|
||||
imageChan <- imageResult{result: result}
|
||||
}()
|
||||
|
||||
// 等待所有协程完成(并发收集结果)
|
||||
var titleRes chatResult
|
||||
var contentRes chatResult
|
||||
var imageRes imageResult
|
||||
|
||||
// 使用 select 来并发等待所有结果
|
||||
completed := 0
|
||||
total := 3
|
||||
|
||||
for completed < total {
|
||||
select {
|
||||
case titleRes = <-titleChan:
|
||||
completed++
|
||||
case contentRes = <-contentChan:
|
||||
completed++
|
||||
case imageRes = <-imageChan:
|
||||
completed++
|
||||
}
|
||||
}
|
||||
|
||||
// 处理标题结果
|
||||
if titleRes.err != nil {
|
||||
service.Error(ctx, fmt.Errorf("生成标题失败: %v", titleRes.err))
|
||||
return
|
||||
}
|
||||
resultAll.Title = titleRes.title
|
||||
|
||||
// 处理内容结果
|
||||
if contentRes.err != nil {
|
||||
service.Error(ctx, fmt.Errorf("生成内容失败: %v", contentRes.err))
|
||||
return
|
||||
}
|
||||
resultAll.Content = contentRes.content
|
||||
|
||||
// 处理图片结果
|
||||
if imageRes.err != nil {
|
||||
service.Error(ctx, fmt.Errorf("生成图片失败: %v", imageRes.err))
|
||||
return
|
||||
}
|
||||
|
||||
if imageRes.result == nil || len(imageRes.result.Output.Results) == 0 {
|
||||
service.Error(ctx, errors.New("图片生成失败"))
|
||||
return
|
||||
}
|
||||
|
||||
// 组装图片结果
|
||||
for _, v := range imageRes.result.Output.Results {
|
||||
resultAll.Result = append(resultAll.Result, struct {
|
||||
Url string `json:"url"`
|
||||
OrigPrompt string `json:"orig_prompt"`
|
||||
ActualPrompt string `json:"actual_prompt"`
|
||||
}{
|
||||
Url: v.URL,
|
||||
OrigPrompt: v.OrigPrompt,
|
||||
ActualPrompt: v.ActualPrompt,
|
||||
})
|
||||
}
|
||||
service.Success(ctx, resultAll)
|
||||
}
|
||||
|
||||
// buildChatRequest 组装聊天的参数(用于 MoreText)
|
||||
func buildChatRequest(prompt string, images []string) (*modelQwen.ChatRequest, error) {
|
||||
if prompt == "" {
|
||||
return nil, errors.New("提示词不能为空")
|
||||
}
|
||||
var chatReq modelQwen.ChatRequest
|
||||
chatReq.Model = "qwen3-max" //qwen3-max qwen-plus qwen-flash
|
||||
var content []modelQwen.Content
|
||||
content = append(content, modelQwen.Content{Type: "text", Text: prompt})
|
||||
for _, v := range images {
|
||||
if v != "" {
|
||||
content = append(content, modelQwen.Content{Type: "image_url", ImageURL: &modelQwen.ImageURL{URL: v}})
|
||||
}
|
||||
}
|
||||
chatReq.Messages = []modelQwen.Message{
|
||||
{
|
||||
Role: "user",
|
||||
Content: content,
|
||||
},
|
||||
}
|
||||
chatReq.Seed = time.Now().Unix()
|
||||
return &chatReq, nil
|
||||
}
|
||||
|
||||
// ChatReqGet 组装聊天的参数
|
||||
func ChatReqGet(req ImageGenerateRequest) (*modelQwen.ChatRequest, error) {
|
||||
return buildChatRequest(req.Prompt, req.Images)
|
||||
}
|
||||
|
||||
func cleanTitle(s string) string {
|
||||
var b strings.Builder
|
||||
for _, r := range strings.TrimSpace(s) {
|
||||
if unicode.Is(unicode.Han, r) || unicode.IsLetter(r) || unicode.IsDigit(r) ||
|
||||
unicode.IsPunct(r) || unicode.IsSpace(r) {
|
||||
b.WriteRune(r)
|
||||
}
|
||||
}
|
||||
out := strings.ReplaceAll(b.String(), "*", "")
|
||||
out = strings.TrimSpace(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// extractTitleAndContent 从完整文本中提取 title 和 content
|
||||
func extractTitleAndContent(text string) (title, content string) {
|
||||
reTitleLine := regexp.MustCompile(`(?m).*标题[::]\s*(.+)$`)
|
||||
if m := reTitleLine.FindStringSubmatch(text); len(m) >= 2 {
|
||||
title = cleanTitle(m[1])
|
||||
}
|
||||
|
||||
reContent := regexp.MustCompile(`(?s)标题[::].*?\n\s*\n(.*?)(?:\n\s*\n📸|\n\s*\n#|$)`)
|
||||
if m := reContent.FindStringSubmatch(text); len(m) >= 2 {
|
||||
content = strings.TrimSpace(m[1])
|
||||
content = regexp.MustCompile(`\n+`).ReplaceAllString(content, "\n")
|
||||
// 如果你希望把段内换行变成句内空格,可用下面这一行代替上面换行替换
|
||||
// content = regexp.MustCompile(`\s*\n\s*`).ReplaceAllString(content, " ")
|
||||
}
|
||||
|
||||
if content == "" && title != "" {
|
||||
idx := strings.Index(text, title)
|
||||
if idx >= 0 {
|
||||
after := text[idx+len(title):]
|
||||
after = strings.ReplaceAll(after, "**", "")
|
||||
// 截到 "📸" 或 第一个 "#" 标签
|
||||
if i := strings.Index(after, "📸"); i >= 0 {
|
||||
after = after[:i]
|
||||
} else if i := strings.Index(after, "#"); i >= 0 {
|
||||
after = after[:i]
|
||||
}
|
||||
content = strings.TrimSpace(after)
|
||||
}
|
||||
}
|
||||
|
||||
return title, content
|
||||
}
|
||||
|
||||
@ -170,7 +170,7 @@ func MetricsArtistAccountExport(ctx *gin.Context) {
|
||||
utils.CheckDirPath("./runtime/"+fmt.Sprint(userInfo.ID), true)
|
||||
sheet := "Sheet1"
|
||||
f := excelize.NewFile()
|
||||
headers := []string{"序号", "艺人", "用户编号", "DM账号", "DM账号昵称", "Instagram账号", "Instagram账号昵称", "TikTok账号", "TikTok账号昵称"}
|
||||
headers := []string{"序号", "艺人", "用户编号", "DM账号名", "Instagram账号名", "TikTok账号名"}
|
||||
for i, h := range headers {
|
||||
col, _ := excelize.ColumnNumberToName(i + 1)
|
||||
cell := col + "1"
|
||||
@ -196,14 +196,11 @@ func MetricsArtistAccountExport(ctx *gin.Context) {
|
||||
_ = write(2, it.ArtistName)
|
||||
_ = write(3, it.UserNum)
|
||||
_ = write(4, it.DmAccount)
|
||||
_ = write(5, it.DmNickname)
|
||||
_ = write(6, it.InstagramAccount)
|
||||
_ = write(7, it.InstagramNickname)
|
||||
_ = write(8, it.TiktokAccount)
|
||||
_ = write(9, it.TiktokNickname)
|
||||
_ = write(5, it.InstagramAccount)
|
||||
_ = write(6, it.TiktokAccount)
|
||||
}
|
||||
// 可选:设置列宽,使表格更美观
|
||||
_ = f.SetColWidth(sheet, "A", "AZ", 15)
|
||||
_ = f.SetColWidth(sheet, "A", "AZ", 18)
|
||||
|
||||
// 保存文件
|
||||
if err := f.SaveAs(filePath); err != nil {
|
||||
|
||||
@ -137,7 +137,7 @@ func HandShelf(c *gin.Context) {
|
||||
}
|
||||
res, err := service.BundleProvider.HandShelf(context.Background(), &req)
|
||||
if err != nil {
|
||||
service.Error(c, errors.New(common.HandShelfFailed))
|
||||
service.Error(c, err)
|
||||
return
|
||||
}
|
||||
service.Success(c, res)
|
||||
|
||||
@ -103,6 +103,24 @@ const (
|
||||
BalanceMetricsExportFailed = "服务使用明细数据导出失败"
|
||||
)
|
||||
|
||||
//素材库
|
||||
const (
|
||||
FileListFailed = "素材库列表查询失败"
|
||||
FileUsageFailed = "素材库使用情况查询失败"
|
||||
GetFileInfoFailed = "素材库文件信息查询失败"
|
||||
CreateFileFailed = "素材库文件创建失败"
|
||||
DeleteFileFailed = "素材库文件删除失败"
|
||||
SearchFileFailed = "素材库文件搜索失败"
|
||||
UploadFileFailed = "素材库文件上传失败"
|
||||
TusCreateFailed = "素材库文件创建失败"
|
||||
TusUploadFailed = "素材库文件上传失败"
|
||||
PreviewFileFailed = "素材库文件预览失败"
|
||||
ActionFailed = "素材库文件操作失败"
|
||||
DirDownloadFailed = "素材库文件下载失败"
|
||||
InvalidUploadOffset = "无效的上传偏移量"
|
||||
ERROR_OPEN_FILE = "打开文件错误"
|
||||
)
|
||||
|
||||
//官网
|
||||
const (
|
||||
CreateSecFilingFailed = "创建官方信息失败"
|
||||
|
||||
@ -2,6 +2,7 @@ package bundle
|
||||
|
||||
import (
|
||||
"context"
|
||||
"dubbo.apache.org/dubbo-go/v3/common/logger"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -9,7 +10,6 @@ import (
|
||||
"fonchain-fiee/api/bundle"
|
||||
"fonchain-fiee/api/order"
|
||||
"fonchain-fiee/api/payment"
|
||||
"fonchain-fiee/pkg/cache"
|
||||
"fonchain-fiee/pkg/config"
|
||||
"fonchain-fiee/pkg/model/login"
|
||||
"fonchain-fiee/pkg/service"
|
||||
@ -19,9 +19,6 @@ import (
|
||||
"math"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"dubbo.apache.org/dubbo-go/v3/common/logger"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
@ -144,13 +141,7 @@ func CreateAntomPay(c *gin.Context) {
|
||||
|
||||
// 获取 用户信息
|
||||
userInfo := login.GetUserInfoFromC(c)
|
||||
// 创建审批 防止重复提交
|
||||
lockKey := fmt.Sprintf("create_antom_pay_%v", userInfo.ID)
|
||||
reply := cache.RedisClient.SetNX(lockKey, 0, 5*time.Second)
|
||||
if !reply.Val() {
|
||||
service.Error(c, errors.New(common.CreateBundleFailed))
|
||||
return
|
||||
}
|
||||
|
||||
// outTradeNo就是orderNo,根据这个去查询子表的source,如果是2就时单独的子套餐,如果是1就是主套餐
|
||||
orderLimit, err := service.BundleProvider.OrderListByOrderNo(context.Background(), &bundle.OrderInfoByOrderNoRequest{
|
||||
OrderNo: req.OutTradeNo,
|
||||
|
||||
@ -2,9 +2,11 @@ package cast
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"fonchain-fiee/api/accountFiee"
|
||||
"fonchain-fiee/api/aryshare"
|
||||
"fonchain-fiee/api/bundle"
|
||||
"fonchain-fiee/api/cast"
|
||||
"fonchain-fiee/cmd/config"
|
||||
@ -17,7 +19,6 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
func MediaUserList(ctx *gin.Context) {
|
||||
@ -36,6 +37,11 @@ func MediaUserList(ctx *gin.Context) {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
for _, v := range resp.Data {
|
||||
_ = SyncAsAuth(v.ArtistUuid)
|
||||
}
|
||||
}()
|
||||
service.Success(ctx, resp)
|
||||
return
|
||||
}
|
||||
@ -106,22 +112,39 @@ func UpdateMediaAccount(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
// 查询艺人的信息
|
||||
userResp, err := service.CastProvider.MediaUserList(context.Background(), &cast.MediaUserListReq{
|
||||
ArtistUuid: req.ArtistUuid,
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
if userResp != nil && len(userResp.Data) > 0 {
|
||||
for _, v := range userResp.Data {
|
||||
if v.PlatformID == uint32(req.PlatformID) {
|
||||
service.Error(ctx, errors.New("账号已存在"))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
// 字符串转整型
|
||||
artistID, err := strconv.ParseUint(req.ArtistUuid, 10, 64)
|
||||
if config.AppConfig.System.AppMode != "dev" {
|
||||
infoResp, err = service.AccountFieeProvider.Info(context.Background(), &accountFiee.InfoRequest{
|
||||
ID: artistID,
|
||||
Domain: "app",
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
infoResp = &accountFiee.UserInfoResponse{
|
||||
Name: "小波",
|
||||
TelNum: "18288888888",
|
||||
}
|
||||
infoResp, err = GetArtistAccountInfo(artistID)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
if infoResp.SubNum == "" {
|
||||
service.Error(ctx, errors.New("用户不存在"))
|
||||
return
|
||||
}
|
||||
|
||||
//TODO 判断是否注册ay
|
||||
if err = CheckAsProfile(infoResp); err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
req.ArtistName = infoResp.Name
|
||||
req.ArtistPhone = infoResp.TelNum
|
||||
@ -166,8 +189,8 @@ func UpdateMediaAccount(ctx *gin.Context) {
|
||||
|
||||
// 账号授权
|
||||
func OAuthAccount(ctx *gin.Context) {
|
||||
var req *cast.OAuthAccountReq
|
||||
var resp *cast.OAuthAccountResp
|
||||
var req *cast.OAuthAccountV2Req
|
||||
var resp *cast.OAuthAccountV2Resp
|
||||
var err error
|
||||
if err = ctx.ShouldBind(&req); err != nil {
|
||||
service.Error(ctx, err)
|
||||
@ -177,11 +200,55 @@ func OAuthAccount(ctx *gin.Context) {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
if resp, err = service.CastProvider.OAuthAccount(ctx, req); err != nil {
|
||||
mediaResp, err := service.CastProvider.MediaUserList(ctx, &cast.MediaUserListReq{
|
||||
MediaUserID: req.MediaAccountUuid,
|
||||
Page: 1,
|
||||
PageSize: 1,
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
if mediaResp == nil || len(mediaResp.Data) == 0 {
|
||||
service.Error(ctx, errors.New("未找到该账号"))
|
||||
return
|
||||
}
|
||||
if err = SyncAsAuth(mediaResp.Data[0].ArtistUuid); err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
if resp, err = service.CastProvider.OAuthAccountV2(ctx, req); err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
if cast.PlatformIDENUM_DM == cast.PlatformIDENUM(resp.PlatformID) {
|
||||
service.Success(ctx, map[string]interface{}{
|
||||
"url": resp.AuthUrl,
|
||||
})
|
||||
return
|
||||
}
|
||||
if resp.ProfileKey == "" {
|
||||
service.Error(ctx, errors.New("艺人未添加平台账号"))
|
||||
return
|
||||
}
|
||||
jwtReq := &aryshare.GenerateJWTRequest{
|
||||
Domain: "",
|
||||
PrivateKey: "",
|
||||
ProfileKey: resp.ProfileKey,
|
||||
Logout: true,
|
||||
Redirect: fmt.Sprintf("%s?artistUuid=%s&platformID=%d", config.AppConfig.System.AuthCallback, resp.ArtistUuid, resp.PlatformID),
|
||||
AllowedSocial: []string{modelCast.PlatformNameKv[resp.PlatformID]},
|
||||
Verify: false,
|
||||
Base64: false,
|
||||
ExpiresIn: 0,
|
||||
Email: nil,
|
||||
}
|
||||
jwtResp, err := service.AyrshareProvider.GenerateJWT(context.Background(), jwtReq)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, jwtResp)
|
||||
return
|
||||
}
|
||||
|
||||
@ -230,6 +297,89 @@ func OAuth2Callback(ctx *gin.Context) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func AsOAuth2Callback(ctx *gin.Context) {
|
||||
var (
|
||||
//platformIds string
|
||||
//userID string
|
||||
)
|
||||
artistUuid := ctx.Query("artistUuid")
|
||||
//platformIDs := ctx.Query("platformID")
|
||||
//platformID, _ := strconv.ParseInt(platformIDs, 10, 64)
|
||||
// 刷新授权
|
||||
var err error
|
||||
var req modelCast.OAuthPlatformReq
|
||||
if err = ctx.ShouldBind(&req); err != nil {
|
||||
//service.Error(ctx, err)
|
||||
ctx.Redirect(http.StatusFound, fmt.Sprintf("%s?status=%d&message=%s", config.AppConfig.System.AuthRedirectUrl, 1, "参数错误"))
|
||||
return
|
||||
}
|
||||
err = SyncAsAuth(artistUuid)
|
||||
if err != nil {
|
||||
ctx.Redirect(http.StatusFound, fmt.Sprintf("%s?status=%d&message=%s", config.AppConfig.System.AuthRedirectUrl, 1, err.Error()))
|
||||
return
|
||||
}
|
||||
ctx.Redirect(http.StatusFound, fmt.Sprintf("%s?status=%d&message=%s", config.AppConfig.System.AuthRedirectUrl, 0, ""))
|
||||
return
|
||||
}
|
||||
|
||||
func SyncAsAuth(artistUuid string) error {
|
||||
resp, err := service.CastProvider.GetArtist(context.Background(), &cast.GetArtistReq{ArtistUuid: artistUuid})
|
||||
if err != nil {
|
||||
return errors.New("获取艺人信息错误")
|
||||
}
|
||||
if resp == nil || resp.ArtistInfo == nil || resp.ArtistInfo.ProfileKey == "" {
|
||||
return errors.New("艺人未注册")
|
||||
}
|
||||
userResp, err := service.AyrshareProvider.GetUser(context.Background(), &aryshare.GetUserRequest{
|
||||
ProfileKey: resp.ArtistInfo.ProfileKey,
|
||||
InstagramDetails: true,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.New("获取艺人绑定信息错误")
|
||||
}
|
||||
var authReq *cast.UpdateOAuthReq
|
||||
authReq = &cast.UpdateOAuthReq{Data: make([]*cast.UpdateOAuthReq_Info, 0)}
|
||||
if len(userResp.DisplayNames) == 0 {
|
||||
//return errors.New("没有授权信息")
|
||||
authReq.Data = append(authReq.Data, &cast.UpdateOAuthReq_Info{
|
||||
ArtistUuid: artistUuid,
|
||||
PlatformID: cast.PlatformIDENUM_UNKNOWN,
|
||||
AsID: "",
|
||||
PlatformUserName: "",
|
||||
AutInfo: "",
|
||||
})
|
||||
_, err = service.CastProvider.UpdateOAuth(context.Background(), authReq)
|
||||
if err != nil {
|
||||
return errors.New("同步授权信息失败")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var asInfoB []byte
|
||||
for _, v := range userResp.DisplayNames {
|
||||
asInfoB, _ = json.Marshal(v)
|
||||
platformIDENUM := cast.PlatformIDENUM(modelCast.NamePlatformIDKv[v.Platform])
|
||||
if platformIDENUM == cast.PlatformIDENUM_UNKNOWN {
|
||||
continue
|
||||
}
|
||||
authReq.Data = append(authReq.Data, &cast.UpdateOAuthReq_Info{
|
||||
ArtistUuid: artistUuid,
|
||||
PlatformID: platformIDENUM,
|
||||
AsID: v.Id,
|
||||
PlatformUserName: v.Username,
|
||||
AutInfo: string(asInfoB),
|
||||
})
|
||||
}
|
||||
if len(authReq.Data) != 0 {
|
||||
_, err = service.CastProvider.UpdateOAuth(context.Background(), authReq)
|
||||
if err != nil {
|
||||
return errors.New("同步授权信息失败")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RefreshToken(ctx *gin.Context) {
|
||||
var req *cast.RefreshTokenReq
|
||||
var resp *cast.RefreshTokenResp
|
||||
@ -270,7 +420,71 @@ func ArtistInfo(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
func Test(ctx *gin.Context) {
|
||||
service.CastProvider.Test(ctx, &emptypb.Empty{})
|
||||
func CheckAsProfile(infoResp *accountFiee.UserInfoResponse) error {
|
||||
var asArtistResp *cast.GetArtistResp
|
||||
var err error
|
||||
title := fmt.Sprintf("%s_%s", config.AppConfig.System.AppMode, infoResp.SubNum)
|
||||
// 查询艺人的信息
|
||||
if asArtistResp, err = service.CastProvider.GetArtist(context.Background(), &cast.GetArtistReq{
|
||||
ArtistUuid: fmt.Sprint(infoResp.Id),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if asArtistResp != nil && asArtistResp.ArtistInfo != nil && asArtistResp.ArtistInfo.ProfileKey != "" {
|
||||
return nil
|
||||
}
|
||||
createProfileResp, err := service.AyrshareProvider.CreateProfile(context.Background(), &aryshare.CreateProfileRequest{
|
||||
Title: title,
|
||||
MessagingActive: true,
|
||||
HideTopHeader: false,
|
||||
TopHeader: "",
|
||||
DisableSocial: nil,
|
||||
Team: false,
|
||||
Email: "",
|
||||
SubHeader: "",
|
||||
Tags: []string{config.AppConfig.System.AppMode},
|
||||
})
|
||||
if err != nil {
|
||||
zap.L().Error("CreateProfile error", zap.Error(err))
|
||||
err = errors.New("创建平台艺人账号失败")
|
||||
return err
|
||||
}
|
||||
zap.L().Info("CreateProfile success", zap.Any("createProfileResp", createProfileResp), zap.Any("title", title))
|
||||
_, err = service.CastProvider.UpdateArtist(context.Background(), &cast.UpdateArtistReq{
|
||||
Uuid: asArtistResp.Uuid,
|
||||
ArtistInfo: &cast.ArtistInfo{
|
||||
ArtistUuid: fmt.Sprint(infoResp.Id),
|
||||
RefID: createProfileResp.RefId,
|
||||
ProfileKey: createProfileResp.ProfileKey,
|
||||
SubNum: infoResp.SubNum,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func SyncAsProfile(ctx *gin.Context) {
|
||||
var req *modelCast.SyncAsProfileReq
|
||||
var err error
|
||||
if err = ctx.ShouldBind(&req); err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
infoResp, err := GetArtistAccountInfo(req.ID)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
if infoResp.SubNum == "" {
|
||||
service.Error(ctx, errors.New("用户不存在"))
|
||||
return
|
||||
}
|
||||
if err = CheckAsProfile(infoResp); err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, infoResp)
|
||||
return
|
||||
}
|
||||
|
||||
@ -191,13 +191,14 @@ func ImportBatch(ctx *gin.Context) {
|
||||
req.Data = append(req.Data, &temp)
|
||||
continue
|
||||
}
|
||||
subInfoResp, _err := service.AccountFieeProvider.SubNumGetInfo(context.Background(), &accountFiee.SubNumGetInfoRequest{
|
||||
var subInfoResp *accountFiee.UserInfoResponse
|
||||
subInfoResp, err = service.AccountFieeProvider.SubNumGetInfo(context.Background(), &accountFiee.SubNumGetInfoRequest{
|
||||
SubNum: row[2],
|
||||
Domain: "app",
|
||||
})
|
||||
if _err != nil {
|
||||
zap.L().Error("AccountFieeProvider.SubNumGetInfo", zap.Error(_err))
|
||||
temp.Remark = _err.Error()
|
||||
if err != nil {
|
||||
zap.L().Error("AccountFieeProvider.SubNumGetInfo", zap.Error(err))
|
||||
temp.Remark = err.Error()
|
||||
} else {
|
||||
temp.ArtistUuid = fmt.Sprint(subInfoResp.Id)
|
||||
temp.ArtistName = subInfoResp.Name
|
||||
|
||||
104
pkg/service/cast/test.go
Normal file
104
pkg/service/cast/test.go
Normal file
@ -0,0 +1,104 @@
|
||||
package cast
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"fonchain-fiee/api/aryshare"
|
||||
"fonchain-fiee/api/cast"
|
||||
"fonchain-fiee/cmd/config"
|
||||
"fonchain-fiee/pkg/service"
|
||||
"fonchain-fiee/pkg/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Test(ctx *gin.Context) {
|
||||
action := ctx.PostForm("action")
|
||||
if action == "getPost" {
|
||||
id := ctx.PostForm("id")
|
||||
profileKey := ctx.PostForm("profileKey")
|
||||
resp, err := service.AyrshareProvider.GetPost(context.Background(), &aryshare.GetPostRequest{
|
||||
Id: id,
|
||||
ProfileKey: profileKey,
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
return
|
||||
}
|
||||
if action == "refreshPost" {
|
||||
err := RefreshPublish()
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, "刷新成功")
|
||||
return
|
||||
}
|
||||
if action == "updateStatus" {
|
||||
resp, err := service.CastProvider.UpdateStatus(context.Background(), &cast.UpdateStatusReq{
|
||||
WorkAction: cast.WorkActionENUM_CONFIRM,
|
||||
WorkUuid: "00059232-3696-4c3e-a960-125955f2d881",
|
||||
ApprovalID: "",
|
||||
ConfirmRemark: "",
|
||||
ConfirmStatus: 1,
|
||||
ApprovalReply: "",
|
||||
AutoPublish: 0,
|
||||
CostType: 1,
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
return
|
||||
}
|
||||
if action == "dmGet" {
|
||||
mediaUuid := ctx.PostForm("mediaUuid")
|
||||
token := ctx.PostForm("token")
|
||||
_, dmData, err := utils.GetUrl(fmt.Sprintf("https://api.dailymotion.com/video/%s?fields=id,title,url,published,private", mediaUuid),
|
||||
map[string]string{"Authorization": "Bearer " + token}, config.AppConfig.System.ProxyUrl)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, dmData)
|
||||
return
|
||||
}
|
||||
|
||||
if action == "" {
|
||||
profileKey := ctx.PostForm("profileKey")
|
||||
resp, err := service.AyrshareProvider.GetUser(context.Background(), &aryshare.GetUserRequest{
|
||||
ProfileKey: profileKey,
|
||||
InstagramDetails: true,
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
return
|
||||
}
|
||||
if action == "getProfile" {
|
||||
//profileKey := ctx.PostForm("profileKey")
|
||||
resp, err := service.AyrshareProvider.GetProfiles(context.Background(), &aryshare.GetProfilesRequest{
|
||||
Title: "",
|
||||
RefId: "",
|
||||
HasActiveSocialAccounts: false,
|
||||
IncludesActiveSocialAccounts: nil,
|
||||
ActionLog: nil,
|
||||
Limit: 0,
|
||||
Cursor: "",
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, "unknow")
|
||||
return
|
||||
}
|
||||
@ -3,8 +3,10 @@ package cast
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"fonchain-fiee/api/accountFiee"
|
||||
"fonchain-fiee/cmd/config"
|
||||
"fonchain-fiee/pkg/model/login"
|
||||
"fonchain-fiee/pkg/service"
|
||||
|
||||
"dubbo.apache.org/dubbo-go/v3/common/constant"
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -38,3 +40,25 @@ func NewCtxWithUserInfo(ctx *gin.Context) (newCtx context.Context) {
|
||||
newCtx = context.WithValue(context.Background(), constant.DubboCtxKey("attachment"), mm)
|
||||
return
|
||||
}
|
||||
|
||||
func GetArtistAccountInfo(artistID uint64) (*accountFiee.UserInfoResponse, error) {
|
||||
var infoResp *accountFiee.UserInfoResponse
|
||||
var err error
|
||||
if config.AppConfig.System.AppMode != "dev" {
|
||||
infoResp, err = service.AccountFieeProvider.Info(context.Background(), &accountFiee.InfoRequest{
|
||||
ID: artistID,
|
||||
Domain: "app",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
infoResp = &accountFiee.UserInfoResponse{
|
||||
Id: 1234,
|
||||
Name: "小波",
|
||||
TelNum: "18288888888",
|
||||
SubNum: "T12345",
|
||||
}
|
||||
}
|
||||
return infoResp, nil
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"fonchain-fiee/api/accountFiee"
|
||||
"fonchain-fiee/api/aryshare"
|
||||
"fonchain-fiee/api/bundle"
|
||||
"fonchain-fiee/api/cast"
|
||||
"fonchain-fiee/cmd/config"
|
||||
@ -15,13 +16,17 @@ import (
|
||||
modelCast "fonchain-fiee/pkg/model/cast"
|
||||
"fonchain-fiee/pkg/model/login"
|
||||
"fonchain-fiee/pkg/service"
|
||||
"fonchain-fiee/pkg/service/check"
|
||||
"fonchain-fiee/pkg/utils"
|
||||
"fonchain-fiee/pkg/utils/stime"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"dubbo.apache.org/dubbo-go/v3/common/constant"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/xuri/excelize/v2"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
@ -261,14 +266,18 @@ func CheckUserBundleBalance(userID int32, balanceType modelCast.BalanceTypeEnum)
|
||||
err = errors.New(e.ErrorBalanceInsufficient)
|
||||
return
|
||||
}
|
||||
case modelCast.BalanceTypeDataValue:
|
||||
if resp.DataAnalysisNumber-resp.DataAnalysisConsumptionNumber <= 0 {
|
||||
err = errors.New(e.ErrorBalanceInsufficient)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Publish(ctx *gin.Context) {
|
||||
var (
|
||||
req *cast.PublishReq
|
||||
resp *cast.PublishResp
|
||||
req *cast.PublishReq
|
||||
//workInfoResp *cast.WorkInfoResp
|
||||
)
|
||||
var err error
|
||||
@ -277,12 +286,220 @@ func Publish(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
newCtx := NewCtxWithUserInfo(ctx)
|
||||
resp, err = service.CastProvider.Publish(newCtx, req)
|
||||
if err != nil {
|
||||
if err = PublishWork(newCtx, req); err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
service.Success(ctx, req)
|
||||
return
|
||||
}
|
||||
|
||||
// PublishWork 统一发布
|
||||
func PublishWork(ctx context.Context, req *cast.PublishReq) error {
|
||||
//检测所有艺人的账号状态
|
||||
if len(req.WorkUuids) == 0 {
|
||||
return errors.New("请选择作品")
|
||||
}
|
||||
var err error
|
||||
var artistUuids []string
|
||||
for _, workUuid := range req.WorkUuids {
|
||||
var workInfoResp *cast.WorkInfoResp
|
||||
workInfoResp, err = service.CastProvider.WorkInfo(ctx, &cast.WorkInfoReq{WorkUuid: workUuid})
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
artistUuids = append(artistUuids, workInfoResp.ArtistUuid)
|
||||
}
|
||||
artistUuids = utils.UniqueT(artistUuids)
|
||||
for _, artistUuid := range artistUuids {
|
||||
_ = SyncAsAuth(artistUuid)
|
||||
}
|
||||
_, err = service.CastProvider.Publish(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var errs []error
|
||||
errs = PostAS(req.WorkUuids)
|
||||
if len(errs) > 0 {
|
||||
var errMsg string
|
||||
for _, v := range errs {
|
||||
errMsg += v.Error() + " "
|
||||
}
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func PostAS(workUuids []string) (errs []error) {
|
||||
for _, workUuid := range workUuids {
|
||||
workDetail, _err := service.CastProvider.WorkDetail(context.Background(), &cast.WorkDetailReq{
|
||||
WorkUuid: workUuid,
|
||||
})
|
||||
if _err != nil {
|
||||
errs = append(errs, errors.New("获取作品详情失败"))
|
||||
zap.L().Error("Publish WorkDetail failed", zap.String("workUuid", workUuid), zap.Error(_err))
|
||||
continue
|
||||
}
|
||||
//if workDetail.WorkStatus != 9 { // 微服务做判断了这边不用判断
|
||||
// errs = append(errs, fmt.Errorf("作品状态不正确,标题是:%s", workDetail.Title))
|
||||
// continue
|
||||
//}
|
||||
needPlatformIDs := workDetail.NeedPlatformIDs
|
||||
if len(needPlatformIDs) == 0 {
|
||||
errs = append(errs, errors.New("没有平台可发布"))
|
||||
continue
|
||||
}
|
||||
var mediaUrls []string
|
||||
var isVideo bool
|
||||
if workDetail.WorkCategory == 1 {
|
||||
isVideo = false
|
||||
mediaUrls = workDetail.Images
|
||||
}
|
||||
if workDetail.WorkCategory == 2 {
|
||||
isVideo = true
|
||||
mediaUrls = []string{workDetail.VideoUrl}
|
||||
}
|
||||
ArtistInfoResp, _err := service.CastProvider.GetArtist(context.Background(), &cast.GetArtistReq{
|
||||
ArtistUuid: workDetail.ArtistUuid,
|
||||
})
|
||||
if _err != nil {
|
||||
errs = append(errs, errors.New("获取艺人信息失败"))
|
||||
continue
|
||||
}
|
||||
if ArtistInfoResp == nil || ArtistInfoResp.ArtistInfo == nil || ArtistInfoResp.ArtistInfo.ProfileKey == "" {
|
||||
errs = append(errs, errors.New("艺人平台信息未配置"))
|
||||
continue
|
||||
}
|
||||
|
||||
for _, platformID := range needPlatformIDs {
|
||||
var postResp *aryshare.PostResponse = &aryshare.PostResponse{}
|
||||
postReq := &aryshare.PostRequest{
|
||||
Post: workDetail.Title,
|
||||
Platforms: []string{modelCast.PlatformNameKv[uint32(platformID)]},
|
||||
MediaUrls: mediaUrls,
|
||||
IsVideo: isVideo,
|
||||
ScheduleDate: "",
|
||||
ValidateScheduled: true,
|
||||
ShortenLinks: false,
|
||||
DisableComments: false,
|
||||
ProfileKey: ArtistInfoResp.ArtistInfo.ProfileKey,
|
||||
}
|
||||
switch cast.PlatformIDENUM(platformID) {
|
||||
case cast.PlatformIDENUM_INS:
|
||||
postReq.InstagramOptions = &aryshare.InstagramOptions{
|
||||
ShareReelsFeed: false,
|
||||
AudioName: "",
|
||||
ThumbNail: workDetail.CoverUrl,
|
||||
ThumbNailOffset: 0,
|
||||
Stories: false,
|
||||
AltText: nil,
|
||||
LocationId: "",
|
||||
UserTags: nil,
|
||||
Collaborators: nil,
|
||||
AutoResize: false,
|
||||
DisableComments: false,
|
||||
}
|
||||
case cast.PlatformIDENUM_TIKTOK:
|
||||
postReq.TikTokOptions = &aryshare.TikTokOptions{
|
||||
AutoAddMusic: false,
|
||||
DisableComments: false,
|
||||
DisableDuet: false,
|
||||
DisableStitch: false,
|
||||
Draft: false,
|
||||
IsAIGenerated: false,
|
||||
IsBrandedContent: false,
|
||||
IsBrandOrganic: false,
|
||||
ImageCoverIndex: int32(workDetail.CoverTimestampMs),
|
||||
Title: "",
|
||||
ThumbNailOffset: 0,
|
||||
ThumbNail: "",
|
||||
Visibility: "",
|
||||
}
|
||||
}
|
||||
zap.L().Info("Publish Ayrshare PostReq", zap.Any("workUuid", workDetail.WorkUuid), zap.Any("postReq", postReq), zap.Any("workDetail", workDetail))
|
||||
postResp, _err = service.AyrshareProvider.Post(context.Background(), postReq)
|
||||
zap.L().Info("Publish Ayrshare postResp", zap.Any("workUuid", workDetail.WorkUuid), zap.Any("postResp", postResp))
|
||||
if _err != nil {
|
||||
go func() {
|
||||
_, _ = service.CastProvider.UpdateWorkPublishLog(context.Background(), &cast.UpdateWorkPublishLogReq{
|
||||
WorkUuid: workUuid,
|
||||
PlatformID: cast.PlatformIDENUM(platformID),
|
||||
Action: "post",
|
||||
Detail: _err.Error(),
|
||||
})
|
||||
}()
|
||||
infoReq := &cast.UpdateWorkPlatformInfoReq{PlatformInfoData: make([]*cast.PlatformInfo, 0)}
|
||||
infoReq.PlatformInfoData = append(infoReq.PlatformInfoData, &cast.PlatformInfo{
|
||||
WorkUuid: workDetail.WorkUuid,
|
||||
MediaAccountUuid: "",
|
||||
PlatformID: uint32(platformID),
|
||||
PublishType: 2,
|
||||
PublishResp: _err.Error(),
|
||||
PublishMediaId: "",
|
||||
PublishStatus: cast.PublishStatusENUM_PublishMediaStatus_EXCEPTION,
|
||||
Remark: "",
|
||||
})
|
||||
_, _ = service.CastProvider.UpdateWorkPlatformInfo(context.Background(), infoReq)
|
||||
zap.L().Error("PostAs Post err", zap.Error(_err))
|
||||
errs = append(errs, errors.New(fmt.Sprintf("发布失败,标题是:%s,平台是:%s", workDetail.Title, modelCast.PlatformNameKv[uint32(platformID)])))
|
||||
continue
|
||||
}
|
||||
go func() {
|
||||
postBytes, _ := json.Marshal(postResp)
|
||||
_, _ = service.CastProvider.UpdateWorkPublishLog(context.Background(), &cast.UpdateWorkPublishLogReq{
|
||||
PlatformID: cast.PlatformIDENUM(platformID),
|
||||
WorkUuid: workUuid,
|
||||
Action: "post",
|
||||
Detail: string(postBytes),
|
||||
})
|
||||
}()
|
||||
zap.L().Info("PostAs", zap.Any("postResp", postResp), zap.Any("workDetail", workDetail))
|
||||
infoReq := &cast.UpdateWorkPlatformInfoReq{
|
||||
PlatformInfoData: make([]*cast.PlatformInfo, 0),
|
||||
}
|
||||
if postResp == nil || postResp.Posts == nil || len(postResp.Posts) == 0 || postResp.Posts[0].PostIds == nil {
|
||||
errs = append(errs, fmt.Errorf("标题:%s,请求平台失败", workDetail.Title))
|
||||
continue
|
||||
}
|
||||
postIDs := postResp.Posts[0].PostIds
|
||||
postData, _ := json.Marshal(postResp)
|
||||
for _, postInfo := range postIDs {
|
||||
var platformID uint32
|
||||
switch postInfo.Platform {
|
||||
case "tiktok":
|
||||
platformID = 1
|
||||
case "instagram":
|
||||
platformID = 3
|
||||
}
|
||||
publishStatus := cast.PublishStatusENUM_PublishMediaStatus_NO
|
||||
if postInfo.Status == "success" {
|
||||
publishStatus = cast.PublishStatusENUM_PublishMediaStatus_ING
|
||||
} else {
|
||||
publishStatus = cast.PublishStatusENUM_PublishMediaStatus_FAIL
|
||||
}
|
||||
switch postInfo.Id {
|
||||
case "pending":
|
||||
publishStatus = cast.PublishStatusENUM_PublishMediaStatus_ING
|
||||
}
|
||||
postBytes, _ := json.Marshal(postInfo)
|
||||
infoReq.PlatformInfoData = append(infoReq.PlatformInfoData, &cast.PlatformInfo{
|
||||
WorkUuid: workDetail.WorkUuid,
|
||||
MediaAccountUuid: "", //FIXME
|
||||
PlatformID: platformID,
|
||||
PublishType: 2,
|
||||
PublishResp: string(postBytes),
|
||||
PublishMediaId: postResp.Posts[0].Id,
|
||||
PublishStatus: publishStatus,
|
||||
Remark: string(postData),
|
||||
})
|
||||
}
|
||||
_, err := service.CastProvider.UpdateWorkPlatformInfo(context.Background(), infoReq)
|
||||
if err != nil {
|
||||
zap.L().Error("Publish UpdateWorkPlatformInfo failed", zap.String("workUuid", workUuid), zap.Error(err))
|
||||
}
|
||||
zap.L().Info("Publish Ayrshare PostResp", zap.Any("postResp", postResp))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -504,8 +721,8 @@ func WorkListExport(ctx *gin.Context) {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
var loigcCastWork = new(logicCast.Work)
|
||||
excelFile, err := loigcCastWork.ExportExcelWorkList(resp.Data)
|
||||
var logicCastWork = new(logicCast.Work)
|
||||
excelFile, err := logicCastWork.ExportExcelWorkList(resp.Data)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
@ -545,7 +762,9 @@ func ProcessTask(ctx context.Context, workUuid string) {
|
||||
zap.L().Error("从队列移除任务失败",
|
||||
zap.String("workUuid", workUuid),
|
||||
zap.Error(err))
|
||||
return
|
||||
}
|
||||
//_ = PublishWork(context.Background(), &cast.PublishReq{WorkUuids: []string{workUuid}})
|
||||
zap.L().Info("自动确认成功", zap.String("workUuid", workUuid))
|
||||
}
|
||||
|
||||
@ -669,3 +888,445 @@ func GetBalanceLayout(ctx *gin.Context) {
|
||||
json.Unmarshal([]byte(res.Data), &j)
|
||||
service.Success(ctx, j)
|
||||
}
|
||||
|
||||
func ImportWorkBatch(ctx *gin.Context) {
|
||||
excelFile, err := ctx.FormFile("file")
|
||||
var (
|
||||
mediaInfoResp *cast.MediaInfoResp
|
||||
)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
loginInfo := login.GetUserInfoFromC(ctx)
|
||||
lockKey := fmt.Sprintf("import_work_batch:%d", loginInfo.ID)
|
||||
replay := cache.RedisClient.SetNX(lockKey, time.Now().Format("20060102150405"), 5*time.Minute)
|
||||
if !replay.Val() {
|
||||
service.Error(ctx, errors.New("有导入任务正在进行,请稍后再试"))
|
||||
return
|
||||
}
|
||||
defer cache.RedisClient.Del(lockKey)
|
||||
tempDir := "./runtime/work"
|
||||
_, err = utils.CheckDirPath(tempDir, true)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
fileName := fmt.Sprintf("%d_in_work.xlsx", time.Now().UnixMicro())
|
||||
excelPath := filepath.Join(tempDir, fileName)
|
||||
if err = ctx.SaveUploadedFile(excelFile, excelPath); err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
excelData, err := excelize.OpenFile(excelPath)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
defer excelData.Close()
|
||||
// 解析Excel中的数据
|
||||
rows, err := excelData.GetRows("Sheet1")
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
req := cast.ImportWorkBatchReq{
|
||||
ImageWorks: make([]*cast.UpdateWorkImageReq, 0),
|
||||
}
|
||||
for line, row := range rows {
|
||||
if line == 0 {
|
||||
continue
|
||||
}
|
||||
if len(row) == 0 {
|
||||
continue
|
||||
}
|
||||
temp := &cast.UpdateWorkImageReq{
|
||||
LineNo: uint32(line),
|
||||
Source: 3,
|
||||
}
|
||||
var artistNum string
|
||||
if len(row) > 1 && utils.CleanString(row[1]) != "" {
|
||||
artistNum = utils.CleanString(row[1])
|
||||
artistSubNum := utils.CleanString(row[1])
|
||||
if artistNum == "" {
|
||||
temp.Remark = "艺人编号不能为空"
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
}
|
||||
var subInfoResp *accountFiee.UserInfoResponse
|
||||
if config.AppConfig.System.AppMode == "dev" { //FIXME
|
||||
subInfoResp = &accountFiee.UserInfoResponse{
|
||||
Id: 123456,
|
||||
Name: "测试用户",
|
||||
TelNum: "18288888888",
|
||||
TelAreaCode: "86",
|
||||
}
|
||||
} else {
|
||||
subInfoResp, err = service.AccountFieeProvider.SubNumGetInfo(context.Background(), &accountFiee.SubNumGetInfoRequest{
|
||||
SubNum: artistSubNum,
|
||||
Domain: "app",
|
||||
})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
temp.Remark = fmt.Sprintf("自媒体用户查询失败:%s", err.Error())
|
||||
zap.L().Error("AccountFieeProvider.SubNumGetInfo", zap.Error(err))
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
if subInfoResp == nil || subInfoResp.Id == 0 {
|
||||
temp.Remark = "自媒体用户不存在"
|
||||
zap.L().Error("AccountFieeProvider.SubNumGetInfo user not found", zap.String("subNum", artistSubNum))
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
temp.ArtistUuid = fmt.Sprint(subInfoResp.Id)
|
||||
temp.ArtistName = subInfoResp.Name
|
||||
temp.ArtistPhone = subInfoResp.TelNum
|
||||
temp.ArtistPhoneAreaCode = subInfoResp.TelAreaCode
|
||||
}
|
||||
if len(row) > 5 {
|
||||
temp.Title = utils.CleanString(row[5])
|
||||
}
|
||||
if len(row) > 6 {
|
||||
temp.Content = utils.CleanString(row[6])
|
||||
}
|
||||
// 图片
|
||||
for i := 8; i <= 18; i++ {
|
||||
if len(row) > i {
|
||||
if utils.CleanString(row[i]) != "" {
|
||||
ok, _err := check.ImageCheckUrlValid(row[i])
|
||||
if _err != nil {
|
||||
temp.Remark = _err.Error()
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
break
|
||||
}
|
||||
if !ok {
|
||||
temp.Remark = fmt.Sprintf("图片%d黄反审核未通过", i-7)
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
break
|
||||
}
|
||||
temp.Images = append(temp.Images, utils.CleanString(row[i]))
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(temp.Images) == 0 {
|
||||
if temp.Remark == "" {
|
||||
temp.Remark = "图片不能为空"
|
||||
}
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
if len(row) > 2 && utils.CleanString(row[2]) != "" {
|
||||
mediaInfoResp, err = service.CastProvider.MediaInfo(context.Background(), &cast.MediaInfoReq{
|
||||
ArtistUuid: temp.ArtistUuid,
|
||||
PlatformID: cast.PlatformIDENUM_TIKTOK,
|
||||
PlatformUserName: utils.CleanString(row[2]),
|
||||
})
|
||||
if err != nil || mediaInfoResp.Info.MediaAccountUuid == "" {
|
||||
temp.Remark = fmt.Sprintf("TIKTOK账号名不存在")
|
||||
zap.L().Error("CastProvider.MediaInfo", zap.Error(err))
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
temp.PublishConfig1 = &cast.PublishConfig{
|
||||
ForbidComment: 1,
|
||||
PublicType: 1,
|
||||
CanJoin: 1,
|
||||
CanQuote: 1,
|
||||
CanComment: 1,
|
||||
IsAI: 1,
|
||||
}
|
||||
temp.PlatformIDs = append(temp.PlatformIDs, cast.PlatformIDENUM_TIKTOK)
|
||||
temp.MediaAccountNames = append(temp.MediaAccountNames, utils.CleanString(row[2]))
|
||||
temp.MediaAccountUuids = append(temp.MediaAccountUuids, mediaInfoResp.Info.MediaAccountUuid)
|
||||
}
|
||||
if len(row) > 3 && utils.CleanString(row[3]) != "" {
|
||||
mediaInfoResp, err = service.CastProvider.MediaInfo(context.Background(), &cast.MediaInfoReq{
|
||||
ArtistUuid: temp.ArtistUuid,
|
||||
PlatformID: cast.PlatformIDENUM_INS,
|
||||
PlatformUserName: utils.CleanString(row[3]),
|
||||
})
|
||||
if err != nil || mediaInfoResp.Info.MediaAccountUuid == "" {
|
||||
temp.Remark = fmt.Sprintf("INS账号名不存在")
|
||||
zap.L().Error("CastProvider.MediaInfo", zap.Error(err))
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
temp.PublishConfig1 = &cast.PublishConfig{
|
||||
ForbidComment: 1,
|
||||
PublicType: 1,
|
||||
CanJoin: 1,
|
||||
CanQuote: 1,
|
||||
CanComment: 1,
|
||||
IsAI: 1,
|
||||
}
|
||||
temp.PlatformIDs = append(temp.PlatformIDs, cast.PlatformIDENUM_INS)
|
||||
temp.MediaAccountNames = append(temp.MediaAccountNames, utils.CleanString(row[3]))
|
||||
temp.MediaAccountUuids = append(temp.MediaAccountUuids, mediaInfoResp.Info.MediaAccountUuid)
|
||||
}
|
||||
if len(row) > 4 && utils.CleanString(row[4]) != "" {
|
||||
temp.Remark = fmt.Sprintf("DM不能发图文")
|
||||
zap.L().Error("CastProvider.MediaInfo", zap.Error(err))
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
/*mediaInfoResp, err = service.CastProvider.MediaInfo(context.Background(), &cast.MediaInfoReq{
|
||||
ArtistUuid: temp.ArtistUuid,
|
||||
PlatformID: cast.PlatformIDENUM_DM,
|
||||
PlatformUserName: utils.CleanString(row[4]),
|
||||
})
|
||||
if err != nil || mediaInfoResp.Info.MediaAccountUuid == "" {
|
||||
temp.Remark = fmt.Sprintf("DM账号名不存在")
|
||||
zap.L().Error("CastProvider.MediaInfo", zap.Error(err))
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
temp.PlatformIDs = append(temp.PlatformIDs, cast.PlatformIDENUM_DM)
|
||||
temp.PublishConfig1 = &cast.PublishConfig{
|
||||
ForbidComment: 1,
|
||||
PublicType: 1,
|
||||
CanJoin: 1,
|
||||
CanQuote: 1,
|
||||
CanComment: 1,
|
||||
IsAI: 1,
|
||||
}
|
||||
temp.MediaAccountNames = append(temp.MediaAccountNames, utils.CleanString(row[4]))
|
||||
temp.MediaAccountUuids = append(temp.MediaAccountUuids, mediaInfoResp.Info.MediaAccountUuid)*/
|
||||
}
|
||||
if artistNum == "" {
|
||||
temp.Remark = "艺人编号不能为空"
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
if len(temp.MediaAccountUuids) == 0 {
|
||||
temp.Remark = "账号名不能为空"
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
if len(temp.PlatformIDs) == 0 {
|
||||
temp.Remark = "关联平台不能为空"
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
if temp.Title == "" {
|
||||
temp.Remark = "标题不能为空"
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
if temp.Content == "" {
|
||||
temp.Remark = "内容不能为空"
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
if len(temp.Images) == 0 {
|
||||
temp.Remark = "图片不能为空"
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
continue
|
||||
}
|
||||
req.ImageWorks = append(req.ImageWorks, temp)
|
||||
}
|
||||
if len(req.ImageWorks) == 0 {
|
||||
service.Error(ctx, errors.New(e.ErrNoData))
|
||||
return
|
||||
}
|
||||
newCtx := NewCtxWithUserInfo(ctx)
|
||||
resp, err := service.CastProvider.ImportWorkBatch(newCtx, &req)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
// 打开模板文件,如果有失败的数据,生成结果文件
|
||||
var urlResult string
|
||||
if resp.FailCount > 0 {
|
||||
hasValueRows := make(map[int]bool, resp.FailCount)
|
||||
for _, v := range resp.ImageWorks {
|
||||
if !v.Success {
|
||||
rowNum := int(v.LineNo) + 1
|
||||
excelData.SetCellValue("Sheet1", fmt.Sprintf("H%d", rowNum), v.Remark)
|
||||
hasValueRows[rowNum] = true
|
||||
}
|
||||
}
|
||||
for i := len(rows) - 1; i >= 1; i-- { // 从最后一行开始
|
||||
if !hasValueRows[i+1] {
|
||||
if err = excelData.RemoveRow("Sheet1", i+1); err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
resultPath := fmt.Sprintf("./runtime/work/%s", fileName)
|
||||
if err = excelData.SaveAs(resultPath); err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
urlHost := config.AppConfig.System.FieeHost
|
||||
urlResult = fmt.Sprintf("%s/api/fiee/static/work/%s", urlHost, fileName)
|
||||
}
|
||||
service.Success(ctx, map[string]interface{}{
|
||||
"successCount": resp.SuccessCount,
|
||||
"failCount": resp.FailCount,
|
||||
"resultUrl": urlResult,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// RefreshPost 刷新帖子状态
|
||||
func RefreshPost(ctx *gin.Context) {
|
||||
err := RefreshPublish()
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
service.Success(ctx, nil)
|
||||
return
|
||||
}
|
||||
|
||||
func RefreshPublish() error {
|
||||
var resp *cast.RefreshWorkListResp
|
||||
var err error
|
||||
resp, err = service.CastProvider.RefreshWorkList(context.Background(), &cast.RefreshWorkListReq{PublishStatus: 1})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, workInfo := range resp.Data {
|
||||
if workInfo.ProfileKey == "" {
|
||||
continue
|
||||
}
|
||||
for _, platformInfo := range workInfo.PlatformInfoData {
|
||||
if platformInfo.PublishMediaID == "" {
|
||||
continue
|
||||
}
|
||||
var infoReq = &cast.UpdateWorkPlatformInfoReq{
|
||||
PlatformInfoData: make([]*cast.PlatformInfo, 0),
|
||||
}
|
||||
//DM单独刷新
|
||||
if platformInfo.PlatformID == cast.PlatformIDENUM_DM {
|
||||
var dmData []byte
|
||||
_, dmData, err = utils.GetUrl(fmt.Sprintf("https://api.dailymotion.com/video/%s?fields=id,title,url,published,private", platformInfo.PublishMediaID),
|
||||
map[string]string{"Authorization": "Bearer " + platformInfo.Token}, config.AppConfig.System.ProxyUrl)
|
||||
if err != nil {
|
||||
infoReq.PlatformInfoData = append(infoReq.PlatformInfoData, &cast.PlatformInfo{
|
||||
WorkUuid: workInfo.WorkUuid,
|
||||
MediaAccountUuid: "",
|
||||
PlatformID: uint32(platformInfo.PlatformID),
|
||||
PublishType: 2,
|
||||
PublishResp: err.Error(),
|
||||
PublishMediaId: platformInfo.PublishMediaID,
|
||||
PublishStatus: cast.PublishStatusENUM_PublishMediaStatus_EXCEPTION,
|
||||
Remark: "",
|
||||
PlatformUuid: platformInfo.PlatformUuid,
|
||||
})
|
||||
_, _ = service.CastProvider.UpdateWorkPlatformInfo(context.Background(), infoReq)
|
||||
continue
|
||||
}
|
||||
var dmPost *modelCast.DMPost
|
||||
_ = json.Unmarshal(dmData, &dmPost)
|
||||
if dmPost.Published {
|
||||
infoReq.PlatformInfoData = append(infoReq.PlatformInfoData, &cast.PlatformInfo{
|
||||
WorkUuid: workInfo.WorkUuid,
|
||||
MediaAccountUuid: "",
|
||||
PlatformID: uint32(platformInfo.PlatformID),
|
||||
PublishType: 2,
|
||||
PublishResp: string(dmData),
|
||||
PublishMediaId: platformInfo.PublishMediaID,
|
||||
PublishStatus: cast.PublishStatusENUM_PublishMediaStatus_DONE,
|
||||
Remark: "",
|
||||
PlatformUuid: platformInfo.PlatformUuid,
|
||||
})
|
||||
_, _ = service.CastProvider.UpdateWorkPlatformInfo(context.Background(), infoReq)
|
||||
} else {
|
||||
infoReq.PlatformInfoData = append(infoReq.PlatformInfoData, &cast.PlatformInfo{
|
||||
WorkUuid: workInfo.WorkUuid,
|
||||
MediaAccountUuid: "",
|
||||
PlatformID: uint32(platformInfo.PlatformID),
|
||||
PublishType: 2,
|
||||
PublishResp: string(dmData),
|
||||
PublishMediaId: platformInfo.PublishMediaID,
|
||||
PublishStatus: cast.PublishStatusENUM_PublishMediaStatus_FAIL,
|
||||
Remark: "",
|
||||
PlatformUuid: platformInfo.PlatformUuid,
|
||||
})
|
||||
_, _ = service.CastProvider.UpdateWorkPlatformInfo(context.Background(), infoReq)
|
||||
}
|
||||
continue
|
||||
}
|
||||
postResp, _err := service.AyrshareProvider.GetPost(context.Background(), &aryshare.GetPostRequest{
|
||||
Id: platformInfo.PublishMediaID,
|
||||
ProfileKey: workInfo.ProfileKey,
|
||||
})
|
||||
|
||||
if _err != nil {
|
||||
zap.L().Error("GetPost err", zap.Error(_err))
|
||||
go func(v *cast.RefreshWorkListResp_Info) {
|
||||
_, _ = service.CastProvider.UpdateWorkPublishLog(context.Background(), &cast.UpdateWorkPublishLogReq{
|
||||
WorkUuid: v.WorkUuid,
|
||||
Detail: _err.Error(),
|
||||
Action: "get",
|
||||
})
|
||||
}(workInfo)
|
||||
infoReq.PlatformInfoData = append(infoReq.PlatformInfoData, &cast.PlatformInfo{
|
||||
WorkUuid: workInfo.WorkUuid,
|
||||
MediaAccountUuid: "",
|
||||
PlatformID: uint32(platformInfo.PlatformID),
|
||||
PublishType: 2,
|
||||
PublishResp: _err.Error(),
|
||||
PublishMediaId: platformInfo.PublishMediaID,
|
||||
PublishStatus: cast.PublishStatusENUM_PublishMediaStatus_EXCEPTION,
|
||||
Remark: "",
|
||||
PlatformUuid: platformInfo.PlatformUuid,
|
||||
})
|
||||
_, _ = service.CastProvider.UpdateWorkPlatformInfo(context.Background(), infoReq)
|
||||
continue
|
||||
}
|
||||
if postResp.Errors != nil {
|
||||
|
||||
}
|
||||
var postBytes []byte
|
||||
postBytes, _ = json.Marshal(postResp)
|
||||
if len(postResp.PostIds) == 0 || len(postResp.Errors) > 0 {
|
||||
infoReq.PlatformInfoData = append(infoReq.PlatformInfoData, &cast.PlatformInfo{
|
||||
WorkUuid: workInfo.WorkUuid,
|
||||
MediaAccountUuid: "",
|
||||
PlatformID: uint32(platformInfo.PlatformID),
|
||||
PublishType: 2,
|
||||
PublishResp: string(postBytes),
|
||||
PublishMediaId: platformInfo.PublishMediaID,
|
||||
PublishStatus: cast.PublishStatusENUM_PublishMediaStatus_FAIL,
|
||||
Remark: "",
|
||||
PlatformUuid: platformInfo.PlatformUuid,
|
||||
})
|
||||
_, _ = service.CastProvider.UpdateWorkPlatformInfo(context.Background(), infoReq)
|
||||
}
|
||||
if len(postResp.PostIds) > 0 {
|
||||
for _, vv := range postResp.PostIds {
|
||||
if vv.Status == "pending" || vv.Status == "awaiting approval" {
|
||||
continue
|
||||
}
|
||||
var publishStatus cast.PublishStatusENUM
|
||||
if vv.Status == "deleted" || vv.Status == "error" {
|
||||
publishStatus = cast.PublishStatusENUM_PublishMediaStatus_FAIL
|
||||
}
|
||||
if vv.Status == "success" {
|
||||
publishStatus = cast.PublishStatusENUM_PublishMediaStatus_DONE
|
||||
}
|
||||
// 不知道TikTok为什么会有这样的数据,as文档没说 特殊判断一下
|
||||
if vv.Platform == "tiktok" && vv.Status == "success" && vv.Id == "pending" {
|
||||
publishStatus = cast.PublishStatusENUM_PublishMediaStatus_ING
|
||||
}
|
||||
platformID := modelCast.NamePlatformIDKv[vv.Platform]
|
||||
infoReq.PlatformInfoData = append(infoReq.PlatformInfoData, &cast.PlatformInfo{
|
||||
WorkUuid: workInfo.WorkUuid,
|
||||
MediaAccountUuid: "",
|
||||
PlatformID: platformID,
|
||||
PublishType: 2,
|
||||
PublishResp: string(postBytes),
|
||||
PublishMediaId: platformInfo.PublishMediaID,
|
||||
PublishStatus: publishStatus,
|
||||
Remark: "",
|
||||
PlatformUuid: platformInfo.PlatformUuid,
|
||||
})
|
||||
}
|
||||
_, _ = service.CastProvider.UpdateWorkPlatformInfo(context.Background(), infoReq)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
52
pkg/service/check/image.go
Normal file
52
pkg/service/check/image.go
Normal file
@ -0,0 +1,52 @@
|
||||
package check
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"time"
|
||||
|
||||
pkgSecurity "fonchain-fiee/pkg/security"
|
||||
|
||||
"github.com/fonchain/utils/security"
|
||||
)
|
||||
|
||||
// ImageCheckUrlValid 图片黄疸检测 true 是通过
|
||||
func ImageCheckUrlValid(imgUrl string) (bool, error) {
|
||||
resp, err := pkgSecurity.ImageScanner.ScanImageByURL(imgUrl, fmt.Sprint(time.Now().UnixMicro()), security.BaselineCheckGlobal)
|
||||
if err != nil {
|
||||
err = errors.New("图片检测请求失败")
|
||||
return false, err
|
||||
}
|
||||
if resp.Code != 200 {
|
||||
err = errors.New("图片检测失败,错误码")
|
||||
return false, err
|
||||
}
|
||||
if len(resp.Data) == 0 || len(resp.Data[0].Results) == 0 {
|
||||
return false, errors.New("图片检测结果异常")
|
||||
}
|
||||
riskLevel := resp.Data[0].Results[0].RiskLevel
|
||||
if *riskLevel == "none" {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func ImageCheckByte(file *multipart.FileHeader) (bool, error) {
|
||||
//imageScanner, err := security.NewImageScanner(&security.Config{
|
||||
// RAMAccessKeyID: "LTAI5tNBzbeEbG1yCitvHsMb",
|
||||
// RAMAccessKeySecret: "G1xAUB8G6WDVo0SLr6DJaJjNWIlpmO",
|
||||
// RAMRoleArn: "acs:ram::5828544250383902:role/content-secret",
|
||||
// Region: "ap-southeast-1",
|
||||
// Endpoint: "green-cip.ap-southeast-1.aliyuncs.com",
|
||||
// TempAccessKeyID: "",
|
||||
// TempAccessKeySecret: "",
|
||||
// SecurityToken: "",
|
||||
//})
|
||||
//if err != nil {
|
||||
// return false, err
|
||||
//}
|
||||
//resp, err := imageScanner.ScanImageByFileByte(file, fmt.Sprint(time.Now().UnixMicro()), security.BaselineCheckGlobal)
|
||||
//fmt.Println(resp)
|
||||
return false, nil
|
||||
}
|
||||
@ -3,9 +3,9 @@ package file
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"fonchain-fiee/api/files"
|
||||
"fonchain-fiee/pkg/service"
|
||||
"fonchain-fiee/pkg/service/bundle/common"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -24,7 +24,7 @@ func Raw(ctx *gin.Context) {
|
||||
w.Header().Set("Cache-Control", "private")
|
||||
rs, err := newGrpcReaderSeeker(getUserSpacePath(ctx), ctx.Param("path"))
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.FileListFailed))
|
||||
return
|
||||
}
|
||||
if r.URL.Query().Get("inline") == "true" {
|
||||
@ -40,6 +40,8 @@ func List(ctx *gin.Context) {
|
||||
path := ctx.DefaultQuery("path", "/")
|
||||
sortBy := ctx.DefaultQuery("sortBy", "name")
|
||||
sortAsc, _ := strconv.ParseBool(ctx.DefaultQuery("sortAsc", "true"))
|
||||
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "100000"))
|
||||
resp, err := service.FilesProvider.List(ctx, &files.FileListReq{
|
||||
Path: path,
|
||||
UserSpacePath: getUserSpacePath(ctx),
|
||||
@ -47,9 +49,11 @@ func List(ctx *gin.Context) {
|
||||
By: sortBy,
|
||||
Asc: sortAsc,
|
||||
},
|
||||
Page: int32(page),
|
||||
PageSize: int32(pageSize),
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.FileListFailed))
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
@ -62,7 +66,7 @@ func Usage(ctx *gin.Context) {
|
||||
UserSpacePath: getUserSpacePath(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.FileUsageFailed))
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
@ -74,7 +78,7 @@ func Info(ctx *gin.Context) {
|
||||
UserSpacePath: getUserSpacePath(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.GetFileInfoFailed))
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
@ -89,7 +93,7 @@ func Create(ctx *gin.Context) {
|
||||
req.UserSpacePath = getUserSpacePath(ctx)
|
||||
resp, err := service.FilesProvider.Create(ctx, &req)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.CreateFileFailed))
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
@ -101,7 +105,7 @@ func Delete(ctx *gin.Context) {
|
||||
UserSpacePath: getUserSpacePath(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.DeleteFileFailed))
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
@ -114,7 +118,7 @@ func Search(ctx *gin.Context) {
|
||||
Query: ctx.Query("query"),
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.SearchFileFailed))
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
@ -128,7 +132,7 @@ func Upload(ctx *gin.Context) {
|
||||
}
|
||||
b, err := io.ReadAll(ctx.Request.Body)
|
||||
if !ok {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.ERROR_OPEN_FILE))
|
||||
return
|
||||
}
|
||||
resp, err := service.FilesProvider.Upload(ctx, &files.UploadReq{
|
||||
@ -137,7 +141,7 @@ func Upload(ctx *gin.Context) {
|
||||
Content: b,
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.UploadFileFailed))
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
@ -152,7 +156,7 @@ func TusCreate(ctx *gin.Context) {
|
||||
req.UserSpacePath = getUserSpacePath(ctx)
|
||||
resp, err := service.FilesProvider.TusCreate(ctx, &req)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.TusCreateFailed))
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
@ -166,24 +170,24 @@ func TusUpload(ctx *gin.Context) {
|
||||
}
|
||||
uploadOffset, err := getUploadOffset(ctx.Request)
|
||||
if err != nil {
|
||||
service.Error(ctx, fmt.Errorf("invalid upload offset: %w", err))
|
||||
service.Error(ctx, errors.New(common.ERROR_OPEN_FILE))
|
||||
return
|
||||
}
|
||||
mf, err := ctx.MultipartForm()
|
||||
if err != nil {
|
||||
service.Error(ctx, fmt.Errorf("invalid upload offset: %w", err))
|
||||
service.Error(ctx, errors.New(common.ERROR_OPEN_FILE))
|
||||
return
|
||||
}
|
||||
f, err := mf.File["file"][0].Open()
|
||||
if err != nil {
|
||||
service.Error(ctx, fmt.Errorf("invalid upload offset: %w", err))
|
||||
service.Error(ctx, errors.New(common.ERROR_OPEN_FILE))
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
b, err := io.ReadAll(f)
|
||||
// b, err := io.ReadAll(ctx.Request.Body)
|
||||
if !ok {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.ERROR_OPEN_FILE))
|
||||
return
|
||||
}
|
||||
resp, err := service.FilesProvider.TusUpload(ctx, &files.TusUploadReq{
|
||||
@ -193,7 +197,7 @@ func TusUpload(ctx *gin.Context) {
|
||||
UserSpacePath: getUserSpacePath(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.TusUploadFailed))
|
||||
return
|
||||
}
|
||||
ctx.Writer.Header().Set("Upload-Offset", strconv.FormatInt(resp.UploadOffset, 10))
|
||||
@ -212,7 +216,7 @@ func Preview(ctx *gin.Context) {
|
||||
Size: uint32(size),
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.PreviewFileFailed))
|
||||
return
|
||||
}
|
||||
ctx.Writer.Header().Set("Cache-Control", "private")
|
||||
@ -228,7 +232,7 @@ func Action(ctx *gin.Context) {
|
||||
req.UserSpacePath = getUserSpacePath(ctx)
|
||||
resp, err := service.FilesProvider.Action(ctx, &req)
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.ActionFailed))
|
||||
return
|
||||
}
|
||||
service.Success(ctx, resp)
|
||||
@ -245,12 +249,12 @@ func DirDownload(ctx *gin.Context) {
|
||||
UserSpacePath: getUserSpacePath(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.DirDownloadFailed))
|
||||
return
|
||||
}
|
||||
header, err := stream.Header()
|
||||
if err != nil {
|
||||
service.Error(ctx, err)
|
||||
service.Error(ctx, errors.New(common.DirDownloadFailed))
|
||||
return
|
||||
}
|
||||
|
||||
@ -267,7 +271,7 @@ func DirDownload(ctx *gin.Context) {
|
||||
func getUploadOffset(r *http.Request) (int64, error) {
|
||||
uploadOffset, err := strconv.ParseInt(r.Header.Get("Upload-Offset"), 10, 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid upload offset: %w", err)
|
||||
return 0, errors.New(common.InvalidUploadOffset)
|
||||
}
|
||||
return uploadOffset, nil
|
||||
}
|
||||
|
||||
140
pkg/service/import/generate.go
Normal file
140
pkg/service/import/generate.go
Normal file
@ -0,0 +1,140 @@
|
||||
package imports
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 配置结构增强
|
||||
type Aiconfig struct {
|
||||
APIKey string
|
||||
BaseURL string
|
||||
Image2ImageURL string
|
||||
TextGenerationURL string
|
||||
TextToImageURL string
|
||||
TextToImageModel string
|
||||
TaskQueryURL string
|
||||
ImageModel string
|
||||
TextModel string
|
||||
DefaultSize string
|
||||
Timeout int
|
||||
SaveDir string
|
||||
MaxTokens int
|
||||
Temperature float64
|
||||
TopP float64
|
||||
}
|
||||
|
||||
// 完整的AI生成器
|
||||
type AiGenerator struct {
|
||||
cfg Aiconfig
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultAPIKey = "sk-5ae9df5d3bcf4755ad5d12012058a2e7"
|
||||
DefaultBaseURL = "https://dashscope.aliyuncs.com"
|
||||
DefaultTextToImageURL = "/api/v1/services/aigc/text2image/image-synthesis" //文生图
|
||||
DefaultTextToImageModel = "wan2.5-t2i-preview"
|
||||
DefaultImage2ImageURL = "/api/v1/services/aigc/image2image/image-synthesis" //图生图
|
||||
DefaultImageModel = "wan2.5-i2i-preview"
|
||||
DefaultTextGenerationURL = "/api/v1/services/aigc/text-generation/generation" //文生文
|
||||
DefaultTextModel = "qwen-turbo"
|
||||
DefaultSize = "1024x1024"
|
||||
DefaultTaskQueryURL = "/api/v1/tasks"
|
||||
|
||||
DefaultTimeout = 30
|
||||
DefaultMaxTokens = 2000
|
||||
DefaultTemperature = 0.8
|
||||
DefaultTopP = 0.9
|
||||
)
|
||||
|
||||
func NewAiGenerator() *AiGenerator {
|
||||
cfg := &Aiconfig{
|
||||
APIKey: DefaultAPIKey,
|
||||
BaseURL: DefaultBaseURL,
|
||||
Image2ImageURL: DefaultImage2ImageURL,
|
||||
TextGenerationURL: DefaultTextGenerationURL,
|
||||
TextToImageURL: DefaultTextToImageURL,
|
||||
TextToImageModel: DefaultTextToImageModel,
|
||||
TaskQueryURL: DefaultTaskQueryURL,
|
||||
ImageModel: DefaultImageModel,
|
||||
TextModel: DefaultTextModel,
|
||||
DefaultSize: DefaultSize,
|
||||
Timeout: DefaultTimeout,
|
||||
MaxTokens: DefaultMaxTokens,
|
||||
Temperature: DefaultTemperature,
|
||||
TopP: DefaultTopP,
|
||||
}
|
||||
|
||||
return &AiGenerator{
|
||||
cfg: *cfg,
|
||||
client: &http.Client{
|
||||
Timeout: time.Duration(cfg.Timeout) * time.Second,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// 任务结果--------------------------------------------------------------------------
|
||||
|
||||
// ImageGenerationResponse 图片生成响应
|
||||
type ImageGenerationResponse struct {
|
||||
RequestID string `json:"request_id"`
|
||||
Output Output `json:"output"`
|
||||
Usage Usage `json:"usage"`
|
||||
}
|
||||
|
||||
type Output struct {
|
||||
TaskID string `json:"task_id"`
|
||||
TaskStatus string `json:"task_status"`
|
||||
SubmitTime string `json:"submit_time"`
|
||||
ScheduledTime string `json:"scheduled_time"`
|
||||
EndTime string `json:"end_time"`
|
||||
Results []Result `json:"results"`
|
||||
TaskMetrics TaskMetrics `json:"task_metrics"`
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
URL string `json:"url,omitempty"`
|
||||
Code string `json:"code,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type TaskMetrics struct {
|
||||
Total int `json:"TOTAL"`
|
||||
Succeeded int `json:"SUCCEEDED"`
|
||||
Failed int `json:"FAILED"`
|
||||
}
|
||||
|
||||
type Usage struct {
|
||||
ImageCount int `json:"image_count"`
|
||||
}
|
||||
|
||||
func (g *AiGenerator) GetTaskDetail(taskID string) (*ImageGenerationResponse, error) {
|
||||
url := fmt.Sprintf("%s/api/v1/tasks/%s", g.cfg.BaseURL, taskID)
|
||||
httpReq, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
httpReq.Header.Set("Authorization", "Bearer "+g.cfg.APIKey)
|
||||
httpReq.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := g.client.Do(httpReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("API错误: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
var imageGenerationResponse ImageGenerationResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&imageGenerationResponse); err != nil {
|
||||
return nil, fmt.Errorf("任务详情解析失败: %v", err)
|
||||
}
|
||||
|
||||
return &imageGenerationResponse, nil
|
||||
}
|
||||
92
pkg/service/import/generateImageToImage.go
Normal file
92
pkg/service/import/generateImageToImage.go
Normal file
@ -0,0 +1,92 @@
|
||||
package imports
|
||||
|
||||
//
|
||||
//import (
|
||||
// "bytes"
|
||||
// "encoding/json"
|
||||
// "fmt"
|
||||
// "net/http"
|
||||
//)
|
||||
//
|
||||
////------------------------------------------图生图
|
||||
//
|
||||
//type Image2ImageRequest struct {
|
||||
// Model string `json:"model"`
|
||||
// Input ImageInput `json:"input"`
|
||||
// Params ImageParams `json:"parameters"`
|
||||
//}
|
||||
//
|
||||
//type ImageInput struct {
|
||||
// Images []string `json:"images"`
|
||||
// Prompt string `json:"prompt"` // 可选的条件文本
|
||||
//}
|
||||
//
|
||||
//type ImageParams struct {
|
||||
// Size string `json:"size,omitempty"` // 输出尺寸
|
||||
// Strength float64 `json:"strength"` // 重绘强度0-1
|
||||
// N int `json:"n,omitempty"` // 生成数量
|
||||
//}
|
||||
//
|
||||
//type ImageResponse struct {
|
||||
// Output struct {
|
||||
// TaskID string `json:"task_id"`
|
||||
// Results []struct {
|
||||
// URL string `json:"url"`
|
||||
// } `json:"results"`
|
||||
// } `json:"output"`
|
||||
// RequestID string `json:"request_id"`
|
||||
//}
|
||||
//
|
||||
//// Image2image 图生图
|
||||
//func (g *AiGenerator) Image2image(imagePath string, prompt string, strength float64, size string, n int) (*ImageResponse, error) {
|
||||
// if g.cfg.APIKey == "" {
|
||||
// return nil, fmt.Errorf("API密钥未配置")
|
||||
// }
|
||||
//
|
||||
// // 构建请求
|
||||
// req := Image2ImageRequest{
|
||||
// Model: g.cfg.ImageModel,
|
||||
// Input: ImageInput{
|
||||
// Images: []string{imagePath},
|
||||
// Prompt: prompt,
|
||||
// },
|
||||
// Params: ImageParams{
|
||||
// Size: size,
|
||||
// Strength: strength,
|
||||
// N: n,
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// url := g.cfg.BaseURL + g.cfg.Image2ImageURL
|
||||
// jsonData, err := json.Marshal(req)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// httpReq, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// httpReq.Header.Set("Content-Type", "application/json")
|
||||
// httpReq.Header.Set("Authorization", "Bearer "+g.cfg.APIKey)
|
||||
// httpReq.Header.Set("X-DashScope-Async", "enable")
|
||||
//
|
||||
// resp, err := g.client.Do(httpReq)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// defer resp.Body.Close()
|
||||
//
|
||||
// // 解析响应
|
||||
// var result ImageResponse
|
||||
// if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
// return nil, fmt.Errorf("响应解析失败: %v", err)
|
||||
// }
|
||||
//
|
||||
// if resp.StatusCode != http.StatusOK {
|
||||
// return nil, fmt.Errorf("API错误: %d", resp.StatusCode)
|
||||
// }
|
||||
//
|
||||
// return &result, nil
|
||||
//}
|
||||
346
pkg/service/import/generateImageToText.go
Normal file
346
pkg/service/import/generateImageToText.go
Normal file
@ -0,0 +1,346 @@
|
||||
package imports
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 使用OpenAI兼容格式
|
||||
type ChatCompletionRequest struct {
|
||||
Model string `json:"model"`
|
||||
Messages []ChatMessage `json:"messages"`
|
||||
MaxTokens int `json:"max_tokens,omitempty"`
|
||||
Temperature float64 `json:"temperature,omitempty"`
|
||||
TopP float64 `json:"top_p,omitempty"`
|
||||
TopK float64 `json:"top_k,omitempty"`
|
||||
PresencePenalty float64 `json:"presence_penalty,omitempty"`
|
||||
Seed int `json:"seed,omitempty"`
|
||||
}
|
||||
|
||||
type ChatMessage struct {
|
||||
Role string `json:"role"`
|
||||
Content []Content `json:"content"`
|
||||
}
|
||||
|
||||
type Content struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text,omitempty"`
|
||||
ImageURL struct {
|
||||
URL string `json:"url"`
|
||||
} `json:"image_url,omitempty"`
|
||||
}
|
||||
|
||||
type ChatCompletionResponse struct {
|
||||
Choices []struct {
|
||||
Message struct {
|
||||
Content string `json:"content"`
|
||||
} `json:"message"`
|
||||
} `json:"choices"`
|
||||
Error struct {
|
||||
Message string `json:"message"`
|
||||
} `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// 图生文:根据图片生成标题和内容
|
||||
func (g *AiGenerator) GenerateTitleAndContentFromImage(imageURL, titleRequire, contentRequire string) (string, string, error) {
|
||||
// 构建提示词
|
||||
prompt := fmt.Sprintf(`请分析这张图片并生成内容:
|
||||
|
||||
图片分析要求:
|
||||
1. 标题要求:%s
|
||||
2. 内容要求:%s
|
||||
|
||||
请严格按照以下格式返回,不要有任何额外文字:
|
||||
标题:{生成的标题}
|
||||
内容:{生成的内容}`, titleRequire, contentRequire)
|
||||
|
||||
// 发送聊天请求
|
||||
response, err := g.chatWithImage(imageURL, prompt)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
title, content := parseTitleAndContent(response)
|
||||
return title, content, nil
|
||||
}
|
||||
|
||||
func (g *AiGenerator) chatWithImage(imageURL, prompt string) (string, error) {
|
||||
reqBody := ChatCompletionRequest{
|
||||
Model: "qwen3-vl-plus",
|
||||
Messages: []ChatMessage{
|
||||
{
|
||||
Role: "user",
|
||||
Content: []Content{
|
||||
{
|
||||
Type: "image_url",
|
||||
ImageURL: struct {
|
||||
URL string `json:"url"`
|
||||
}{
|
||||
URL: imageURL,
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: "text",
|
||||
Text: prompt,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MaxTokens: 2000,
|
||||
Temperature: 1.5,
|
||||
TopP: 0.9,
|
||||
TopK: 99,
|
||||
PresencePenalty: 1.5,
|
||||
Seed: generateSeed(),
|
||||
}
|
||||
|
||||
// 使用兼容模式接口
|
||||
url := g.cfg.BaseURL + "/compatible-mode/v1/chat/completions"
|
||||
|
||||
jsonData, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("JSON序列化失败: %v", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("创建请求失败: %v", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer "+g.cfg.APIKey)
|
||||
req.Header.Set("X-DashScope-Session-Id", fmt.Sprintf("session-%d", time.Now().UnixNano()))
|
||||
|
||||
resp, err := g.client.Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("API请求失败: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 读取响应体
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("读取响应失败: %v", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("API错误: %d, 响应: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
var result ChatCompletionResponse
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
return "", fmt.Errorf("JSON解析失败: %v, 响应: %s", err, string(body))
|
||||
}
|
||||
|
||||
// 检查API错误
|
||||
if result.Error.Message != "" {
|
||||
return "", fmt.Errorf("API返回错误: %s", result.Error.Message)
|
||||
}
|
||||
|
||||
if len(result.Choices) == 0 {
|
||||
return "", errors.New("AI未生成有效响应")
|
||||
}
|
||||
|
||||
response := strings.TrimSpace(result.Choices[0].Message.Content)
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func generateSeed() int {
|
||||
rand.Seed(time.Now().UnixNano()) // 使用当前时间戳作为种子
|
||||
return rand.Intn(2147483647) // 生成一个在 [0, 231-1] 范围内的随机数
|
||||
}
|
||||
|
||||
// 解析标题和内容
|
||||
func parseTitleAndContent(response string) (string, string) {
|
||||
var title, content string
|
||||
|
||||
lines := strings.Split(response, "\n")
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasPrefix(line, "标题:") {
|
||||
title = strings.TrimPrefix(line, "标题:")
|
||||
} else if strings.HasPrefix(line, "内容:") {
|
||||
content = strings.TrimPrefix(line, "内容:")
|
||||
}
|
||||
}
|
||||
|
||||
return strings.TrimSpace(title), strings.TrimSpace(content)
|
||||
}
|
||||
|
||||
// 文本生成文本(聊天模式)
|
||||
func (g *AiGenerator) GenerateTitleAndContentFromText(titleRequire, contentRequire string) (string, string, error) {
|
||||
// 构建提示词
|
||||
prompt := fmt.Sprintf(`请根据以下要求生成内容:
|
||||
|
||||
生成要求:
|
||||
1. 标题要求:%s
|
||||
2. 内容要求:%s
|
||||
|
||||
请严格按照以下格式返回,不要有任何额外文字:
|
||||
标题:{生成的标题}
|
||||
内容:{生成的内容}`,
|
||||
titleRequire,
|
||||
contentRequire,
|
||||
)
|
||||
|
||||
// 发送聊天请求
|
||||
response, err := g.chatWithText(prompt)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
title, content := parseTitleAndContent(response)
|
||||
return title, content, nil
|
||||
}
|
||||
|
||||
// 文本聊天(纯文本生成)
|
||||
func (g *AiGenerator) chatWithText(prompt string) (string, error) {
|
||||
reqBody := ChatCompletionRequest{
|
||||
Model: "qwen-max", // 使用文本模型
|
||||
Messages: []ChatMessage{
|
||||
{
|
||||
Role: "user",
|
||||
Content: []Content{
|
||||
{
|
||||
Type: "text",
|
||||
Text: prompt,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MaxTokens: 2000,
|
||||
Temperature: 1.9,
|
||||
TopP: 1.0,
|
||||
TopK: 99,
|
||||
PresencePenalty: 1.0,
|
||||
Seed: generateSeed(),
|
||||
}
|
||||
|
||||
url := g.cfg.BaseURL + "/compatible-mode/v1/chat/completions"
|
||||
jsonData, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("JSON序列化失败: %v", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("创建请求失败: %v", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer "+g.cfg.APIKey)
|
||||
req.Header.Set("X-DashScope-Session-Id", fmt.Sprintf("session-%d", time.Now().UnixNano()))
|
||||
|
||||
resp, err := g.client.Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("API请求失败: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("读取响应失败: %v", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("API错误: %d, 响应: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
var result ChatCompletionResponse
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
return "", fmt.Errorf("JSON解析失败: %v, 响应: %s", err, string(body))
|
||||
}
|
||||
|
||||
if result.Error.Message != "" {
|
||||
return "", fmt.Errorf("API返回错误: %s", result.Error.Message)
|
||||
}
|
||||
|
||||
if len(result.Choices) == 0 {
|
||||
return "", errors.New("AI未生成有效响应")
|
||||
}
|
||||
response := strings.TrimSpace(result.Choices[0].Message.Content)
|
||||
return response, nil
|
||||
}
|
||||
|
||||
//func (g *AiGenerator) GenerateImageFromText(prompt, size string, n int) (string, error) {
|
||||
// // 构建图片生成提示词
|
||||
// imagePrompt := fmt.Sprintf(`请根据以下描述生成图片:
|
||||
//
|
||||
//图片描述:%s
|
||||
//生成数量:%d张
|
||||
//图片尺寸:%s
|
||||
//
|
||||
//请直接生成图片,不要返回任何文字描述。`,
|
||||
// prompt, n, size)
|
||||
//
|
||||
// // 使用文生图API
|
||||
// result, err := g.TextToImage(imagePrompt, size, n)
|
||||
// if err != nil {
|
||||
// return "", err
|
||||
// }
|
||||
//
|
||||
// return result.Output.TaskID, nil
|
||||
//}
|
||||
|
||||
// 文本生成图像
|
||||
//func (g *AiGenerator) TextToImage(prompt, size string, n int) (ImageGenerationResponse, error) {
|
||||
// // 构建图像生成请求
|
||||
// reqBody := map[string]interface{}{
|
||||
// "prompt": prompt,
|
||||
// "n": n,
|
||||
// "size": size,
|
||||
// "response_format": "url", // 假设返回的格式为图像 URL,可以根据实际 API 调整
|
||||
// }
|
||||
//
|
||||
// // 使用图像生成接口
|
||||
// url := g.cfg.BaseURL + "/v1/images/generations"
|
||||
// jsonData, err := json.Marshal(reqBody)
|
||||
// if err != nil {
|
||||
// return ImageGenerationResponse{}, fmt.Errorf("JSON序列化失败: %v", err)
|
||||
// }
|
||||
//
|
||||
// req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||
// if err != nil {
|
||||
// return ImageGenerationResponse{}, fmt.Errorf("创建请求失败: %v", err)
|
||||
// }
|
||||
//
|
||||
// req.Header.Set("Content-Type", "application/json")
|
||||
// req.Header.Set("Authorization", "Bearer "+g.cfg.APIKey)
|
||||
//
|
||||
// resp, err := g.client.Do(req)
|
||||
// if err != nil {
|
||||
// return ImageGenerationResponse{}, fmt.Errorf("API请求失败: %v", err)
|
||||
// }
|
||||
// defer resp.Body.Close()
|
||||
//
|
||||
// // 读取响应体
|
||||
// body, err := io.ReadAll(resp.Body)
|
||||
// if err != nil {
|
||||
// return ImageGenerationResponse{}, fmt.Errorf("读取响应失败: %v", err)
|
||||
// }
|
||||
//
|
||||
// if resp.StatusCode != http.StatusOK {
|
||||
// return ImageGenerationResponse{}, fmt.Errorf("API错误: %d, 响应: %s", resp.StatusCode, string(body))
|
||||
// }
|
||||
//
|
||||
// // 解析图像生成响应
|
||||
// var result ImageGenerationResponse
|
||||
// if err := json.Unmarshal(body, &result); err != nil {
|
||||
// return ImageGenerationResponse{}, fmt.Errorf("JSON解析失败: %v, 响应: %s", err, string(body))
|
||||
// }
|
||||
//
|
||||
// if len(result.Data) == 0 {
|
||||
// return ImageGenerationResponse{}, errors.New("未生成任何图像")
|
||||
// }
|
||||
//
|
||||
// return result, nil
|
||||
//}
|
||||
100
pkg/service/import/generateText.go
Normal file
100
pkg/service/import/generateText.go
Normal file
@ -0,0 +1,100 @@
|
||||
package imports
|
||||
|
||||
//
|
||||
//import (
|
||||
// "bytes"
|
||||
// "encoding/json"
|
||||
// "fmt"
|
||||
// "net/http"
|
||||
//)
|
||||
//
|
||||
//// ----------------------------文生文
|
||||
//
|
||||
//// 文本生成请求结构
|
||||
//type TextGenerationRequest struct {
|
||||
// Model string `json:"model"`
|
||||
// Input TextInput `json:"input"`
|
||||
// Params TextParams `json:"parameters"`
|
||||
//}
|
||||
//
|
||||
//type TextInput struct {
|
||||
// Messages []Message `json:"messages"`
|
||||
//}
|
||||
//
|
||||
//type TextParams struct {
|
||||
// ResultFormat string `json:"result_format,omitempty"` // 结果格式
|
||||
// MaxTokens int `json:"max_tokens,omitempty"` // 最大token数
|
||||
// Temperature float64 `json:"temperature,omitempty"` // 温度参数
|
||||
// TopP float64 `json:"top_p,omitempty"` // 核采样参数
|
||||
//}
|
||||
//
|
||||
//type TextResponse struct {
|
||||
// Output struct {
|
||||
// Text string `json:"text"`
|
||||
// FinishReason string `json:"finish_reason"`
|
||||
// } `json:"output"`
|
||||
// Usage struct {
|
||||
// InputTokens int `json:"input_tokens"`
|
||||
// OutputTokens int `json:"output_tokens"`
|
||||
// TotalTokens int `json:"total_tokens"`
|
||||
// } `json:"usage"`
|
||||
// RequestID string `json:"request_id"`
|
||||
//}
|
||||
//
|
||||
//// GenerateText 生成文本
|
||||
//func (g *AiGenerator) GenerateText(prompt string) (*TextResponse, error) {
|
||||
// if g.cfg.APIKey == "" {
|
||||
// return nil, fmt.Errorf("API密钥未配置")
|
||||
// }
|
||||
//
|
||||
// // 构建请求
|
||||
// req := TextGenerationRequest{
|
||||
// Model: g.cfg.TextModel,
|
||||
// Input: TextInput{
|
||||
// Messages: []Message{
|
||||
// {
|
||||
// Role: "user",
|
||||
// Content: prompt,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// Params: TextParams{
|
||||
// ResultFormat: "message",
|
||||
// MaxTokens: g.cfg.MaxTokens,
|
||||
// Temperature: g.cfg.Temperature,
|
||||
// TopP: g.cfg.TopP,
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// url := g.cfg.BaseURL + g.cfg.TextGenerationURL
|
||||
// jsonData, err := json.Marshal(req)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// httpReq, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// httpReq.Header.Set("Content-Type", "application/json")
|
||||
// httpReq.Header.Set("Authorization", "Bearer "+g.cfg.APIKey)
|
||||
//
|
||||
// resp, err := g.client.Do(httpReq)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// defer resp.Body.Close()
|
||||
//
|
||||
// // 解析响应
|
||||
// var result TextResponse
|
||||
// if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
// return nil, fmt.Errorf("文本生成响应解析失败: %v", err)
|
||||
// }
|
||||
//
|
||||
// if resp.StatusCode != http.StatusOK {
|
||||
// return nil, fmt.Errorf("API错误: %d", resp.StatusCode)
|
||||
// }
|
||||
//
|
||||
// return &result, nil
|
||||
//}
|
||||
120
pkg/service/import/generateTextToImage.go
Normal file
120
pkg/service/import/generateTextToImage.go
Normal file
@ -0,0 +1,120 @@
|
||||
package imports
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// 修正后的文生图请求结构
|
||||
type TextToImageRequest struct {
|
||||
Model string `json:"model"`
|
||||
Input TextToImageInput `json:"input"`
|
||||
Params TextToImageParameters `json:"parameters"` // 修正字段名
|
||||
}
|
||||
|
||||
type TextToImageInput struct {
|
||||
Prompt string `json:"prompt"`
|
||||
NegativePrompt string `json:"negative_prompt"`
|
||||
}
|
||||
|
||||
type TextToImageParameters struct {
|
||||
Size string `json:"size,omitempty"`
|
||||
N int `json:"n,omitempty"`
|
||||
NegativePrompt string `json:"negative_prompt,omitempty"`
|
||||
Steps int `json:"steps,omitempty"`
|
||||
Scale float64 `json:"scale,omitempty"`
|
||||
Style string `json:"style,omitempty"`
|
||||
Seed int `json:"seed,omitempty"`
|
||||
Temperature float64 `json:"temperature,omitempty"`
|
||||
TopP float64 `json:"top_p,omitempty"`
|
||||
}
|
||||
|
||||
type TextToImageResponse struct {
|
||||
Output struct {
|
||||
TaskID string `json:"task_id"`
|
||||
TaskStatus string `json:"task_status"` // 添加任务状态字段
|
||||
Results []struct {
|
||||
URL string `json:"url"`
|
||||
} `json:"results"`
|
||||
} `json:"output"`
|
||||
RequestID string `json:"request_id"`
|
||||
Code string `json:"code,omitempty"` // 错误代码
|
||||
Message string `json:"message,omitempty"` // 错误信息
|
||||
}
|
||||
|
||||
// 修正后的文生图函数
|
||||
func (g *AiGenerator) TextToImage(prompt string, size string, n int) (*TextToImageResponse, error) {
|
||||
if g.cfg.APIKey == "" {
|
||||
return nil, fmt.Errorf("API密钥未配置")
|
||||
}
|
||||
|
||||
// 构建请求
|
||||
req := TextToImageRequest{
|
||||
Model: g.cfg.TextToImageModel,
|
||||
Input: TextToImageInput{
|
||||
Prompt: prompt,
|
||||
NegativePrompt: "低质量、残缺、人物正脸、多余的手指、乱码字符和文字、比例不良丶场景以国内场景为主",
|
||||
//NegativePrompt: "人物正脸",
|
||||
},
|
||||
Params: TextToImageParameters{
|
||||
Size: size,
|
||||
N: n,
|
||||
Seed: generateSeed(),
|
||||
NegativePrompt: "低质量、残缺、人物正脸、多余的手指、乱码字符和文字、比例不良、场景以国内场景为主",
|
||||
},
|
||||
}
|
||||
|
||||
url := g.cfg.BaseURL + g.cfg.TextToImageURL
|
||||
jsonData, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("JSON序列化失败: %v", err)
|
||||
}
|
||||
|
||||
// 打印请求信息用于调试
|
||||
fmt.Printf("请求URL: %s\n", url)
|
||||
fmt.Printf("请求体: %s\n", string(jsonData))
|
||||
|
||||
httpReq, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建请求失败: %v", err)
|
||||
}
|
||||
|
||||
httpReq.Header.Set("Content-Type", "application/json")
|
||||
httpReq.Header.Set("Authorization", "Bearer "+g.cfg.APIKey)
|
||||
httpReq.Header.Set("X-DashScope-Async", "enable")
|
||||
|
||||
resp, err := g.client.Do(httpReq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("API请求失败: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 读取完整响应体
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("读取响应失败: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("响应状态: %d\n", resp.StatusCode)
|
||||
fmt.Printf("响应体: %s\n", string(body))
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("API错误: %d, 响应: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
var result TextToImageResponse
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("响应解析失败: %v, 原始响应: %s", err, string(body))
|
||||
}
|
||||
|
||||
// 检查任务状态
|
||||
if result.Output.TaskStatus == "FAILED" {
|
||||
return nil, fmt.Errorf("图片生成失败: %s", result)
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
116
pkg/service/import/generateTextToText.go
Normal file
116
pkg/service/import/generateTextToText.go
Normal file
@ -0,0 +1,116 @@
|
||||
package imports
|
||||
|
||||
//
|
||||
//import (
|
||||
// "bytes"
|
||||
// "encoding/json"
|
||||
// "fmt"
|
||||
// "io"
|
||||
// "net/http"
|
||||
//)
|
||||
//
|
||||
//// Message 结构体定义
|
||||
//type Message struct {
|
||||
// Role string `json:"role"`
|
||||
// Content string `json:"content"`
|
||||
//}
|
||||
//
|
||||
//// 同步文本生成请求
|
||||
//type SyncTextGenerationRequest struct {
|
||||
// Model string `json:"model"`
|
||||
// Input SyncTextInput `json:"input"`
|
||||
// Parameters SyncTextGenerationParams `json:"parameters"`
|
||||
//}
|
||||
//
|
||||
//type SyncTextInput struct {
|
||||
// Messages []Message `json:"messages"`
|
||||
//}
|
||||
//
|
||||
//type SyncTextGenerationParams struct {
|
||||
// ResultFormat string `json:"result_format,omitempty"`
|
||||
// MaxTokens int `json:"max_tokens,omitempty"`
|
||||
// Temperature float64 `json:"temperature,omitempty"`
|
||||
// TopP float64 `json:"top_p,omitempty"`
|
||||
// TopK int `json:"top_k,omitempty"`
|
||||
// Seed int64 `json:"seed,omitempty"`
|
||||
//}
|
||||
//
|
||||
//// 同步文本生成响应
|
||||
//type SyncTextGenerationResponse struct {
|
||||
// Output struct {
|
||||
// Choices []struct {
|
||||
// Message Message `json:"message"`
|
||||
// } `json:"choices"`
|
||||
// Text string `json:"text"`
|
||||
// FinishReason string `json:"finish_reason"`
|
||||
// } `json:"output"`
|
||||
// Usage struct {
|
||||
// InputTokens int `json:"input_tokens"`
|
||||
// OutputTokens int `json:"output_tokens"`
|
||||
// TotalTokens int `json:"total_tokens"`
|
||||
// } `json:"usage"`
|
||||
// RequestID string `json:"request_id"`
|
||||
//}
|
||||
//
|
||||
//// 同步文本生成URL
|
||||
//const DefaultSyncTextGenerationURL = "/api/v1/services/aigc/text-generation/generation"
|
||||
//
|
||||
//// 同步生成文本
|
||||
//func (g *AiGenerator) GenerateTextSync(prompt string) (*SyncTextGenerationResponse, error) {
|
||||
// if g.cfg.APIKey == "" {
|
||||
// return nil, fmt.Errorf("API密钥未配置")
|
||||
// }
|
||||
//
|
||||
// // 构建请求
|
||||
// req := SyncTextGenerationRequest{
|
||||
// Model: g.cfg.TextModel,
|
||||
// Input: SyncTextInput{
|
||||
// Messages: []Message{
|
||||
// {
|
||||
// Role: "user",
|
||||
// Content: prompt,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// Parameters: SyncTextGenerationParams{
|
||||
// ResultFormat: "message",
|
||||
// MaxTokens: g.cfg.MaxTokens,
|
||||
// Temperature: g.cfg.Temperature,
|
||||
// TopP: g.cfg.TopP,
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// url := g.cfg.BaseURL + DefaultSyncTextGenerationURL
|
||||
// jsonData, err := json.Marshal(req)
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("JSON序列化失败: %v", err)
|
||||
// }
|
||||
//
|
||||
// httpReq, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("创建请求失败: %v", err)
|
||||
// }
|
||||
//
|
||||
// httpReq.Header.Set("Content-Type", "application/json")
|
||||
// httpReq.Header.Set("Authorization", "Bearer "+g.cfg.APIKey)
|
||||
// // 注意:这里不设置 X-DashScope-Async 头,使用同步模式
|
||||
//
|
||||
// resp, err := g.client.Do(httpReq)
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("API请求失败: %v", err)
|
||||
// }
|
||||
// defer resp.Body.Close()
|
||||
//
|
||||
// if resp.StatusCode != http.StatusOK {
|
||||
// body, _ := io.ReadAll(resp.Body)
|
||||
// return nil, fmt.Errorf("API错误: %d, 响应: %s", resp.StatusCode, string(body))
|
||||
// }
|
||||
//
|
||||
// // 解析响应
|
||||
// var result SyncTextGenerationResponse
|
||||
// if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
// return nil, fmt.Errorf("响应解析失败: %v", err)
|
||||
// }
|
||||
//
|
||||
// return &result, nil
|
||||
//}
|
||||
118
pkg/service/import/imageContentGetResult.go
Normal file
118
pkg/service/import/imageContentGetResult.go
Normal file
@ -0,0 +1,118 @@
|
||||
package imports
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"fonchain-fiee/pkg/service"
|
||||
"fonchain-fiee/pkg/utils"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func ImageContentGetResult(c *gin.Context) {
|
||||
processor := GetBatchProcessorReadOnly()
|
||||
if processor == nil {
|
||||
service.Success(c, gin.H{
|
||||
"status": 0,
|
||||
"status_description": StatusMap[0],
|
||||
"message": "暂无执行中的任务",
|
||||
})
|
||||
return
|
||||
}
|
||||
currentStatus := processor.getStatus()
|
||||
switch currentStatus {
|
||||
case StatusIdle:
|
||||
service.Success(c, gin.H{
|
||||
"status": currentStatus,
|
||||
"status_description": StatusMap[currentStatus],
|
||||
"message": "暂无执行中的任务",
|
||||
})
|
||||
return
|
||||
|
||||
case StatusProcessing:
|
||||
completed, pending, total, completedTasks, failedTasks := processor.getTaskStatistics()
|
||||
service.Success(c, gin.H{
|
||||
"status": currentStatus,
|
||||
"status_description": StatusMap[currentStatus],
|
||||
"message": "任务执行中,请稍后",
|
||||
"total_tasks": total,
|
||||
"pending_tasks": pending,
|
||||
"failed_tasks": len(failedTasks), //失败数量
|
||||
"success_tasks": len(completedTasks), //成功数量
|
||||
"progress": fmt.Sprintf("%.1f%%", float64(completed)/float64(total)*100),
|
||||
"completed_tasks": completed,
|
||||
"completed_rate": float64(completed) / float64(total) * 100,
|
||||
})
|
||||
return
|
||||
|
||||
case StatusCompleted:
|
||||
completed, pending, total, completedTasks, failedTasks := processor.getTaskStatistics()
|
||||
service.Success(c, gin.H{
|
||||
"status": currentStatus,
|
||||
"status_description": StatusMap[currentStatus],
|
||||
"message": "所有任务已完成",
|
||||
"total_tasks": total,
|
||||
"failed_tasks": len(failedTasks), //失败数量
|
||||
"success_tasks": len(completedTasks), //成功数量
|
||||
"success_rate": fmt.Sprintf("%.1f%%", float64(len(completedTasks))/float64(total)*100),
|
||||
"pending_tasks": pending,
|
||||
"completed_tasks": completed,
|
||||
"completed_rate": float64(completed) / float64(total) * 100,
|
||||
}, "任务完成")
|
||||
return
|
||||
}
|
||||
}
|
||||
func ImageContentGetResultExcel(c *gin.Context) {
|
||||
processor := GetBatchProcessorReadOnly()
|
||||
if processor == nil {
|
||||
service.Error(c, errors.New("任务未开始或者任务在处理中"))
|
||||
return
|
||||
}
|
||||
currentStatus := processor.getStatus()
|
||||
switch currentStatus {
|
||||
case StatusCompleted:
|
||||
_, _, _, _, failedTasks := processor.getTaskStatistics()
|
||||
if len(failedTasks) > 0 {
|
||||
if err := returnExcel(failedTasks, c); err != nil {
|
||||
service.Error(c, errors.New("生成错误报告失败"))
|
||||
return
|
||||
}
|
||||
return
|
||||
} else {
|
||||
service.Error(c, errors.New("没有错误"))
|
||||
}
|
||||
case StatusIdle, StatusProcessing:
|
||||
service.Error(c, errors.New("任务未开始或者任务在处理中"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func returnExcel(failedTasks []*Task, c *gin.Context) error {
|
||||
titleList := []string{
|
||||
"行数", "艺术家", "编号", "错误信息", "任务ID", "开始时间",
|
||||
}
|
||||
var dataList []interface{}
|
||||
for _, task := range failedTasks {
|
||||
data := []interface{}{
|
||||
task.Data.LineNum + 1,
|
||||
task.Data.ArtistName,
|
||||
task.Data.SubNum,
|
||||
getErrorMessage(task.Error),
|
||||
task.TaskId,
|
||||
task.StartTime.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
dataList = append(dataList, &data)
|
||||
}
|
||||
sort.Slice(failedTasks, func(i, j int) bool {
|
||||
return failedTasks[i].Data.LineNum < failedTasks[j].Data.LineNum
|
||||
})
|
||||
|
||||
content, err := utils.ToExcelByType(titleList, dataList, "slice", "")
|
||||
if err != nil {
|
||||
return fmt.Errorf("生成Excel失败: %v", err)
|
||||
}
|
||||
utils.ResponseXls(c, content, fmt.Sprintf("失败任务报告_%s.xlsx", time.Now().Format("20060102150405")))
|
||||
return nil
|
||||
}
|
||||
339
pkg/service/import/imageContentImport.go
Normal file
339
pkg/service/import/imageContentImport.go
Normal file
@ -0,0 +1,339 @@
|
||||
package imports
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"fonchain-fiee/pkg/config"
|
||||
"fonchain-fiee/pkg/service"
|
||||
"fonchain-fiee/pkg/utils"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fonchain_enterprise/utils/objstorage"
|
||||
"github.com/xuri/excelize/v2"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
fail string = "操作失败"
|
||||
)
|
||||
|
||||
type excelData struct {
|
||||
ArtistName string //艺人 必须字段
|
||||
SubNum string //用户编号 必须字段
|
||||
TikTok string
|
||||
Instagram string
|
||||
Youtube string
|
||||
Desc string //艺人简介
|
||||
TitleRequire string //标题要求 必须字段
|
||||
ContentRequire string //内容要求 必须字段
|
||||
PhotoRequire string //图片要求 必须字段
|
||||
PhotoUrl string //画作地址
|
||||
PhotoNum int //图片数量 必须字段
|
||||
LineNum int
|
||||
Title string //标题
|
||||
Content string //内容
|
||||
MediaAccountUuids []string
|
||||
MediaAccountNames []string
|
||||
PhotoDpi string
|
||||
}
|
||||
type publishImageReq struct {
|
||||
ArtistName string //艺人
|
||||
SubNum string //用户编号
|
||||
Title string //标题
|
||||
Content string //内容
|
||||
TikTok string
|
||||
Instagram string
|
||||
GeneratePhotoUrl []string //生成图片地址
|
||||
MediaAccountUuids []string
|
||||
MediaAccountNames []string
|
||||
}
|
||||
|
||||
func getErrorMessage(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
func ImageContentImport(c *gin.Context) {
|
||||
processor := GetOrCreateBatchProcessor()
|
||||
currentStatus := processor.getStatus()
|
||||
switch currentStatus {
|
||||
case StatusProcessing: //进行中
|
||||
service.Error(c, errors.New("当前有任务正在执行中,请先查看执行进度"))
|
||||
return
|
||||
case StatusIdle, StatusCompleted: //空闲状态,完成可以执行下一次导入
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
service.Error(c, errors.New("操作失败"))
|
||||
}
|
||||
}()
|
||||
|
||||
// 导入excel
|
||||
excelFile, err := c.FormFile("excel")
|
||||
if err != nil {
|
||||
service.Error(c, errors.New("缺少excel文件"))
|
||||
return
|
||||
}
|
||||
|
||||
// 创建临时文件
|
||||
tempDir := "tmp"
|
||||
if err = os.MkdirAll(tempDir, 0755); err != nil {
|
||||
service.Error(c, errors.New("创建临时目录失败"))
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 保存excel
|
||||
excelPath := filepath.Join(tempDir, "excel.xlsx")
|
||||
if err = c.SaveUploadedFile(excelFile, excelPath); err != nil {
|
||||
service.Error(c, errors.New("保存excel文件失败"))
|
||||
return
|
||||
}
|
||||
|
||||
// 读取excel
|
||||
readExcelResult, err := readExcel(excelPath)
|
||||
if err != nil {
|
||||
service.Error(c, fmt.Errorf("读取excel失败: %v", err))
|
||||
return
|
||||
}
|
||||
if len(readExcelResult) == 0 {
|
||||
service.Error(c, errors.New("请检查excel文件"))
|
||||
return
|
||||
}
|
||||
//设置全局状态为进行中
|
||||
processor.setStatus(StatusProcessing)
|
||||
//设置请求间隔
|
||||
qps := 10
|
||||
interval := time.Second / time.Duration(qps)
|
||||
for i, v := range readExcelResult {
|
||||
if i > 0 {
|
||||
time.Sleep(interval)
|
||||
}
|
||||
|
||||
if err := processor.submitTask(&v); err != nil {
|
||||
task := &Task{
|
||||
Data: &v,
|
||||
TaskId: i,
|
||||
Error: err,
|
||||
StartTime: time.Now(),
|
||||
}
|
||||
processor.taskIdFindTask[v.LineNum] = task
|
||||
processor.taskIdFindTaskStatus[v.LineNum] = true
|
||||
}
|
||||
}
|
||||
//开始轮询
|
||||
processor.startPolling()
|
||||
service.Success(c, gin.H{
|
||||
"message": "导入成功",
|
||||
"total": len(readExcelResult),
|
||||
})
|
||||
}
|
||||
|
||||
func readExcel(excelPath string) ([]excelData, error) {
|
||||
//打开excel
|
||||
f, err := excelize.OpenFile(excelPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
//读取第一页
|
||||
sheetName := f.GetSheetName(0)
|
||||
if sheetName == "" {
|
||||
return nil, errors.New("excel文件中没有工作表")
|
||||
}
|
||||
|
||||
//读取数据
|
||||
rows, err := f.GetRows(sheetName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("读取工作表失败: %v", err)
|
||||
}
|
||||
|
||||
if len(rows) <= 1 {
|
||||
return nil, errors.New("excel文件没有数据行(只有表头或为空)")
|
||||
}
|
||||
var result []excelData
|
||||
for i := 1; i < len(rows); i++ { // 从第2行开始(跳过表头)
|
||||
row := rows[i]
|
||||
if len(row) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
artistName := getCellValue(f, sheetName, i, 0)
|
||||
if artistName == "" {
|
||||
return nil, fmt.Errorf("第%d行应该有艺人名称", i+1)
|
||||
}
|
||||
subNum := getCellValue(f, sheetName, i, 1)
|
||||
if subNum == "" {
|
||||
return nil, fmt.Errorf("第%d行应该有编号", i+1)
|
||||
}
|
||||
tikTok := getCellValue(f, sheetName, i, 2)
|
||||
if tikTok == "" {
|
||||
return nil, fmt.Errorf("第%d行应该有tiktok账号昵称", i+1)
|
||||
}
|
||||
instagram := getCellValue(f, sheetName, i, 3)
|
||||
if instagram == "" {
|
||||
return nil, fmt.Errorf("第%d行应该有ins账号昵称", i+1)
|
||||
}
|
||||
desc := getCellValue(f, sheetName, i, 4)
|
||||
titleRequire := getCellValue(f, sheetName, i, 5)
|
||||
if titleRequire == "" {
|
||||
return nil, fmt.Errorf("第%d行应该有标题要求", i+1)
|
||||
}
|
||||
contentRequire := getCellValue(f, sheetName, i, 6)
|
||||
if contentRequire == "" {
|
||||
return nil, fmt.Errorf("第%d行应该有内容要求", i+1)
|
||||
}
|
||||
photoRequire := getCellValue(f, sheetName, i, 7)
|
||||
photoUrl := getCellValue(f, sheetName, i, 8)
|
||||
photoNumStr := getCellValue(f, sheetName, i, 9)
|
||||
photoDpi := getCellValue(f, sheetName, i, 10)
|
||||
var num int
|
||||
if photoUrl == "" { //如果没有关联画作,数量必须有,需求必须有
|
||||
//需求必须有
|
||||
if photoRequire == "" {
|
||||
return nil, fmt.Errorf("第%d行应该有图片需求", i+1)
|
||||
}
|
||||
//转换成功
|
||||
photoNum, err := strconv.Atoi(strings.TrimSpace(photoNumStr))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("第%d行图片数量格式错误: '%s',必须是整数", i+1, photoNumStr)
|
||||
}
|
||||
// 数量大于
|
||||
if photoNum <= 0 {
|
||||
return nil, fmt.Errorf("第%d行图片数量必须大于0,当前值: %d", i+1, photoNum)
|
||||
}
|
||||
num = photoNum
|
||||
}
|
||||
|
||||
data := excelData{
|
||||
ArtistName: artistName,
|
||||
SubNum: subNum,
|
||||
TikTok: tikTok,
|
||||
Instagram: instagram,
|
||||
Desc: desc,
|
||||
TitleRequire: titleRequire,
|
||||
ContentRequire: contentRequire,
|
||||
PhotoRequire: photoRequire,
|
||||
PhotoUrl: photoUrl,
|
||||
PhotoNum: num,
|
||||
LineNum: i, //行数
|
||||
PhotoDpi: photoDpi,
|
||||
}
|
||||
|
||||
result = append(result, data)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func getCellValue(f *excelize.File, sheetName string, rowIndex, colIndex int) string {
|
||||
colName, _ := excelize.ColumnNumberToName(colIndex + 1)
|
||||
cell := fmt.Sprintf("%s%d", colName, rowIndex+1)
|
||||
|
||||
value, err := f.GetCellValue(sheetName, cell)
|
||||
if err != nil {
|
||||
log.Printf("读取单元格 %s 失败: %v", cell, err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.TrimSpace(value)
|
||||
}
|
||||
|
||||
func Test1(c *gin.Context) {
|
||||
// 创建临时目录
|
||||
tempDir := "tmp"
|
||||
if err := os.MkdirAll(tempDir, 0755); err != nil {
|
||||
}
|
||||
defer os.RemoveAll(tempDir) // 程序结束时清理整个目录
|
||||
// 生成唯一文件名
|
||||
fileName := fmt.Sprintf("%d.jpg", time.Now().Unix())
|
||||
|
||||
// 构建文件路径
|
||||
imgPath := filepath.Join(tempDir, fileName)
|
||||
|
||||
// 创建文件
|
||||
file, err := os.Create(imgPath)
|
||||
if err != nil {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
log.Printf("文件创建在: %s", imgPath)
|
||||
|
||||
// 下载图片到文件
|
||||
resp, err := http.Get("https://e-cdn.fontree.cn/fontree-fiee/tmp/unzipped/9.23-04/邬小明/90_1758873144.jpg")
|
||||
if err != nil {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
}
|
||||
|
||||
// 复制到文件
|
||||
_, err = io.Copy(file, resp.Body)
|
||||
if err != nil {
|
||||
}
|
||||
|
||||
file.Sync()
|
||||
fileBytes, err := os.ReadFile(imgPath)
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
// 上传到桶
|
||||
BOSClient, err := objstorage.NewOSS(
|
||||
config.ConfigData.Oss.AccessKeyId,
|
||||
config.ConfigData.Oss.AccessKeySecret,
|
||||
config.ConfigData.Oss.Endpoint,
|
||||
)
|
||||
_, err = BOSClient.PutObjectFromBytes(config.ConfigData.Oss.BucketName, fileName, fileBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
url := fmt.Sprintf("%s/%s", config.ConfigData.Oss.CdnHost, fileName)
|
||||
|
||||
log.Printf("图片上传成功: %s -> %s", fileName, url)
|
||||
service.Success(c)
|
||||
}
|
||||
|
||||
func Test(c *gin.Context) {
|
||||
err := publishImage(publishImageReq{
|
||||
ArtistName: "荣小松",
|
||||
SubNum: "FE00062",
|
||||
|
||||
Title: "test",
|
||||
Content: "test",
|
||||
GeneratePhotoUrl: []string{"0221", "2"},
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
service.Success(c)
|
||||
}
|
||||
|
||||
func Test2(c *gin.Context) {
|
||||
titleList := []string{
|
||||
"1",
|
||||
}
|
||||
var dataList []interface{}
|
||||
data := []string{
|
||||
"123123",
|
||||
}
|
||||
dataList = append(dataList, &data)
|
||||
content, err := utils.ToExcelByType(titleList, dataList, "slice", "")
|
||||
if err != nil {
|
||||
service.Error(c, err)
|
||||
return
|
||||
}
|
||||
utils.ResponseXls(c, content, "1")
|
||||
}
|
||||
746
pkg/service/import/imageContentProcessor.go
Normal file
746
pkg/service/import/imageContentProcessor.go
Normal file
@ -0,0 +1,746 @@
|
||||
package imports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"fonchain-fiee/api/accountFiee"
|
||||
apiCast "fonchain-fiee/api/cast"
|
||||
"fonchain-fiee/pkg/config"
|
||||
"fonchain-fiee/pkg/service"
|
||||
"io"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fonchain_enterprise/utils/objstorage"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type TaskStatus string
|
||||
|
||||
const (
|
||||
TaskPending TaskStatus = "PENDING" //任务排队中
|
||||
TaskRunning TaskStatus = "RUNNING" //任务处理中
|
||||
TaskSuccessful TaskStatus = "SUCCESSFUL" //任务执行成功
|
||||
TaskFailed TaskStatus = "FAILED" //任务执行失败
|
||||
TaskCancelled TaskStatus = "CANCELLED" //任务已经取消
|
||||
TaskCanceled TaskStatus = "UNKNOWN" //任务不存在
|
||||
)
|
||||
|
||||
var (
|
||||
batchProcessor *BatchProcessor
|
||||
batchProcessorMutex sync.Mutex
|
||||
)
|
||||
|
||||
const (
|
||||
StatusIdle = 0 // 空闲中(可执行新任务)
|
||||
StatusProcessing = 1 // 处理中(只能读取进度)
|
||||
StatusCompleted = 2 // 已完成(可读取结果)
|
||||
)
|
||||
|
||||
var StatusMap = map[int]string{StatusIdle: "空闲中", StatusProcessing: "处理中", StatusCompleted: "已完成"}
|
||||
|
||||
type BatchProcessor struct {
|
||||
mu sync.RWMutex
|
||||
taskIdFindTask map[int]*Task //IdFind任务
|
||||
taskIdFindTaskStatus map[int]bool //IdFind任务状态
|
||||
taskIdFindSubTaskStatus map[int]map[string]TaskStatus //IdFind子任务状态
|
||||
pollInterval time.Duration //间隔时间
|
||||
status int //全局实例状态
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
StartTime time.Time //任务开始时间
|
||||
EndTime time.Time //任务结束时间
|
||||
RetryCount int //重试次数todo暂未使用
|
||||
TaskId int //任务唯一标识
|
||||
Data *excelData //导入的初始任务数据
|
||||
Status TaskStatus //统一千文的错误
|
||||
Error error //任务调度中的报错
|
||||
//子任务
|
||||
SubTaskStatus map[string]TaskStatus //子任务-状态
|
||||
RequiredCount int //子任务-需要成功的数量
|
||||
SuccessCount int //子任务-成功数量
|
||||
FailedCount int //子任务-失败数量
|
||||
//生成的内容
|
||||
Title string //生成的标题
|
||||
Content string //生成的内容
|
||||
Urls []string //生成的地址
|
||||
}
|
||||
|
||||
// GetBatchProcessorReadOnly 获取只读实例
|
||||
func GetBatchProcessorReadOnly() *BatchProcessor {
|
||||
return batchProcessor
|
||||
}
|
||||
|
||||
// GetOrCreateBatchProcessor 获取实例
|
||||
func GetOrCreateBatchProcessor() *BatchProcessor {
|
||||
batchProcessorMutex.Lock()
|
||||
defer batchProcessorMutex.Unlock()
|
||||
|
||||
if batchProcessor == nil || batchProcessor.status == StatusCompleted {
|
||||
batchProcessor = &BatchProcessor{
|
||||
taskIdFindTask: make(map[int]*Task),
|
||||
taskIdFindTaskStatus: make(map[int]bool),
|
||||
taskIdFindSubTaskStatus: make(map[int]map[string]TaskStatus),
|
||||
pollInterval: 100 * time.Millisecond,
|
||||
status: StatusIdle,
|
||||
}
|
||||
}
|
||||
return batchProcessor
|
||||
}
|
||||
|
||||
// 设置任务状态
|
||||
func (p *BatchProcessor) setStatus(status int) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
p.status = status
|
||||
|
||||
}
|
||||
|
||||
// GetStatus 获取当前状态
|
||||
func (p *BatchProcessor) getStatus() int {
|
||||
p.mu.RLock()
|
||||
defer p.mu.RUnlock()
|
||||
return p.status
|
||||
}
|
||||
|
||||
// GetTaskStatistics 获取实例相关信息
|
||||
func (p *BatchProcessor) getTaskStatistics() (completed, pending, total int, completedTasks, failedTasks []*Task) {
|
||||
p.mu.RLock()
|
||||
defer p.mu.RUnlock()
|
||||
total = len(p.taskIdFindTask)
|
||||
for _, task := range p.taskIdFindTask {
|
||||
if p.taskIdFindTaskStatus[task.TaskId] { //是否转换成功
|
||||
completed++
|
||||
if task.Status == TaskSuccessful && task.Error == nil { //转换成功 并且 发布成功
|
||||
completedTasks = append(completedTasks, task)
|
||||
} else if task.Status == TaskFailed || task.Error != nil { //转换失败 或者 发布失败
|
||||
failedTasks = append(failedTasks, task)
|
||||
}
|
||||
} else {
|
||||
pending++
|
||||
}
|
||||
}
|
||||
|
||||
return completed, pending, total, completedTasks, failedTasks
|
||||
}
|
||||
func (p *BatchProcessor) recordSubTaskStatus(taskID int, subTaskID string, status TaskStatus) {
|
||||
|
||||
if _, exists := p.taskIdFindSubTaskStatus[taskID]; !exists {
|
||||
p.taskIdFindSubTaskStatus[taskID] = make(map[string]TaskStatus)
|
||||
}
|
||||
|
||||
p.taskIdFindSubTaskStatus[taskID][subTaskID] = status
|
||||
|
||||
// 更新主任务状态
|
||||
if task, exists := p.taskIdFindTask[taskID]; exists {
|
||||
switch status {
|
||||
case TaskSuccessful:
|
||||
task.SuccessCount++
|
||||
task.SubTaskStatus[subTaskID] = TaskSuccessful
|
||||
case TaskFailed:
|
||||
task.FailedCount++
|
||||
task.SubTaskStatus[subTaskID] = TaskFailed
|
||||
case TaskPending:
|
||||
task.SubTaskStatus[subTaskID] = TaskPending
|
||||
}
|
||||
|
||||
// 检查任务完成状态
|
||||
p.checkTaskCompletion(taskID)
|
||||
}
|
||||
}
|
||||
|
||||
// 检查任务是否完成
|
||||
func (p *BatchProcessor) checkTaskCompletion(taskID int) {
|
||||
task, exists := p.taskIdFindTask[taskID]
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否所有子任务都完成
|
||||
if task.SuccessCount+task.FailedCount >= len(p.taskIdFindSubTaskStatus[taskID]) {
|
||||
// 子任务都完成,判断成功数量
|
||||
if task.SuccessCount >= task.RequiredCount {
|
||||
// 成功数量满足要求
|
||||
task.Status = TaskSuccessful
|
||||
zap.L().Info("任务完成", zap.Int("taskID", taskID), zap.String("status", "success"))
|
||||
} else {
|
||||
// 成功数量不满足要求,但所有子任务完成
|
||||
task.Status = TaskFailed
|
||||
zap.L().Warn("任务部分成功", zap.Int("taskID", taskID), zap.Int("success", task.SuccessCount), zap.Int("required", task.RequiredCount))
|
||||
}
|
||||
task.EndTime = time.Now()
|
||||
p.taskIdFindTaskStatus[taskID] = true
|
||||
} else {
|
||||
zap.L().Info("任务正在进行中", zap.Int("taskID", taskID), zap.String("status", "in progress"))
|
||||
}
|
||||
}
|
||||
|
||||
// IsAllCompleted 获取任务是否全部完成
|
||||
func (p *BatchProcessor) IsAllCompleted() bool {
|
||||
p.mu.RLock()
|
||||
defer p.mu.RUnlock()
|
||||
|
||||
if len(p.taskIdFindTaskStatus) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
// 检查是否所有任务都标记为完成
|
||||
for _, completed := range p.taskIdFindTaskStatus {
|
||||
if !completed {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 获取未完成的任务列表
|
||||
func (p *BatchProcessor) getIncompleteTasks() []int {
|
||||
p.mu.RLock()
|
||||
defer p.mu.RUnlock()
|
||||
|
||||
var incomplete []int
|
||||
for taskID, completed := range p.taskIdFindTaskStatus {
|
||||
if !completed {
|
||||
incomplete = append(incomplete, taskID)
|
||||
}
|
||||
}
|
||||
return incomplete
|
||||
}
|
||||
|
||||
// 开始轮询
|
||||
func (p *BatchProcessor) startPolling() {
|
||||
go func() {
|
||||
ticker := time.NewTicker(p.pollInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for range ticker.C {
|
||||
if p.IsAllCompleted() {
|
||||
p.setStatus(StatusCompleted)
|
||||
zap.L().Info("所有任务已完成,停止轮询")
|
||||
break
|
||||
}
|
||||
for taskId, isAccomplish := range p.taskIdFindTaskStatus { // 遍历 inProgress 中的任务
|
||||
if !isAccomplish { // 如果任务未完成
|
||||
for subTaskId, taskIdTaskStates := range p.taskIdFindSubTaskStatus[taskId] { // 遍历该任务的子任务状态
|
||||
if taskIdTaskStates == TaskPending { // 如果子任务是待处理状态
|
||||
if err := p.updateTask(taskId, subTaskId); err != nil {
|
||||
zap.L().Error("批量更新任务状态失败: %v", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// 提交一个任务
|
||||
func (p *BatchProcessor) submitTask(req *excelData) error {
|
||||
// 获取用户信息
|
||||
list, err := service.AccountFieeProvider.UserList(context.Background(), &accountFiee.UserListRequest{
|
||||
Name: req.ArtistName,
|
||||
SubNum: req.SubNum,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取用户信息失败: %s", err.Error())
|
||||
}
|
||||
if len(list.UserList) == 0 {
|
||||
return fmt.Errorf("未找到用户信息: %s", req.ArtistName)
|
||||
}
|
||||
// 获取用户详细信息
|
||||
_, err = service.AccountFieeProvider.Info(context.Background(), &accountFiee.InfoRequest{
|
||||
ID: list.UserList[0].Id,
|
||||
Domain: "app",
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取用户详细信息失败: %s", err.Error())
|
||||
}
|
||||
|
||||
// 获取 TikTok 自媒体账号
|
||||
accountListTikTok, err := service.CastProvider.MediaUserList(context.Background(), &apiCast.MediaUserListReq{
|
||||
ArtistVal: req.ArtistName,
|
||||
PlatformID: 1,
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
ArtistUuid: strconv.FormatUint(list.UserList[0].Id, 10),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取 TikTok 账号失败: %s", err.Error())
|
||||
}
|
||||
if accountListTikTok == nil || len(accountListTikTok.Data) == 0 {
|
||||
return fmt.Errorf("tiktok自媒体账号数量为0")
|
||||
}
|
||||
// 查找 TikTok 账号
|
||||
tiktokFound := false
|
||||
for _, user := range accountListTikTok.Data {
|
||||
if user.PlatformUserName == req.TikTok {
|
||||
req.MediaAccountNames = append(req.MediaAccountNames, user.PlatformUserName)
|
||||
req.MediaAccountUuids = append(req.MediaAccountUuids, user.MediaAccountUuid)
|
||||
tiktokFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !tiktokFound {
|
||||
return fmt.Errorf("未找到匹配的TikTok账号: %s", req.TikTok)
|
||||
}
|
||||
// 获取 Instagram 自媒体账号
|
||||
accountListIns, err := service.CastProvider.MediaUserList(context.Background(), &apiCast.MediaUserListReq{
|
||||
ArtistVal: req.ArtistName,
|
||||
PlatformID: 3,
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
ArtistUuid: strconv.FormatUint(list.UserList[0].Id, 10),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取 Instagram 账号失败: %s", err.Error())
|
||||
}
|
||||
if accountListIns == nil || len(accountListIns.Data) == 0 {
|
||||
return fmt.Errorf("ins自媒体账号数量为0")
|
||||
}
|
||||
|
||||
// 查找 Instagram 账号
|
||||
insFound := false
|
||||
for _, user := range accountListIns.Data {
|
||||
if user.PlatformUserName == req.Instagram {
|
||||
req.MediaAccountNames = append(req.MediaAccountNames, user.PlatformUserName)
|
||||
req.MediaAccountUuids = append(req.MediaAccountUuids, user.MediaAccountUuid)
|
||||
insFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !insFound {
|
||||
return fmt.Errorf("未找到匹配的Instagram账号: %s", req.Instagram)
|
||||
}
|
||||
|
||||
switch {
|
||||
case req.PhotoUrl == "": // 如果没有提供照片 URL,生成标题和内容
|
||||
// 生成标题和内容
|
||||
title, content, err := p.generateTitleAndContent(req)
|
||||
if err != nil {
|
||||
zap.L().Error("生成标题和内容失败: %v", zap.Error(err))
|
||||
return fmt.Errorf("生成标题失败")
|
||||
}
|
||||
req.Title = title
|
||||
req.Content = content
|
||||
|
||||
// 请求生成图片
|
||||
|
||||
taskIds := make([]string, 0, req.PhotoNum)
|
||||
for i := 0; i < req.PhotoNum; i++ {
|
||||
taskId, err := p.generateImage(req)
|
||||
if err != nil {
|
||||
zap.L().Error("生成图片失败: %v", zap.Error(err))
|
||||
p.recordSubTaskStatus(req.LineNum, taskId, TaskFailed)
|
||||
return fmt.Errorf("生成图片失败")
|
||||
}
|
||||
taskIds = append(taskIds, taskId)
|
||||
p.recordSubTaskStatus(req.LineNum, taskId, TaskPending)
|
||||
}
|
||||
|
||||
// 创建并保存任务
|
||||
task := &Task{
|
||||
Data: req,
|
||||
TaskId: req.LineNum,
|
||||
Status: TaskPending,
|
||||
Title: title,
|
||||
Content: content,
|
||||
StartTime: time.Now(),
|
||||
SubTaskStatus: make(map[string]TaskStatus),
|
||||
RequiredCount: req.PhotoNum, // 需要成功的图片数量
|
||||
SuccessCount: 0,
|
||||
FailedCount: 0,
|
||||
}
|
||||
p.taskIdFindTask[req.LineNum] = task
|
||||
p.taskIdFindTaskStatus[req.LineNum] = false
|
||||
|
||||
case req.PhotoUrl != "": //如果有图片
|
||||
task := &Task{
|
||||
Data: req,
|
||||
TaskId: req.LineNum,
|
||||
Status: TaskPending,
|
||||
StartTime: time.Now(),
|
||||
RequiredCount: 1, // 单张图片只需要成功1次
|
||||
SuccessCount: 0,
|
||||
FailedCount: 0,
|
||||
SubTaskStatus: make(map[string]TaskStatus),
|
||||
}
|
||||
p.recordSubTaskStatus(req.LineNum, strconv.Itoa(req.LineNum), TaskPending)
|
||||
p.taskIdFindTask[req.LineNum] = task
|
||||
p.taskIdFindTaskStatus[req.LineNum] = false
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 更新任务
|
||||
func (p *BatchProcessor) updateTask(id int, taskId string) (err error) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
// 任务不存在直接返回
|
||||
task, exists := p.taskIdFindTask[id]
|
||||
if !exists {
|
||||
return fmt.Errorf("任务ID %d 不存在", id)
|
||||
}
|
||||
|
||||
switch {
|
||||
case task.Data.PhotoUrl != "": // 如果有图片 URL,生成标题和内容并发布
|
||||
// 生成标题和内容
|
||||
title, content, err := p.generateTitleAndContent(task.Data)
|
||||
if err != nil { //生成标题失败
|
||||
task.Status = TaskFailed
|
||||
p.taskIdFindTaskStatus[id] = true
|
||||
task.EndTime = time.Now()
|
||||
task.Error = fmt.Errorf("生成标题和内容失败: %s", err.Error())
|
||||
p.recordSubTaskStatus(id, taskId, TaskFailed)
|
||||
zap.L().Error("生成标题和内容失败: %v", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
task.Title = title
|
||||
task.Content = content
|
||||
// 发布内容
|
||||
if err = publishImage(publishImageReq{
|
||||
ArtistName: task.Data.ArtistName,
|
||||
SubNum: task.Data.SubNum,
|
||||
Title: task.Title,
|
||||
Content: task.Content,
|
||||
TikTok: task.Data.TikTok,
|
||||
Instagram: task.Data.Instagram,
|
||||
GeneratePhotoUrl: []string{task.Data.PhotoUrl},
|
||||
MediaAccountUuids: task.Data.MediaAccountUuids,
|
||||
MediaAccountNames: task.Data.MediaAccountNames,
|
||||
}); err != nil { //发布失败
|
||||
task.Status = TaskFailed
|
||||
p.taskIdFindTaskStatus[id] = true
|
||||
task.EndTime = time.Now()
|
||||
task.Error = fmt.Errorf("发布内容失败: %s", err.Error())
|
||||
zap.L().Error("发布内容失败: %v", zap.Error(err))
|
||||
p.recordSubTaskStatus(id, taskId, TaskFailed)
|
||||
return err
|
||||
}
|
||||
//操作成功
|
||||
p.recordSubTaskStatus(id, taskId, TaskSuccessful)
|
||||
|
||||
case task.Data.PhotoUrl == "": // 如果没有图片 URL,处理图片生成结果
|
||||
getTaskDetailRes, err := NewAiGenerator().GetTaskDetail(taskId)
|
||||
if err != nil { //获取图片结果失败
|
||||
zap.L().Error("查看图片生成结果失败: %v", zap.Error(err))
|
||||
task.Error = fmt.Errorf("查看图片生成结果失败")
|
||||
//task.Status = TaskFailed
|
||||
//p.inProgress[id] = true
|
||||
//task.EndTime = time.Now()
|
||||
p.recordSubTaskStatus(id, taskId, TaskFailed)
|
||||
return err
|
||||
}
|
||||
|
||||
switch getTaskDetailRes.Output.TaskStatus {
|
||||
case "SUCCEEDED":
|
||||
if task.Status != TaskSuccessful {
|
||||
//上传图片
|
||||
urls := make([]string, len(getTaskDetailRes.Output.Results))
|
||||
for i, v := range getTaskDetailRes.Output.Results {
|
||||
urls[i] = v.URL
|
||||
}
|
||||
uploadedURLs, err := downloadAndUploadImages(urls)
|
||||
if err != nil { //图片上传失败
|
||||
zap.L().Error("图片上传失败: %v", zap.Error(err))
|
||||
task.Error = fmt.Errorf("图片上传失败")
|
||||
//task.Status = TaskFailed
|
||||
//p.inProgress[id] = true
|
||||
//task.EndTime = time.Now()
|
||||
p.recordSubTaskStatus(id, taskId, TaskFailed)
|
||||
return err
|
||||
}
|
||||
task.Urls = append(task.Urls, uploadedURLs...)
|
||||
p.recordSubTaskStatus(id, taskId, TaskSuccessful)
|
||||
}
|
||||
|
||||
case "FAILED": //第三方返回失败
|
||||
if task.Status != TaskFailed {
|
||||
zap.L().Error("第三方生成失败: %v", zap.Error(err))
|
||||
task.Error = fmt.Errorf("生成失败")
|
||||
//task.Status = TaskFailed
|
||||
//p.inProgress[id] = true
|
||||
//task.EndTime = time.Now()
|
||||
p.recordSubTaskStatus(id, taskId, TaskFailed)
|
||||
return err
|
||||
}
|
||||
}
|
||||
p.checkTaskCompletion(id)
|
||||
if p.taskIdFindTaskStatus[id] == true {
|
||||
// 发布图文
|
||||
if err = publishImage(publishImageReq{
|
||||
ArtistName: task.Data.ArtistName,
|
||||
SubNum: task.Data.SubNum,
|
||||
Title: task.Title,
|
||||
Content: task.Content,
|
||||
TikTok: task.Data.TikTok,
|
||||
Instagram: task.Data.Instagram,
|
||||
MediaAccountUuids: task.Data.MediaAccountUuids,
|
||||
MediaAccountNames: task.Data.MediaAccountNames,
|
||||
GeneratePhotoUrl: task.Urls,
|
||||
}); err != nil { //发布失败
|
||||
zap.L().Error("发布内容失败: %v", zap.Error(err))
|
||||
task.Error = fmt.Errorf("发布内容失败")
|
||||
task.Status = TaskFailed
|
||||
p.taskIdFindTaskStatus[id] = true
|
||||
task.EndTime = time.Now()
|
||||
return err
|
||||
}
|
||||
//处理成功
|
||||
task.Status = TaskSuccessful
|
||||
p.taskIdFindTaskStatus[id] = true
|
||||
task.EndTime = time.Now()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 批量上传图片
|
||||
func downloadAndUploadImages(urls []string) ([]string, error) {
|
||||
var uploadedURLs []string
|
||||
|
||||
for _, result := range urls {
|
||||
if result == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// 下载并直接上传到桶
|
||||
bucketURL, err := downloadAndUploadToBucket(result)
|
||||
if err != nil {
|
||||
log.Printf("图片上传失败 [%s]: %v", result, err)
|
||||
continue
|
||||
}
|
||||
|
||||
uploadedURLs = append(uploadedURLs, bucketURL)
|
||||
log.Printf("图片上传成功: %s -> %s", result, bucketURL)
|
||||
}
|
||||
|
||||
if len(uploadedURLs) == 0 {
|
||||
return nil, errors.New("所有图片上传失败")
|
||||
}
|
||||
|
||||
return uploadedURLs, nil
|
||||
}
|
||||
|
||||
// 上传图片到桶里面
|
||||
func downloadAndUploadToBucket(imageURL string) (string, error) {
|
||||
// 创建临时目录
|
||||
tempDir := "tmp"
|
||||
if err := os.MkdirAll(tempDir, 0755); err != nil {
|
||||
return "", fmt.Errorf("创建临时目录失败: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir) // 程序结束时清理整个目录
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
fileName := fmt.Sprintf("%d%04d.jpg", time.Now().Unix(), rand.Intn(10000))
|
||||
// 构建文件路径
|
||||
imgPath := filepath.Join(tempDir, fileName)
|
||||
|
||||
// 创建文件
|
||||
file, err := os.Create(imgPath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("创建文件失败: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
log.Printf("文件创建在: %s", imgPath)
|
||||
|
||||
// 下载图片到文件
|
||||
resp, err := http.Get(imageURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("下载图片失败: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("下载失败,状态码: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// 复制到文件
|
||||
_, err = io.Copy(file, resp.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("保存文件失败: %v", err)
|
||||
}
|
||||
|
||||
file.Sync()
|
||||
|
||||
fileBytes, err := os.ReadFile(imgPath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("读取本地文件失败: %v", err)
|
||||
}
|
||||
|
||||
BOSClient, err := objstorage.NewOSS(
|
||||
os.Getenv(config.ConfigData.Oss.AccessKeyId),
|
||||
os.Getenv(config.ConfigData.Oss.AccessKeySecret),
|
||||
os.Getenv(config.ConfigData.Oss.Endpoint),
|
||||
)
|
||||
if BOSClient == nil {
|
||||
return "", fmt.Errorf("上传文件失败: %v", err)
|
||||
}
|
||||
_, err = BOSClient.PutObjectFromBytes(os.Getenv(config.ConfigData.Oss.BucketName), fileName, fileBytes)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("上传文件失败: %v", err)
|
||||
}
|
||||
url := fmt.Sprintf("%s/%s", os.Getenv(config.ConfigData.Oss.CdnHost), fileName)
|
||||
//上传到桶
|
||||
//BOSClient, err := objstorage.NewOSS(
|
||||
// config.ConfigData.Oss.AccessKeyId,
|
||||
// config.ConfigData.Oss.AccessKeySecret,
|
||||
// config.ConfigData.Oss.Endpoint,
|
||||
//)
|
||||
//if BOSClient == nil {
|
||||
// return "", fmt.Errorf("上传文件失败: %v", err)
|
||||
//}
|
||||
//_, err = BOSClient.PutObjectFromBytes(config.ConfigData.Oss.BucketName, fileName, fileBytes)
|
||||
//if err != nil {
|
||||
// return "", fmt.Errorf("上传文件失败: %v", err)
|
||||
//}
|
||||
//url := fmt.Sprintf("%s/%s", config.ConfigData.Oss.CdnHost, fileName)
|
||||
|
||||
return url, nil
|
||||
}
|
||||
|
||||
func (p *BatchProcessor) generateTitleAndContent(req *excelData) (string, string, error) {
|
||||
if req.PhotoUrl != "" {
|
||||
title, content, err := NewAiGenerator().GenerateTitleAndContentFromImage(
|
||||
req.PhotoUrl,
|
||||
req.TitleRequire,
|
||||
req.ContentRequire,
|
||||
)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("图生文失败: %v", err)
|
||||
}
|
||||
return title, content, nil
|
||||
} else {
|
||||
title, content, err := NewAiGenerator().GenerateTitleAndContentFromText(
|
||||
req.TitleRequire,
|
||||
req.ContentRequire,
|
||||
)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("生成内容失败: %v", err)
|
||||
}
|
||||
return title, content, nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (p *BatchProcessor) generateImage(req *excelData) (string, error) {
|
||||
prompt := fmt.Sprintf("请根据以下要求生成内容:%s\n", req.PhotoRequire)
|
||||
if req.Title != "" {
|
||||
prompt += fmt.Sprintf("1:标题:%s\n", req.Title) // 关联标题
|
||||
}
|
||||
if req.Content != "" {
|
||||
prompt += fmt.Sprintf("2:内容:%s\n", req.Content) // 关联内容
|
||||
}
|
||||
if req.Desc != "" {
|
||||
prompt += fmt.Sprintf("3:艺人简介:%s,艺人简介的优先级要低,只依据艺人简介的风格", req.Desc)
|
||||
}
|
||||
prompt += "\n请基于标题和内容生成单张图片,高质量,高分辨率。"
|
||||
prompt += "\n要求不能出现:低质量、残缺、人物正脸、多余的手指、乱码字符和文字、比例不良,场景以国内场景为主"
|
||||
|
||||
if req.PhotoDpi == "" {
|
||||
req.PhotoDpi = "720*1280"
|
||||
|
||||
}
|
||||
result, err := NewAiGenerator().TextToImage(
|
||||
prompt,
|
||||
req.PhotoDpi,
|
||||
1,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return result.Output.TaskID, nil
|
||||
}
|
||||
|
||||
//func (p *BatchProcessor) StartPolling() {
|
||||
// go func() {
|
||||
// ticker := time.NewTicker(p.pollInterval) // 1秒间隔
|
||||
// defer ticker.Stop()
|
||||
//
|
||||
// // 令牌桶,控制每秒最多10个请求
|
||||
// tokenBucket := make(chan struct{}, 10)
|
||||
//
|
||||
// // 每秒补充令牌
|
||||
// go func() {
|
||||
// refillTicker := time.NewTicker(time.Second)
|
||||
// defer refillTicker.Stop()
|
||||
//
|
||||
// for {
|
||||
// select {
|
||||
// case <-refillTicker.C:
|
||||
// // 每秒补充到10个令牌
|
||||
// for i := 0; i < 10-len(tokenBucket); i++ {
|
||||
// select {
|
||||
// case tokenBucket <- struct{}{}:
|
||||
// default:
|
||||
// // 桶已满,跳过
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }()
|
||||
//
|
||||
// for range ticker.C {
|
||||
// if p.IsAllCompleted() {
|
||||
// p.SetStatus(StatusCompleted)
|
||||
// zap.L().Info("所有任务已完成,停止轮询")
|
||||
// ticker.Stop()
|
||||
// break
|
||||
// }
|
||||
//
|
||||
// // 获取未完成的任务
|
||||
// incompleteTasks := p.getIncompleteTasks()
|
||||
// if len(incompleteTasks) == 0 {
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// // 处理当前可用的任务(最多10个)
|
||||
// processedCount := 0
|
||||
// for _, taskID := range incompleteTasks {
|
||||
// if processedCount >= 10 {
|
||||
// break // 本秒已达到10个请求限制
|
||||
// }
|
||||
//
|
||||
// select {
|
||||
// case <-tokenBucket:
|
||||
// // 获取到令牌,可以发送请求
|
||||
// processedCount++
|
||||
// go p.updateTaskWithToken(taskID, tokenBucket)
|
||||
// default:
|
||||
// // 没有令牌了,跳过
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// zap.L().Debug("本轮处理任务数量",
|
||||
// zap.Int("processed", processedCount),
|
||||
// zap.Int("remaining", len(incompleteTasks)-processedCount))
|
||||
// }
|
||||
// }()
|
||||
//}
|
||||
//
|
||||
//// 使用令牌更新任务状态
|
||||
//func (p *BatchProcessor) updateTaskWithToken(taskID string, tokenBucket chan struct{}) {
|
||||
// defer func() {
|
||||
// // 任务完成后不返还令牌,由定时器统一补充
|
||||
// }()
|
||||
//
|
||||
// if err := p.UpdateTaskStatuses(taskID); err != nil {
|
||||
// zap.L().Error("更新任务状态失败",
|
||||
// zap.String("task_id", taskID),
|
||||
// zap.Error(err))
|
||||
// }
|
||||
//}
|
||||
107
pkg/service/import/imageContentPublish.go
Normal file
107
pkg/service/import/imageContentPublish.go
Normal file
@ -0,0 +1,107 @@
|
||||
package imports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"fonchain-fiee/api/accountFiee"
|
||||
apiCast "fonchain-fiee/api/cast"
|
||||
"fonchain-fiee/pkg/service"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func publishImage(req publishImageReq) (err error) {
|
||||
var infoResp *accountFiee.UserInfoResponse
|
||||
list, err := service.AccountFieeProvider.UserList(context.Background(), &accountFiee.UserListRequest{
|
||||
Name: req.ArtistName,
|
||||
SubNum: req.SubNum,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取用户信息失败: %s", err.Error())
|
||||
}
|
||||
if len(list.UserList) == 0 {
|
||||
return fmt.Errorf("未找到用户信息: %s", req.ArtistName)
|
||||
}
|
||||
if len(list.UserList) > 0 {
|
||||
infoResp, err = service.AccountFieeProvider.Info(context.Background(), &accountFiee.InfoRequest{
|
||||
ID: list.UserList[0].Id,
|
||||
Domain: "app",
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取用户信息失败: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------获取自媒体账号
|
||||
//accountList, err := service.CastProvider.MediaUserList(context.Background(), &apiCast.MediaUserListReq{
|
||||
// ArtistUuid: strconv.FormatUint(list.UserList[0].Id, 10),
|
||||
// ArtistVal: req.ArtistName,
|
||||
// Page: 1,
|
||||
// PageSize: 10,
|
||||
//})
|
||||
//if err != nil {
|
||||
// return fmt.Errorf("自媒体账号数量获取失败: %s,账号数量:%d", err.Error(), len(accountList.Data))
|
||||
//}
|
||||
//if accountList == nil || len(accountList.Data) == 0 {
|
||||
// return fmt.Errorf("自媒体账号数量为0")
|
||||
//}
|
||||
//var mediaAccountUuids []string
|
||||
//var mediaAccountNames []string
|
||||
//platformIDs 1 tiktok 2youtube 3ins
|
||||
//platformIDs := []apiCast.PlatformIDENUM{}
|
||||
//for _, info := range accountList.Data {
|
||||
// if info.ArtistName == req.TikTok || info.ArtistName == req.Instagram {
|
||||
// mediaAccountUuids = append(mediaAccountUuids, info.MediaAccountUuid)
|
||||
// mediaAccountNames = append(mediaAccountNames, info.PlatformUserName)
|
||||
// platformIDs = append(platformIDs, apiCast.PlatformIDENUM(info.PlatformID))
|
||||
// }
|
||||
//}
|
||||
|
||||
//---------------------------------------------------发布
|
||||
_, err = service.CastProvider.UpdateWorkImage(context.Background(), &apiCast.UpdateWorkImageReq{
|
||||
Title: req.Title,
|
||||
Content: req.Content,
|
||||
Images: req.GeneratePhotoUrl,
|
||||
MediaAccountUuids: req.MediaAccountUuids,
|
||||
MediaAccountNames: req.MediaAccountNames,
|
||||
PlatformIDs: []apiCast.PlatformIDENUM{1, 3},
|
||||
PublishConfig1: &apiCast.PublishConfig{
|
||||
CanComment: 1,
|
||||
CanJoin: 1,
|
||||
CanQuote: 1,
|
||||
ForbidComment: 1,
|
||||
IsAI: 1,
|
||||
PublicType: 1,
|
||||
},
|
||||
PublishConfig2: &apiCast.PublishConfig{
|
||||
CanComment: 1,
|
||||
CanJoin: 1,
|
||||
CanQuote: 1,
|
||||
ForbidComment: 1,
|
||||
IsAI: 1,
|
||||
PublicType: 1,
|
||||
},
|
||||
PublishConfig3: &apiCast.PublishConfig{
|
||||
CanComment: 1,
|
||||
CanJoin: 1,
|
||||
CanQuote: 1,
|
||||
ForbidComment: 1,
|
||||
IsAI: 1,
|
||||
PublicType: 1,
|
||||
},
|
||||
PublishConfig4: nil,
|
||||
Action: "submit",
|
||||
ArtistPhone: infoResp.TelNum,
|
||||
ArtistUuid: strconv.FormatUint(list.UserList[0].Id, 10),
|
||||
ArtistName: infoResp.Name,
|
||||
ArtistPhoneAreaCode: infoResp.TelAreaCode,
|
||||
WorkUuid: "",
|
||||
Source: 2,
|
||||
LineNo: 0,
|
||||
Remark: "",
|
||||
Success: false,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("发布"+req.ArtistName+"图文"+"失败: %s", err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"fonchain-fiee/api/account"
|
||||
"fonchain-fiee/api/accountFiee"
|
||||
"fonchain-fiee/api/aryshare"
|
||||
"fonchain-fiee/api/bundle"
|
||||
"fonchain-fiee/api/cast"
|
||||
"fonchain-fiee/api/files"
|
||||
@ -31,6 +32,7 @@ var CastProvider = new(cast.CastClientImpl)
|
||||
var GovernanceProvider = new(governance.GovernanceClientImpl)
|
||||
var PressReleasesProvider = new(pressreleases.PressReleasesClientImpl)
|
||||
var SecFilingProvider = new(secFilings.SecFilingsClientImpl)
|
||||
var AyrshareProvider = new(aryshare.AyrshareClientImpl)
|
||||
|
||||
func init() {
|
||||
config.SetConsumerService(BundleProvider)
|
||||
@ -43,6 +45,7 @@ func init() {
|
||||
config.SetConsumerService(GovernanceProvider)
|
||||
config.SetConsumerService(PressReleasesProvider)
|
||||
config.SetConsumerService(SecFilingProvider)
|
||||
config.SetConsumerService(AyrshareProvider)
|
||||
|
||||
if err := config.Load(); err != nil {
|
||||
panic(err)
|
||||
|
||||
@ -182,6 +182,22 @@ func GetRecentAssignRecords(c *gin.Context) {
|
||||
service.Success(c, res)
|
||||
}
|
||||
|
||||
func AddHiddenTaskAssignee(c *gin.Context) {
|
||||
var req bundle.AddHiddenTaskAssigneeRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
service.Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
res, err := service.BundleProvider.AddHiddenTaskAssignee(context.Background(), &req)
|
||||
if err != nil {
|
||||
service.Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
service.Success(c, res)
|
||||
}
|
||||
|
||||
// GetEmployeeAssignedTasks 根据登录人信息查询被指派给该员工的任务
|
||||
func GetEmployeeAssignedTasks(c *gin.Context) {
|
||||
var req bundle.EmployeeTaskQueryRequest
|
||||
@ -553,7 +569,7 @@ func GetArtistUploadStatsListDownload(c *gin.Context) {
|
||||
}
|
||||
|
||||
titleList := []string{
|
||||
"用户编号", "艺人", "手机号", "最近一次指派人", "待上传视频脚本数", "已上传视频脚本数", "待上传视频数", "已上传视频数", "已释放视频额度", "套餐视频总数", "增值视频总数", "待上传图文数", "已上传图文数", "已释放图文额度", "套餐图文总数", "增值图文总数", "待上传数据数", "已上传数据数", "已释放数据额度", "套餐数据总数", "增值数据总数", "进行中任务数", "已完成任务数",
|
||||
"用户编号", "艺人", "手机号", "最近一次指派人", "可指派视频脚本数", "可上传视频脚本数", "已上传视频脚本数", "可指派视频数", "可上传视频数", "已上传视频数", "已释放视频额度", "套餐视频总数", "增值视频总数", "可指派图文数", "可上传图文数", "已上传图文数", "已释放图文额度", "套餐图文总数", "增值图文总数", "可指派数据数", "可上传数据数", "已上传数据数", "已释放数据额度", "套餐数据总数", "增值数据总数", "进行中任务数", "已完成任务数",
|
||||
}
|
||||
|
||||
var dataList []interface{}
|
||||
@ -563,18 +579,22 @@ func GetArtistUploadStatsListDownload(c *gin.Context) {
|
||||
i.ArtistName,
|
||||
i.TelNum,
|
||||
i.LastTaskAssignee,
|
||||
i.AllowVideoScriptCount,
|
||||
i.PendingVideoScriptCount,
|
||||
i.UploadedVideoScriptCount,
|
||||
i.AllowVideoCount,
|
||||
i.PendingVideoCount,
|
||||
i.UploadedVideoCount,
|
||||
i.ReleasedVideoTotal,
|
||||
i.BundleVideoTotal,
|
||||
i.IncreaseVideoTotal,
|
||||
i.AllowPostCount,
|
||||
i.PendingPostCount,
|
||||
i.UploadedPostCount,
|
||||
i.ReleasedPostTotal,
|
||||
i.BundlePostTotal,
|
||||
i.IncreasePostTotal,
|
||||
i.AllowDataCount,
|
||||
i.PendingDataAnalysisCount,
|
||||
i.UploadedDataAnalysisCount,
|
||||
i.ReleasedDataAnalysisTotal,
|
||||
@ -659,3 +679,19 @@ func UpdateVideoScriptWithUUID(ctx *gin.Context) {
|
||||
service.Success(ctx, resp)
|
||||
return
|
||||
}
|
||||
|
||||
func GetPendingAssign(c *gin.Context) {
|
||||
var req bundle.PendingAssignRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
service.Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
res, err := service.BundleProvider.GetPendingAssign(context.Background(), &req)
|
||||
if err != nil {
|
||||
service.Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
service.Success(c, res)
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
@ -41,7 +42,7 @@ func Post(url, data string) (string, error) {
|
||||
func PostBytes(url string, header map[string]interface{}, data []byte) ([]byte, error) {
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建请求失败: %v", err)
|
||||
return nil, fmt.Errorf("创建请求失败: %v", "")
|
||||
}
|
||||
for k, v := range header {
|
||||
req.Header.Set(k, fmt.Sprintf("%v", v))
|
||||
@ -49,16 +50,16 @@ func PostBytes(url string, header map[string]interface{}, data []byte) ([]byte,
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("请求失败: %v", err)
|
||||
return nil, fmt.Errorf("请求失败: %v", "")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("读取响应失败: %v", err)
|
||||
return nil, fmt.Errorf("读取响应失败: %v", "")
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
zap.L().Error("API返回错误", zap.Int("status", resp.StatusCode), zap.String("body", string(body)))
|
||||
return nil, fmt.Errorf("API返回错误: status=%d, body=%s", resp.StatusCode, string(body))
|
||||
return nil, fmt.Errorf("接口返回错误")
|
||||
}
|
||||
return body, nil
|
||||
}
|
||||
@ -87,3 +88,48 @@ func GetBytes(url string, header map[string]interface{}) ([]byte, error) {
|
||||
}
|
||||
return body, nil
|
||||
}
|
||||
|
||||
func GetUrl(apiUrl string, headerData map[string]string, proxyURL ...string) (statusCode int, body []byte, err error) {
|
||||
req, err := http.NewRequest("GET", apiUrl, nil)
|
||||
if err != nil {
|
||||
zap.L().Error("Get", zap.Any("url", apiUrl), zap.Error(err))
|
||||
err = fmt.Errorf("create request failed: %w", err)
|
||||
return
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
if len(headerData) > 0 {
|
||||
for k, v := range headerData {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
}
|
||||
client := &http.Client{}
|
||||
// 支持可选的代理参数
|
||||
if len(proxyURL) > 0 && proxyURL[0] != "" {
|
||||
proxy, _err := url.Parse(proxyURL[0])
|
||||
if _err != nil {
|
||||
err = _err
|
||||
return
|
||||
}
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyURL(proxy),
|
||||
}
|
||||
client.Transport = transport
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
zap.L().Error("Get", zap.Any("url", apiUrl), zap.Error(err))
|
||||
err = fmt.Errorf("send request failed: %w", err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
zap.L().Error("Get", zap.Any("url", apiUrl), zap.Error(err))
|
||||
err = fmt.Errorf("read response failed: %w", err)
|
||||
return
|
||||
}
|
||||
statusCode = resp.StatusCode
|
||||
zap.L().Info("Get", zap.Any("url", apiUrl), zap.Any("body", body))
|
||||
return
|
||||
}
|
||||
|
||||
13
pkg/utils/slice.go
Normal file
13
pkg/utils/slice.go
Normal file
@ -0,0 +1,13 @@
|
||||
package utils
|
||||
|
||||
func UniqueT[T comparable](list []T) []T {
|
||||
m := make(map[T]struct{})
|
||||
result := make([]T, 0, len(list))
|
||||
for _, v := range list {
|
||||
if _, exists := m[v]; !exists {
|
||||
m[v] = struct{}{}
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user