互动管理接口

This commit is contained in:
戴育兵 2025-12-18 16:00:56 +08:00
commit be1af84920
13 changed files with 3301 additions and 3 deletions

1912
api/cron/cron.pb.go Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,143 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: pb/cron.proto
package cron
import (
fmt "fmt"
math "math"
proto "github.com/golang/protobuf/proto"
_ "google.golang.org/protobuf/types/known/emptypb"
github_com_mwitkow_go_proto_validators "github.com/mwitkow/go-proto-validators"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
func (this *CommonIDRequest) Validate() error {
return nil
}
func (this *CommonResponse) Validate() error {
return nil
}
func (this *ScheduleTask) Validate() error {
if this.TaskDetail != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.TaskDetail); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("TaskDetail", err)
}
}
for _, item := range this.ExecutionRecords {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("ExecutionRecords", err)
}
}
}
return nil
}
func (this *ExecutionRecord) Validate() error {
for _, item := range this.ExecutionResults {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("ExecutionResults", err)
}
}
}
return nil
}
func (this *ExecutionResult) Validate() error {
return nil
}
func (this *TaskDetail) Validate() error {
for _, item := range this.Artists {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Artists", err)
}
}
}
return nil
}
func (this *ArtistInfo) Validate() error {
return nil
}
func (this *CreateScheduleTaskRequest) Validate() error {
if this.TaskDetail != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.TaskDetail); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("TaskDetail", err)
}
}
return nil
}
func (this *TaskDetailRequest) Validate() error {
for _, item := range this.Artists {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Artists", err)
}
}
}
return nil
}
func (this *CreateScheduleTaskResponse) Validate() error {
if this.Data != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Data); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Data", err)
}
}
return nil
}
func (this *GetListScheduleTaskRequest) Validate() error {
return nil
}
func (this *GetListScheduleTaskResponse) Validate() error {
for _, item := range this.Data {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Data", err)
}
}
}
return nil
}
func (this *GetListExecutionRecordRequest) Validate() error {
return nil
}
func (this *GetListExecutionRecordResponse) Validate() error {
for _, item := range this.Data {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Data", err)
}
}
}
return nil
}
func (this *GetListExecutionResultRequest) Validate() error {
return nil
}
func (this *GetListExecutionResultResponse) Validate() error {
for _, item := range this.Data {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Data", err)
}
}
}
return nil
}
func (this *TaskStatus) Validate() error {
return nil
}
func (this *GetScheduleTaskStatusResponse) Validate() error {
for _, item := range this.Status {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Status", err)
}
}
}
return nil
}

463
api/cron/cron_triple.pb.go Normal file
View File

@ -0,0 +1,463 @@
// Code generated by protoc-gen-go-triple. DO NOT EDIT.
// versions:
// - protoc-gen-go-triple v1.0.5
// - protoc v6.32.0
// source: pb/cron.proto
package cron
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"
emptypb "google.golang.org/protobuf/types/known/emptypb"
)
// 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
// CronClient is the client API for Cron 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 CronClient interface {
CreateScheduleTask(ctx context.Context, in *CreateScheduleTaskRequest, opts ...grpc_go.CallOption) (*CreateScheduleTaskResponse, common.ErrorWithAttachment)
GetListScheduleTask(ctx context.Context, in *GetListScheduleTaskRequest, opts ...grpc_go.CallOption) (*GetListScheduleTaskResponse, common.ErrorWithAttachment)
GetListExecutionRecord(ctx context.Context, in *GetListExecutionRecordRequest, opts ...grpc_go.CallOption) (*GetListExecutionRecordResponse, common.ErrorWithAttachment)
GetListExecutionResult(ctx context.Context, in *GetListExecutionResultRequest, opts ...grpc_go.CallOption) (*GetListExecutionResultResponse, common.ErrorWithAttachment)
PauseScheduleTask(ctx context.Context, in *CommonIDRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment)
StartScheduleTask(ctx context.Context, in *CommonIDRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment)
DeleteScheduleTask(ctx context.Context, in *CommonIDRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment)
GetScheduleTaskStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc_go.CallOption) (*GetScheduleTaskStatusResponse, common.ErrorWithAttachment)
}
type cronClient struct {
cc *triple.TripleConn
}
type CronClientImpl struct {
CreateScheduleTask func(ctx context.Context, in *CreateScheduleTaskRequest) (*CreateScheduleTaskResponse, error)
GetListScheduleTask func(ctx context.Context, in *GetListScheduleTaskRequest) (*GetListScheduleTaskResponse, error)
GetListExecutionRecord func(ctx context.Context, in *GetListExecutionRecordRequest) (*GetListExecutionRecordResponse, error)
GetListExecutionResult func(ctx context.Context, in *GetListExecutionResultRequest) (*GetListExecutionResultResponse, error)
PauseScheduleTask func(ctx context.Context, in *CommonIDRequest) (*CommonResponse, error)
StartScheduleTask func(ctx context.Context, in *CommonIDRequest) (*CommonResponse, error)
DeleteScheduleTask func(ctx context.Context, in *CommonIDRequest) (*CommonResponse, error)
GetScheduleTaskStatus func(ctx context.Context, in *emptypb.Empty) (*GetScheduleTaskStatusResponse, error)
}
func (c *CronClientImpl) GetDubboStub(cc *triple.TripleConn) CronClient {
return NewCronClient(cc)
}
func (c *CronClientImpl) XXX_InterfaceName() string {
return "cron.Cron"
}
func NewCronClient(cc *triple.TripleConn) CronClient {
return &cronClient{cc}
}
func (c *cronClient) CreateScheduleTask(ctx context.Context, in *CreateScheduleTaskRequest, opts ...grpc_go.CallOption) (*CreateScheduleTaskResponse, common.ErrorWithAttachment) {
out := new(CreateScheduleTaskResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/CreateScheduleTask", in, out)
}
func (c *cronClient) GetListScheduleTask(ctx context.Context, in *GetListScheduleTaskRequest, opts ...grpc_go.CallOption) (*GetListScheduleTaskResponse, common.ErrorWithAttachment) {
out := new(GetListScheduleTaskResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetListScheduleTask", in, out)
}
func (c *cronClient) GetListExecutionRecord(ctx context.Context, in *GetListExecutionRecordRequest, opts ...grpc_go.CallOption) (*GetListExecutionRecordResponse, common.ErrorWithAttachment) {
out := new(GetListExecutionRecordResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetListExecutionRecord", in, out)
}
func (c *cronClient) GetListExecutionResult(ctx context.Context, in *GetListExecutionResultRequest, opts ...grpc_go.CallOption) (*GetListExecutionResultResponse, common.ErrorWithAttachment) {
out := new(GetListExecutionResultResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetListExecutionResult", in, out)
}
func (c *cronClient) PauseScheduleTask(ctx context.Context, in *CommonIDRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment) {
out := new(CommonResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/PauseScheduleTask", in, out)
}
func (c *cronClient) StartScheduleTask(ctx context.Context, in *CommonIDRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment) {
out := new(CommonResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/StartScheduleTask", in, out)
}
func (c *cronClient) DeleteScheduleTask(ctx context.Context, in *CommonIDRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment) {
out := new(CommonResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/DeleteScheduleTask", in, out)
}
func (c *cronClient) GetScheduleTaskStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc_go.CallOption) (*GetScheduleTaskStatusResponse, common.ErrorWithAttachment) {
out := new(GetScheduleTaskStatusResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetScheduleTaskStatus", in, out)
}
// CronServer is the server API for Cron service.
// All implementations must embed UnimplementedCronServer
// for forward compatibility
type CronServer interface {
CreateScheduleTask(context.Context, *CreateScheduleTaskRequest) (*CreateScheduleTaskResponse, error)
GetListScheduleTask(context.Context, *GetListScheduleTaskRequest) (*GetListScheduleTaskResponse, error)
GetListExecutionRecord(context.Context, *GetListExecutionRecordRequest) (*GetListExecutionRecordResponse, error)
GetListExecutionResult(context.Context, *GetListExecutionResultRequest) (*GetListExecutionResultResponse, error)
PauseScheduleTask(context.Context, *CommonIDRequest) (*CommonResponse, error)
StartScheduleTask(context.Context, *CommonIDRequest) (*CommonResponse, error)
DeleteScheduleTask(context.Context, *CommonIDRequest) (*CommonResponse, error)
GetScheduleTaskStatus(context.Context, *emptypb.Empty) (*GetScheduleTaskStatusResponse, error)
mustEmbedUnimplementedCronServer()
}
// UnimplementedCronServer must be embedded to have forward compatible implementations.
type UnimplementedCronServer struct {
proxyImpl protocol.Invoker
}
func (UnimplementedCronServer) CreateScheduleTask(context.Context, *CreateScheduleTaskRequest) (*CreateScheduleTaskResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateScheduleTask not implemented")
}
func (UnimplementedCronServer) GetListScheduleTask(context.Context, *GetListScheduleTaskRequest) (*GetListScheduleTaskResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetListScheduleTask not implemented")
}
func (UnimplementedCronServer) GetListExecutionRecord(context.Context, *GetListExecutionRecordRequest) (*GetListExecutionRecordResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetListExecutionRecord not implemented")
}
func (UnimplementedCronServer) GetListExecutionResult(context.Context, *GetListExecutionResultRequest) (*GetListExecutionResultResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetListExecutionResult not implemented")
}
func (UnimplementedCronServer) PauseScheduleTask(context.Context, *CommonIDRequest) (*CommonResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method PauseScheduleTask not implemented")
}
func (UnimplementedCronServer) StartScheduleTask(context.Context, *CommonIDRequest) (*CommonResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method StartScheduleTask not implemented")
}
func (UnimplementedCronServer) DeleteScheduleTask(context.Context, *CommonIDRequest) (*CommonResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteScheduleTask not implemented")
}
func (UnimplementedCronServer) GetScheduleTaskStatus(context.Context, *emptypb.Empty) (*GetScheduleTaskStatusResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetScheduleTaskStatus not implemented")
}
func (s *UnimplementedCronServer) XXX_SetProxyImpl(impl protocol.Invoker) {
s.proxyImpl = impl
}
func (s *UnimplementedCronServer) XXX_GetProxyImpl() protocol.Invoker {
return s.proxyImpl
}
func (s *UnimplementedCronServer) XXX_ServiceDesc() *grpc_go.ServiceDesc {
return &Cron_ServiceDesc
}
func (s *UnimplementedCronServer) XXX_InterfaceName() string {
return "cron.Cron"
}
func (UnimplementedCronServer) mustEmbedUnimplementedCronServer() {}
// UnsafeCronServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to CronServer will
// result in compilation errors.
type UnsafeCronServer interface {
mustEmbedUnimplementedCronServer()
}
func RegisterCronServer(s grpc_go.ServiceRegistrar, srv CronServer) {
s.RegisterService(&Cron_ServiceDesc, srv)
}
func _Cron_CreateScheduleTask_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateScheduleTaskRequest)
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("CreateScheduleTask", 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 _Cron_GetListScheduleTask_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(GetListScheduleTaskRequest)
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("GetListScheduleTask", 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 _Cron_GetListExecutionRecord_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(GetListExecutionRecordRequest)
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("GetListExecutionRecord", 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 _Cron_GetListExecutionResult_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(GetListExecutionResultRequest)
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("GetListExecutionResult", 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 _Cron_PauseScheduleTask_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(CommonIDRequest)
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("PauseScheduleTask", 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 _Cron_StartScheduleTask_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(CommonIDRequest)
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("StartScheduleTask", 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 _Cron_DeleteScheduleTask_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(CommonIDRequest)
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("DeleteScheduleTask", 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 _Cron_GetScheduleTaskStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(emptypb.Empty)
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("GetScheduleTaskStatus", 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)
}
// Cron_ServiceDesc is the grpc_go.ServiceDesc for Cron service.
// It's only intended for direct use with grpc_go.RegisterService,
// and not to be introspected or modified (even as a copy)
var Cron_ServiceDesc = grpc_go.ServiceDesc{
ServiceName: "cron.Cron",
HandlerType: (*CronServer)(nil),
Methods: []grpc_go.MethodDesc{
{
MethodName: "CreateScheduleTask",
Handler: _Cron_CreateScheduleTask_Handler,
},
{
MethodName: "GetListScheduleTask",
Handler: _Cron_GetListScheduleTask_Handler,
},
{
MethodName: "GetListExecutionRecord",
Handler: _Cron_GetListExecutionRecord_Handler,
},
{
MethodName: "GetListExecutionResult",
Handler: _Cron_GetListExecutionResult_Handler,
},
{
MethodName: "PauseScheduleTask",
Handler: _Cron_PauseScheduleTask_Handler,
},
{
MethodName: "StartScheduleTask",
Handler: _Cron_StartScheduleTask_Handler,
},
{
MethodName: "DeleteScheduleTask",
Handler: _Cron_DeleteScheduleTask_Handler,
},
{
MethodName: "GetScheduleTaskStatus",
Handler: _Cron_GetScheduleTaskStatus_Handler,
},
},
Streams: []grpc_go.StreamDesc{},
Metadata: "pb/cron.proto",
}

View File

@ -57,6 +57,9 @@ dubbo:
AyrshareClientImpl:
protocol: tri
interface: com.fontree.microservices.fiee.ayrshare
FieeCronClientImpl:
protocol: tri
interface: com.fontree.microservices.fiee.cron
logger:
zap-config:
level: error # 日志级别

View File

@ -59,6 +59,9 @@ dubbo:
AyrshareClientImpl:
protocol: tri
interface: com.fontree.microservices.fiee.ayrshare
FieeCronClientImpl:
protocol: tri
interface: com.fontree.microservices.fiee.cron
logger:
zap-config:
level: error # 日志级别

View File

@ -57,6 +57,9 @@ dubbo:
AyrshareClientImpl:
protocol: tri
interface: com.fontree.microservices.fiee.ayrshare
FieeCronClientImpl:
protocol: tri
interface: com.fontree.microservices.fiee.cron
logger:
zap-config:
level: error # 日志级别

View File

@ -31,6 +31,9 @@ func InitTasks() error {
err = cm.AddTask("artistAutoConfirmAnalysis", "0 */1 * * * *", ArtistAutoConfirmAnalysisTask)
err = cm.AddTask("refreshWorkAnalysisApprovalStatus", "0 */1 * * * *", RefreshWorkAnalysisApprovalStatusTask)
err = cm.AddTask("scheduledPublish", "0 */1 * * * *", ScheduledPublishTask)
// 每天 00:30 和 12:30 执行 Ayrshare 指标采集任务
err = cm.AddTask("ayrshareMetricsCollector", "30 0,12 * * *", AyrshareMetricsCollectorTask)
if err != nil {
log.Printf("添加定时任务失败: %v", err)
}
@ -388,3 +391,8 @@ func ScheduledPublishTask() {
zap.Int("expired_count", expiredCount),
zap.Int("total_count", len(workList)))
}
// AyrshareMetricsCollectorTask Ayrshare 指标采集定时任务(每天 00:30 和 12:30 执行)
func AyrshareMetricsCollectorTask() {
serverCast.ExecuteAyrshareMetricsCollector()
}

View File

@ -10,6 +10,8 @@ import (
)
func AnalysisRouter(r *gin.RouterGroup) {
r.POST("analysis/trigger-ayrshare-metrics", serviceCast.TriggerAyrshareMetricsCollector)
analysis := r.Group("analysis")
analysis.Use(middleware.CheckWebLogin(service.AccountProvider))
{
@ -29,6 +31,7 @@ func AnalysisRouter(r *gin.RouterGroup) {
analysis.POST("artist-metrics-single", serviceCast.ArtistMetricsDailyWindow) // 艺人指标日窗口
analysis.POST("tobe-confirmed-list", serviceCast.TobeConfirmedList) // 待确认数据列表
analysis.POST("update-approval-id", serviceCast.UpdateWorkAnalysisApprovalID) // 更新作品分析审批ID
// analysis.POST("trigger-ayrshare-metrics", serviceCast.TriggerAyrshareMetricsCollector) // 手动触发 Ayrshare 指标采集任务
}

25
pkg/router/cron.go Normal file
View File

@ -0,0 +1,25 @@
package router
import (
"fonchain-fiee/pkg/middleware"
"fonchain-fiee/pkg/service"
cronService "fonchain-fiee/pkg/service/cron"
"github.com/gin-gonic/gin"
)
func cronRouter(r *gin.RouterGroup) {
auth := r.Group("")
auth.Use(middleware.CheckWebLogin(service.AccountProvider))
cron := auth.Group("cron")
{
cron.POST("createScheduleTask", cronService.CreateScheduleTask)
cron.POST("pauseScheduleTask", cronService.PauseScheduleTask)
cron.POST("startScheduleTask", cronService.StartScheduleTask)
cron.POST("deleteScheduleTask", cronService.DeleteScheduleTask)
cron.POST("getListScheduleTask", cronService.GetListScheduleTask)
cron.POST("getListExecutionResult", cronService.GetListExecutionResult)
cron.POST("getListExecutionRecord", cronService.GetListExecutionRecord)
//cron.GET("getScheduleTaskStatus", cronService.GetScheduleTaskStatus)
}
}

View File

@ -59,6 +59,7 @@ func NewRouter() *gin.Engine {
AnalysisRouter(privateGroup)
SecFilingRouter(privateGroup)
app.MediaAppRouter(privateGroup)
cronRouter(privateGroup)
{
v1.POST("version", version.Version) //版本号公共
}

View File

@ -2,8 +2,10 @@ package cast
import (
"context"
"encoding/json"
"errors"
"fmt"
"fonchain-fiee/api/aryshare"
"fonchain-fiee/api/bundle"
"fonchain-fiee/api/cast"
"fonchain-fiee/pkg/cache"
@ -17,6 +19,7 @@ import (
"dubbo.apache.org/dubbo-go/v3/common/constant"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"go.uber.org/zap"
)
@ -639,3 +642,585 @@ func autoConfirmAnalysis(ctx context.Context, analysisUuid string) (err error) {
}
return
}
// TriggerAyrshareMetricsCollector 手动触发 Ayrshare 指标采集任务
func TriggerAyrshareMetricsCollector(ctx *gin.Context) {
// 在后台 goroutine 中执行任务,避免阻塞 HTTP 请求
go func() {
// 同时使用 zap 和 fmt.Printf 确保日志输出到终端
zap.L().Info("手动触发 Ayrshare 指标采集任务")
fmt.Printf("[%s] 手动触发 Ayrshare 指标采集任务\n", time.Now().Format("2006-01-02 15:04:05"))
executeAyrshareMetricsCollector()
}()
service.Success(ctx, map[string]string{
"message": "任务已触发,正在后台执行",
})
return
}
// ExecuteAyrshareMetricsCollector 提供给定时任务调用的 Ayrshare 指标采集入口
func ExecuteAyrshareMetricsCollector() {
executeAyrshareMetricsCollector()
}
// executeAyrshareMetricsCollector 执行 Ayrshare 指标采集任务
func executeAyrshareMetricsCollector() {
ctx := context.Background()
zap.L().Info("开始执行 Ayrshare 指标采集任务")
fmt.Printf("[%s] [INFO] 开始执行 Ayrshare 指标采集任务\n", time.Now().Format("2006-01-02 15:04:05"))
// 获取当前日期中国时区格式YYYYMMDD
loc, _ := time.LoadLocation("Asia/Shanghai")
now := time.Now().In(loc)
dateCN := now.Year()*10000 + int(now.Month())*100 + now.Day()
// 第一步获取所有状态为1的艺人AyrShare信息
mediaMetricsList, err := collectMediaMetricsForAyrshare(ctx, dateCN)
if err != nil {
zap.L().Error("采集账号指标失败", zap.Error(err))
fmt.Printf("[%s] [ERROR] 采集账号指标失败: %v\n", time.Now().Format("2006-01-02 15:04:05"), err)
return
}
// 批量插入账号指标
if len(mediaMetricsList) > 0 {
req := &cast.UpsertMediaMetricsDailyBatchReq{
Data: mediaMetricsList,
}
resp, err := service.CastProvider.UpsertMediaMetricsDailyBatch(ctx, req)
if err != nil {
zap.L().Error("批量插入账号指标失败", zap.Error(err))
fmt.Printf("[%s] [ERROR] 批量插入账号指标失败: %v\n", time.Now().Format("2006-01-02 15:04:05"), err)
} else if resp != nil && resp.Success {
zap.L().Info("批量插入账号指标成功", zap.Int("count", len(mediaMetricsList)))
fmt.Printf("[%s] [INFO] 批量插入账号指标成功,数量: %d\n", time.Now().Format("2006-01-02 15:04:05"), len(mediaMetricsList))
}
}
// 第二步:获取作品指标
workMetricsList, err := collectWorkMetricsForAyrshare(ctx, dateCN)
if err != nil {
zap.L().Error("采集作品指标失败", zap.Error(err))
fmt.Printf("[%s] [ERROR] 采集作品指标失败: %v\n", time.Now().Format("2006-01-02 15:04:05"), err)
return
}
// 批量插入作品指标
if len(workMetricsList) > 0 {
req := &cast.UpsertWorkMetricsDailyBatchReq{
Data: workMetricsList,
}
resp, err := service.CastProvider.UpsertWorkMetricsDailyBatch(ctx, req)
if err != nil {
zap.L().Error("批量插入作品指标失败", zap.Error(err))
fmt.Printf("[%s] [ERROR] 批量插入作品指标失败: %v\n", time.Now().Format("2006-01-02 15:04:05"), err)
} else if resp != nil && resp.Success {
zap.L().Info("批量插入作品指标成功", zap.Int("count", len(workMetricsList)))
fmt.Printf("[%s] [INFO] 批量插入作品指标成功,数量: %d\n", time.Now().Format("2006-01-02 15:04:05"), len(workMetricsList))
}
}
zap.L().Info("Ayrshare 指标采集任务执行完成")
fmt.Printf("[%s] [INFO] Ayrshare 指标采集任务执行完成\n", time.Now().Format("2006-01-02 15:04:05"))
}
// collectMediaMetricsForAyrshare 采集账号指标
func collectMediaMetricsForAyrshare(ctx context.Context, dateCN int) ([]*cast.MediaMetricsDailyItem, error) {
metricsList := make([]*cast.MediaMetricsDailyItem, 0)
page := int32(1)
pageSize := int32(500)
fmt.Printf("[%s] [INFO] 开始采集账号指标\n", time.Now().Format("2006-01-02 15:04:05"))
for {
// 获取状态为1的艺人AyrShare信息
req := &cast.GetArtistAyrShareInfoReq{
Status: 1, // 状态为1表示有效
Page: page,
PageSize: pageSize,
}
resp, err := service.CastProvider.GetArtistAyrShareInfo(ctx, req)
if err != nil {
zap.L().Error("获取艺人AyrShare信息失败", zap.Error(err), zap.Int32("page", page))
fmt.Printf("[%s] [ERROR] 获取艺人AyrShare信息失败页码: %d, 错误: %v\n", time.Now().Format("2006-01-02 15:04:05"), page, err)
return metricsList, err
}
if resp == nil || resp.Data == nil || len(resp.Data) == 0 {
break
}
fmt.Printf("[%s] [INFO] 获取到第 %d 页艺人信息,数量: %d\n", time.Now().Format("2006-01-02 15:04:05"), page, len(resp.Data))
// 对每个艺人调用 GetSocialAnalytics
for _, artistInfo := range resp.Data {
if artistInfo.ProfileKey == "" {
zap.L().Warn("艺人ProfileKey为空跳过", zap.String("artistUuid", artistInfo.ArtistUuid))
fmt.Printf("[%s] [WARN] 艺人ProfileKey为空跳过artistUuid: %s\n", time.Now().Format("2006-01-02 15:04:05"), artistInfo.ArtistUuid)
continue
}
// 调用 GetSocialAnalytics平台为 ["instagram", "tiktok"]
socialReq := &aryshare.GetSocialAnalyticsRequest{
Platforms: []string{"instagram", "tiktok"},
ProfileKey: artistInfo.ProfileKey,
}
socialResp, err := service.AyrshareProvider.GetSocialAnalytics(ctx, socialReq)
if err != nil {
zap.L().Warn("获取社交分析数据失败", zap.Error(err), zap.String("profileKey", artistInfo.ProfileKey))
fmt.Printf("[%s] [WARN] 获取社交分析数据失败profileKey: %s, 错误: %v\n", time.Now().Format("2006-01-02 15:04:05"), artistInfo.ProfileKey, err)
continue
}
fmt.Println("socialResp", socialResp)
// 解析 JSON 数据并构建指标
items := parseSocialAnalyticsToMediaMetricsForAyrshare(socialResp, artistInfo, dateCN)
metricsList = append(metricsList, items...)
// 避免请求过于频繁
time.Sleep(200 * time.Millisecond)
}
// 如果返回的数据少于 pageSize说明已经是最后一页
if len(resp.Data) < int(pageSize) {
break
}
page++
}
fmt.Printf("[%s] [INFO] 账号指标采集完成,共采集 %d 条\n", time.Now().Format("2006-01-02 15:04:05"), len(metricsList))
fmt.Println("--------------------------------")
fmt.Println("账号的指标数据")
fmt.Println("metricsList", metricsList)
fmt.Println("--------------------------------")
return metricsList, nil
}
// parseSocialAnalyticsToMediaMetricsForAyrshare 解析社交分析数据并转换为媒体指标
func parseSocialAnalyticsToMediaMetricsForAyrshare(socialResp *aryshare.GetSocialAnalyticsResponse, artistInfo *cast.ArtistAyrShareInfo, dateCN int) []*cast.MediaMetricsDailyItem {
items := make([]*cast.MediaMetricsDailyItem, 0)
ctx := context.Background()
// 解析 Instagram 数据
if socialResp.Instagram != "" {
// 调试:打印 Instagram JSON 字符串的前500字符
instaPreview := socialResp.Instagram
if len(instaPreview) > 500 {
instaPreview = instaPreview[:500] + "..."
}
fmt.Printf("[%s] [DEBUG] Instagram JSON 字符串预览: %s\n", time.Now().Format("2006-01-02 15:04:05"), instaPreview)
item := parsePlatformDataForAyrshare(socialResp.Instagram, "instagram", artistInfo, dateCN)
if item != nil {
// 获取 Instagram 平台的用户信息
mediaInfoReq := &cast.MediaInfoByPlatformReq{
ArtistUuid: artistInfo.ArtistUuid,
PlatformID: cast.PlatformIDENUM_INS, // Instagram 平台 ID 为 3
}
mediaInfoResp, err := service.CastProvider.MediaInfoByPlatform(ctx, mediaInfoReq)
if err != nil {
zap.L().Warn("获取Instagram媒体账号信息失败", zap.Error(err), zap.String("artistUuid", artistInfo.ArtistUuid))
fmt.Printf("[%s] [WARN] 获取Instagram媒体账号信息失败artistUuid: %s, 错误: %v\n", time.Now().Format("2006-01-02 15:04:05"), artistInfo.ArtistUuid, err)
} else if mediaInfoResp != nil && mediaInfoResp.Info != nil {
// 填充媒体账号信息
item.MediaName = mediaInfoResp.Info.PlatformUserName
item.ArtistName = mediaInfoResp.Info.ArtistName
item.ArtistPhone = mediaInfoResp.Info.ArtistPhone
item.MediaAccUserID = mediaInfoResp.Info.MediaAccountUuid
fmt.Printf("[%s] [INFO] 成功获取Instagram账号信息账号名: %s\n", time.Now().Format("2006-01-02 15:04:05"), item.MediaName)
}
items = append(items, item)
fmt.Printf("[%s] [INFO] 解析 Instagram 账号指标成功,艺人: %s\n", time.Now().Format("2006-01-02 15:04:05"), artistInfo.ArtistUuid)
}
}
// 解析 TikTok 数据
if socialResp.Tiktok != "" {
// 调试:打印 TikTok JSON 字符串的前500字符
tiktokPreview := socialResp.Tiktok
if len(tiktokPreview) > 500 {
tiktokPreview = tiktokPreview[:500] + "..."
}
fmt.Printf("[%s] [DEBUG] TikTok JSON 字符串预览: %s\n", time.Now().Format("2006-01-02 15:04:05"), tiktokPreview)
item := parsePlatformDataForAyrshare(socialResp.Tiktok, "tiktok", artistInfo, dateCN)
if item != nil {
// 获取 TikTok 平台的用户信息
mediaInfoReq := &cast.MediaInfoByPlatformReq{
ArtistUuid: artistInfo.ArtistUuid,
PlatformID: cast.PlatformIDENUM_TIKTOK, // TikTok 平台 ID 为 1
}
mediaInfoResp, err := service.CastProvider.MediaInfoByPlatform(ctx, mediaInfoReq)
if err != nil {
zap.L().Warn("获取TikTok媒体账号信息失败", zap.Error(err), zap.String("artistUuid", artistInfo.ArtistUuid))
fmt.Printf("[%s] [WARN] 获取TikTok媒体账号信息失败artistUuid: %s, 错误: %v\n", time.Now().Format("2006-01-02 15:04:05"), artistInfo.ArtistUuid, err)
} else if mediaInfoResp != nil && mediaInfoResp.Info != nil {
// 填充媒体账号信息
item.MediaName = mediaInfoResp.Info.PlatformUserName
item.ArtistName = mediaInfoResp.Info.ArtistName
item.ArtistPhone = mediaInfoResp.Info.ArtistPhone
item.MediaAccUserID = mediaInfoResp.Info.MediaAccountUuid
fmt.Printf("[%s] [INFO] 成功获取TikTok账号信息账号名: %s\n", time.Now().Format("2006-01-02 15:04:05"), item.MediaName)
}
items = append(items, item)
fmt.Printf("[%s] [INFO] 解析 TikTok 账号指标成功,艺人: %s\n", time.Now().Format("2006-01-02 15:04:05"), artistInfo.ArtistUuid)
}
}
fmt.Println("items", items)
fmt.Println("items length", len(items))
return items
}
// parsePlatformDataForAyrshare 解析平台数据JSON格式
func parsePlatformDataForAyrshare(jsonData, platform string, artistInfo *cast.ArtistAyrShareInfo, dateCN int) *cast.MediaMetricsDailyItem {
// 调试:打印原始 JSON 数据截取前500字符避免日志过长
jsonPreview := jsonData
fmt.Printf("parsePlatformDataForAyrshare 原始 JSON 数据: %s\n", jsonPreview)
var rootData map[string]interface{}
if err := json.Unmarshal([]byte(jsonData), &rootData); err != nil {
zap.L().Warn("解析平台数据失败", zap.Error(err), zap.String("platform", platform))
fmt.Printf("parsePlatformDataForAyrshare 解析平台数据失败,平台: %s, 错误: %v\n", platform, err)
return nil
}
// 调试:打印根数据的所有 key
rootKeys := make([]string, 0, len(rootData))
for k := range rootData {
rootKeys = append(rootKeys, k)
}
fmt.Printf("parsePlatformDataForAyrshare 根数据字段: %v\n", rootKeys)
// 根据平台映射平台ID1 TikTok, 3 Instagram
var platformID uint32
if platform == "tiktok" {
platformID = 1
} else if platform == "instagram" {
platformID = 3
} else {
return nil
}
// 从根数据中提取 analytics 对象,实际数据在 analytics 字段下
var analyticsData map[string]interface{}
if analyticsVal, ok := rootData["analytics"]; ok {
if analyticsMap, ok := analyticsVal.(map[string]interface{}); ok {
analyticsData = analyticsMap
} else {
fmt.Printf("parsePlatformDataForAyrshare analytics 字段类型不正确: %T\n", analyticsVal)
}
} else {
fmt.Printf("[%s] [WARN] %s 根数据中没有找到 analytics 字段\n", time.Now().Format("2006-01-02 15:04:05"), platform)
}
// 如果没有 analytics 字段,尝试直接从根数据提取(兼容旧格式)
if analyticsData == nil {
analyticsData = rootData
fmt.Printf("parsePlatformDataForAyrshare 使用根数据作为 analytics 数据\n")
}
// 调试:打印 analytics 数据的所有 key帮助诊断字段名
if len(analyticsData) > 0 {
keys := make([]string, 0, len(analyticsData))
for k := range analyticsData {
keys = append(keys, k)
}
fmt.Printf("parsePlatformDataForAyrshare analytics 数据字段: %v\n", keys)
} else {
fmt.Printf("parsePlatformDataForAyrshare analytics 数据为空\n")
}
// 提取指标数据(根据 Ayrshare API 的实际返回结构)
// Instagram 字段followersCount, likeCount, mediaCount, viewsCount, commentsCount
// TikTok 字段videoCountTotal, viewCountTotal, commentCountTotal, shareCountTotal
item := &cast.MediaMetricsDailyItem{
Uuid: uuid.NewString(),
ArtistUuid: artistInfo.ArtistUuid,
MediaAccUserID: "", // MediaAccUserID 需要通过其他接口获取,暂时留空
MediaName: "", // MediaName 需要通过其他接口获取,暂时留空
ArtistName: "", // ArtistName 需要通过其他接口获取,暂时留空
ArtistPhone: "", // ArtistPhone 需要通过其他接口获取,暂时留空
PlatformID: platformID,
Date: int32(dateCN),
// 粉丝数Instagram 使用 followsCountTikTok 可能没有直接对应字段
FansCount: extractInt64ForAyrshare(analyticsData, "followsCount", "followersCount", "followers", "followerCount", "fans", "fanCount"),
// 观看量Instagram 使用 viewsCountTikTok 使用 viewCountTotal
ViewsCount: extractInt64ForAyrshare(analyticsData, "viewCountTotal", "viewsCount", "views", "viewCount", "viewCountPeriod"),
// 点赞数Instagram 使用 likeCount
LikesCount: extractInt64ForAyrshare(analyticsData, "likeCount", "likes", "likesCount", "likeCountTotal"),
// 评论数Instagram 使用 commentsCountTikTok 使用 commentCountTotal
CommentsCount: extractInt64ForAyrshare(analyticsData, "commentCountTotal", "commentsCount", "comments", "commentCount", "commentCountPeriod"),
// 分享数Instagram 使用 reachCountTikTok 使用 shareCountTotal
SharesCount: extractInt64ForAyrshare(analyticsData, "shareCountTotal", "shares", "shareCount", "sharesCount", "shareCountPeriod"),
// 视频数Instagram 使用 mediaCountTikTok 使用 videoCountTotal
VideoCount: extractInt64ForAyrshare(analyticsData, "mediaCount", "videoCountTotal", "videos", "videoCount", "videosCount"),
// 图片/媒体数Instagram 可能没有直接对应字段,使用 posts 等
ImageCount: extractInt64ForAyrshare(analyticsData, "posts", "postCount", "postsCount", "images", "imageCount", "imagesCount"),
}
// 调试:打印提取到的指标值
fmt.Printf("parsePlatformDataForAyrshare 提取的指标 - 粉丝数: %d, 观看量: %d, 点赞数: %d, 评论数: %d, 分享数: %d, 视频数: %d, 图片数: %d\n",
item.FansCount, item.ViewsCount, item.LikesCount, item.CommentsCount, item.SharesCount, item.VideoCount, item.ImageCount)
return item
}
// extractInt64ForAyrshare 从 map 中提取 int64 值,尝试多个可能的 key
// getMapKeys 获取 map 的所有键,用于调试
func getMapKeys(m map[string]interface{}) []string {
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
return keys
}
func extractInt64ForAyrshare(data map[string]interface{}, keys ...string) int64 {
for _, key := range keys {
if val, ok := data[key]; ok {
// 调试:打印找到的字段和值
fmt.Printf("extractInt64ForAyrshare 找到字段 %s, 值: %v, 类型: %T\n", key, val, val)
switch v := val.(type) {
case float64:
return int64(v)
case int64:
return v
case int:
return int64(v)
case int32:
return int64(v)
case string:
// 如果是字符串,尝试解析为数字
if key == "viewCountPeriod" || key == "commentCountPeriod" || key == "shareCountPeriod" {
// 这些字段是字符串,跳过
continue
}
// 尝试将字符串解析为数字
if num, err := strconv.ParseInt(v, 10, 64); err == nil {
return num
}
if num, err := strconv.ParseFloat(v, 64); err == nil {
return int64(num)
}
}
}
}
return 0
}
// collectWorkMetricsForAyrshare 采集作品指标
func collectWorkMetricsForAyrshare(ctx context.Context, dateCN int) ([]*cast.WorkMetricsDailyItem, error) {
metricsList := make([]*cast.WorkMetricsDailyItem, 0)
fmt.Printf("[%s] [INFO] 开始采集作品指标\n", time.Now().Format("2006-01-02 15:04:05"))
// 调用 ListWorkPlatformInfoPlatformIDs=[1,3], PublishMediaStatus=2, PageSize=99999999
req := &cast.ListWorkPlatformInfoReq{
PlatformIDs: []uint32{1, 3}, // 1 TikTok, 3 Instagram
PublishMediaStatus: 2, // 状态为2
Page: 1,
PageSize: 99999999,
}
resp, err := service.CastProvider.ListWorkPlatformInfo(ctx, req)
if err != nil {
return metricsList, err
}
fmt.Println("--------------------------------")
fmt.Println("66666666666666666666666666666")
fmt.Println("resp", resp)
fmt.Println("66666666666666666666666666666")
fmt.Println("--------------------------------")
if resp == nil || resp.Data == nil || len(resp.Data) == 0 {
zap.L().Info("没有作品平台信息")
return metricsList, nil
}
// 对每个作品调用 GetPostAnalytics
for _, platformInfo := range resp.Data {
if platformInfo.PublishMediaID == "" || platformInfo.WorkUuid == "" {
continue
}
// 只处理 TikTok(1) 和 Instagram(3) 平台
if platformInfo.PlatformID != 1 && platformInfo.PlatformID != 3 {
continue
}
// 通过 ArtistUuid 获取艺人的 AyrShare 信息,获取 profileKey
artistAyrShareReq := &cast.GetArtistAyrShareInfoReq{
ArtistUuid: platformInfo.ArtistUuid,
Status: 1, // 状态为1表示有效
Page: 1,
PageSize: 1,
}
artistAyrShareResp, err := service.CastProvider.GetArtistAyrShareInfo(ctx, artistAyrShareReq)
if err != nil || artistAyrShareResp == nil || len(artistAyrShareResp.Data) == 0 {
zap.L().Warn("获取艺人AyrShare信息失败", zap.Error(err), zap.String("artistUuid", platformInfo.ArtistUuid))
fmt.Printf("collectWorkMetricsForAyrshare 获取艺人AyrShare信息失败artistUuid: %s, 错误: %v\n", platformInfo.ArtistUuid, err)
continue
}
profileKey := artistAyrShareResp.Data[0].ProfileKey
if profileKey == "" {
zap.L().Warn("作品ProfileKey为空跳过", zap.String("workUuid", platformInfo.WorkUuid))
fmt.Printf("collectWorkMetricsForAyrshare 作品ProfileKey为空跳过workUuid: %s\n", platformInfo.WorkUuid)
continue
}
// 调用 GetPostAnalytics 接口
var postReq *aryshare.GetPostAnalyticsRequest
if platformInfo.PlatformID == 1 {
// TikTok 平台
postReq = &aryshare.GetPostAnalyticsRequest{
Id: platformInfo.PublishMediaID,
Platforms: []string{"tiktok"},
ProfileKey: profileKey,
}
} else if platformInfo.PlatformID == 3 {
// Instagram 平台
postReq = &aryshare.GetPostAnalyticsRequest{
Id: platformInfo.PublishMediaID,
Platforms: []string{"instagram"},
ProfileKey: profileKey,
}
}
postResp, err := service.AyrshareProvider.GetPostAnalytics(ctx, postReq)
fmt.Println("--------------------------------")
fmt.Println("postResp", postResp)
fmt.Println("--------------------------------")
if err != nil {
zap.L().Warn("获取作品分析数据失败", zap.Error(err), zap.String("publishMediaID", platformInfo.PublishMediaID))
fmt.Printf("collectWorkMetricsForAyrshare 获取作品分析数据失败publishMediaID: %s, 错误: %v\n", platformInfo.PublishMediaID, err)
continue
}
// 解析作品分析数据并构建指标
item := parsePostAnalyticsToWorkMetricsForAyrshare(postResp, platformInfo, dateCN)
if item != nil {
fmt.Println("--------------------------------")
fmt.Println("test")
fmt.Println("item", item)
fmt.Println("--------------------------------")
metricsList = append(metricsList, item)
fmt.Printf("collectWorkMetricsForAyrshare 解析作品指标成功workUuid: %s, platformID: %d\n", platformInfo.WorkUuid, platformInfo.PlatformID)
}
// 避免请求过于频繁
time.Sleep(200 * time.Millisecond)
}
fmt.Println("--------------------------------")
fmt.Println("metricsList", metricsList)
fmt.Println("--------------------------------")
fmt.Printf("collectWorkMetricsForAyrshare 作品指标采集完成,共采集 %d 条\n", len(metricsList))
return metricsList, nil
}
// parsePostAnalyticsToWorkMetricsForAyrshare 解析作品分析数据并转换为作品指标
func parsePostAnalyticsToWorkMetricsForAyrshare(postResp *aryshare.GetPostAnalyticsResponse, platformInfo *cast.WorkPlatformInfo, dateCN int) *cast.WorkMetricsDailyItem {
fmt.Println("--------------------------------")
fmt.Println("44444444444444444444444444444")
fmt.Println("platformInfo", platformInfo)
fmt.Println("44444444444444444444444444444")
fmt.Println("--------------------------------")
// 根据平台ID选择对应的 JSON 数据
var jsonData string
if platformInfo.PlatformID == 1 { // TikTok
jsonData = postResp.Tiktok
} else if platformInfo.PlatformID == 3 { // Instagram
jsonData = postResp.Instagram
} else {
return nil
}
if jsonData == "" {
return nil
}
// 解析 JSON 数据
var rootData map[string]interface{}
if err := json.Unmarshal([]byte(jsonData), &rootData); err != nil {
zap.L().Warn("解析作品分析数据失败", zap.Error(err))
fmt.Printf("parsePostAnalyticsToWorkMetricsForAyrshare 解析作品分析数据失败workUuid: %s, 错误: %v\n", platformInfo.WorkUuid, err)
return nil
}
// 调试:打印根数据的键
fmt.Printf("[DEBUG] 根数据包含的键: %v\n", getMapKeys(rootData))
// 从根数据中提取 analytics 对象,实际数据可能在 analytics 字段下
var analyticsData map[string]interface{}
if analyticsVal, ok := rootData["analytics"]; ok {
if analyticsMap, ok := analyticsVal.(map[string]interface{}); ok {
analyticsData = analyticsMap
fmt.Printf("analytics 字段提取数据,包含的键: %v\n", getMapKeys(analyticsData))
}
}
// 如果没有 analytics 字段,尝试直接从根数据提取(兼容旧格式)
if analyticsData == nil {
analyticsData = rootData
fmt.Printf("parsePostAnalyticsToWorkMetricsForAyrshare 使用根数据作为 analyticsData包含的键: %v\n", getMapKeys(analyticsData))
}
// 构建作品指标项,使用 ListWorkPlatformInfo 返回的字段信息
item := &cast.WorkMetricsDailyItem{
Uuid: uuid.NewString(),
WorkUuid: platformInfo.WorkUuid,
ArtistUuid: platformInfo.ArtistUuid,
MediaAccUserID: platformInfo.PlatformUserID, // 使用平台用户ID
MediaName: platformInfo.PlatformUserName, // 平台用户名
ArtistName: platformInfo.ArtistName, // 艺人名字
ArtistPhone: platformInfo.ArtistPhone, // 艺人手机号
PlatformID: platformInfo.PlatformID,
Date: int32(dateCN),
}
// 根据平台ID使用不同的字段提取逻辑
if platformInfo.PlatformID == 3 {
// Instagram 平台
// 访问量:使用 viewsCount
item.ViewsCount = extractInt64ForAyrshare(analyticsData, "viewsCount", "viewCount", "views")
// 点赞数:使用 likeCount
item.LikesCount = extractInt64ForAyrshare(analyticsData, "likeCount", "likes", "likesCount")
// 评论数Instagram 可能没有评论数字段,尝试多种可能
item.CommentsCount = extractInt64ForAyrshare(analyticsData, "commentsCount", "commentCount", "comments")
// 分享数:使用 sharesCount注意是复数形式
item.SharesCount = extractInt64ForAyrshare(analyticsData, "sharesCount", "shareCount", "shares")
// 打印解析结果
fmt.Printf("parsePostAnalyticsToWorkMetricsForAyrshare Instagram 作品指标解析完成 - workUuid: %s, 访问量: %d, 点赞数: %d, 评论数: %d, 分享数: %d\n",
platformInfo.WorkUuid,
item.ViewsCount, item.LikesCount, item.CommentsCount, item.SharesCount)
} else if platformInfo.PlatformID == 1 {
// TikTok 平台
// 访问量:使用 viewCountTotal
item.ViewsCount = extractInt64ForAyrshare(analyticsData, "viewCountTotal", "viewCount", "views", "videoViews")
// 点赞数:使用 likeCount
item.LikesCount = extractInt64ForAyrshare(analyticsData, "likeCount", "likes", "likesCount")
// 评论数:使用 commentCountTotal
item.CommentsCount = extractInt64ForAyrshare(analyticsData, "commentCountTotal", "commentCount", "comments", "commentsCount")
// 分享数:使用 shareCountTotal
item.SharesCount = extractInt64ForAyrshare(analyticsData, "shareCountTotal", "shareCount", "shares", "sharesCount")
// 打印解析结果
fmt.Printf("parsePostAnalyticsToWorkMetricsForAyrshare TikTok 作品指标解析完成 - workUuid: %s, 访问量: %d, 点赞数: %d, 评论数: %d, 分享数: %d\n",
platformInfo.WorkUuid,
item.ViewsCount, item.LikesCount, item.CommentsCount, item.SharesCount)
}
fmt.Println("--------------------------------")
fmt.Println("5555555555555555555555")
fmt.Println("item", item)
fmt.Println("5555555555555555555555")
fmt.Println("--------------------------------")
return item
}

148
pkg/service/cron/cron.go Normal file
View File

@ -0,0 +1,148 @@
package cron
import (
"context"
"errors"
"fonchain-fiee/api/cron"
"fonchain-fiee/pkg/service"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
func CreateScheduleTask(c *gin.Context) {
var req cron.CreateScheduleTaskRequest
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, errors.New("参数错误"))
return
}
res, err := service.CronProvider.CreateScheduleTask(context.Background(), &req)
if err != nil {
service.Error(c, errors.New("网络超时,请重试"))
return
}
if res.Code != 200 {
service.Error(c, errors.New(res.Message))
return
}
service.Success(c, res)
}
func GetListScheduleTask(c *gin.Context) {
var req cron.GetListScheduleTaskRequest
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, errors.New("参数错误"))
return
}
res, err := service.CronProvider.GetListScheduleTask(context.Background(), &req)
if err != nil {
service.Error(c, errors.New("网络超时,请重试"))
return
}
if res.Code != 200 {
service.Error(c, errors.New(res.Message))
return
}
service.Success(c, res)
}
func GetListExecutionRecord(c *gin.Context) {
var req cron.GetListExecutionRecordRequest
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, errors.New("参数错误"))
return
}
res, err := service.CronProvider.GetListExecutionRecord(context.Background(), &req)
if err != nil {
service.Error(c, errors.New("网络超时,请重试"))
return
}
if res.Code != 200 {
service.Error(c, errors.New(res.Message))
return
}
service.Success(c, res)
}
func GetListExecutionResult(c *gin.Context) {
var req cron.GetListExecutionResultRequest
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, errors.New("参数错误"))
return
}
res, err := service.CronProvider.GetListExecutionResult(context.Background(), &req)
if err != nil {
service.Error(c, errors.New("网络超时,请重试"))
return
}
if res.Code != 200 {
service.Error(c, errors.New(res.Message))
return
}
service.Success(c, res)
}
func StartScheduleTask(c *gin.Context) {
var req cron.CommonIDRequest
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, errors.New("参数错误"))
return
}
res, err := service.CronProvider.StartScheduleTask(context.Background(), &req)
if err != nil {
service.Error(c, errors.New("网络超时,请重试"))
return
}
if res.Code != 200 {
service.Error(c, errors.New(res.Message))
return
}
service.Success(c, res)
}
func PauseScheduleTask(c *gin.Context) {
var req cron.CommonIDRequest
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, errors.New("参数错误"))
return
}
res, err := service.CronProvider.PauseScheduleTask(context.Background(), &req)
if err != nil {
service.Error(c, errors.New("网络超时,请重试"))
return
}
if res.Code != 200 {
service.Error(c, errors.New(res.Message))
return
}
service.Success(c, res)
}
func DeleteScheduleTask(c *gin.Context) {
var req cron.CommonIDRequest
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, errors.New("参数错误"))
return
}
res, err := service.CronProvider.DeleteScheduleTask(context.Background(), &req)
if err != nil {
service.Error(c, errors.New("网络超时,请重试"))
return
}
if res.Code != 200 {
service.Error(c, errors.New(res.Message))
return
}
service.Success(c, res)
}
//func GetScheduleTaskStatus(c *gin.Context) {
// res, err := service.CronProvider.GetScheduleTaskStatus(context.Background(), &emptypb.Empty{})
// if err != nil {
// service.Error(c, errors.New("网络超时,请重试"))
// return
// }
// if res.Code != 200 {
// service.Error(c, errors.New(res.Message))
// return
// }
// service.Success(c, res)
//}

View File

@ -7,6 +7,7 @@ import (
"fonchain-fiee/api/aryshare"
"fonchain-fiee/api/bundle"
"fonchain-fiee/api/cast"
"fonchain-fiee/api/cron"
"fonchain-fiee/api/emailAlerts"
"fonchain-fiee/api/files"
"fonchain-fiee/api/governance"
@ -39,6 +40,7 @@ var ReportsProvider = new(reports.ReportsClientImpl)
var EmailAlertsProvider = new(emailAlerts.EmailAlertsClientImpl)
var MembersProvider = new(members.MembersClientImpl)
var AyrshareProvider = new(aryshare.AyrshareClientImpl)
var CronProvider = new(cron.CronClientImpl)
func init() {
config.SetConsumerService(BundleProvider)
@ -55,9 +57,8 @@ func init() {
config.SetConsumerService(EmailAlertsProvider)
config.SetConsumerService(MembersProvider)
config.SetConsumerService(AyrshareProvider)
config.SetConsumerService(FilesProvider)
config.SetConsumerService(GovernanceProvider)
config.SetConsumerService(PressReleasesProvider)
config.SetConsumerService(CronProvider)
if err := config.Load(); err != nil {
panic(err)
}