Compare commits

..

No commits in common. "main" and "dev-lzh" have entirely different histories.

111 changed files with 4135 additions and 20178 deletions

13
.gitignore vendored
View File

@ -1,12 +1,17 @@
.gitignore
.idea
.scannerwork
.vscode
# local env files
.env.local
.env.*.local
# Log files
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.idea
.vscode
# Editor directories and files
*.suo
*.ntvs*
*.njsproj
@ -27,7 +32,7 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
/cmd/runtime
/cmd/logs/*.log
/cmd/runtime/log/*.log
/build/*

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -18,9 +18,9 @@
syntax = "proto3";
package accountFiee;
import "github.com/mwitkow/go-proto-validators@v0.3.2/validator.proto";
option go_package = "./;accountFiee";
//protoc -I . -I C:\Users\lenovo\go\src --go_out=. --go-triple_out=. ./accountFiee.proto
service AccountFiee {
rpc Login (LoginRequest) returns (TokenInfo) {}
rpc RefreshToken (RefreshTokenRequest) returns (TokenInfo) {} //token
@ -62,38 +62,9 @@ service AccountFiee {
rpc VerifySliderCaptcha(VerifySliderCaptchaRequest) returns (VerifySliderCaptchaResponse) {}//
rpc SendNationMsg (SendNationMsgRequest) returns (SendMsgStatusResponse) {} // --
rpc VerifySliderStatus(VerifySliderStatusRequest) returns (VerifySliderStatusResponse) {}//
rpc SendNationTemplateMsg (SendNationMsgRequest) returns (SendMsgStatusResponse) {} // --
// submit info
rpc SaveSubmitInfo(SubmitInfoRequest) returns (CommonResponse);
//-------------------------------------------------------------
rpc CreateChatUser ( ChatUserData )returns( CreateChatUserResp ){} //
rpc UpdateChatUser ( ChatUserData )returns( CommonMsg ){} //
rpc SaveChatUser ( ChatUserData )returns( CommonMsg ){} //
rpc DeleteChatUser ( DeleteChatUserRequest )returns( CommonMsg ){} //
rpc GetChatUserDetail ( GetChatUserByIdRequest )returns( ChatUserData ){} //
rpc GetChatUserList ( GetChatUserListRequest )returns( GetChatUserListResp ){} //
rpc GetChatUserList2 ( GetChatUserListRequest2 )returns( GetChatUserListResp2 ){} //2
rpc RegisterWaiter ( RegisterWaiterRequest )returns( RegisterWaiterResp ){} //
rpc CreateChatRecord ( ChatRecordData )returns( CreateChatRecordResp ){} //ChatRecord
rpc UpdateChatRecord ( ChatRecordData )returns( CommonMsg ){} //ChatRecord
rpc SaveChatRecord ( ChatRecordData )returns( CommonMsg ){} //ChatRecord
rpc DeleteChatRecord ( DeleteChatRecordRequest )returns( CommonMsg ){} //ChatRecord
rpc GetChatRecordDetail ( GetChatRecordByIdRequest )returns( ChatRecordData ){} //ChatRecord详情
rpc GetChatRecordList ( GetChatRecordListRequest )returns( GetChatRecordListResp ){} //ChatRecord列表
rpc CreateChatMedia ( ChatMediaData )returns( CreateChatMediaResp ){} //ChatMedia
rpc UpdateChatMedia ( ChatMediaData )returns( CommonMsg ){} //ChatMedia
rpc SaveChatMedia ( ChatMediaData )returns( CommonMsg ){} //ChatMedia
rpc DeleteChatMedia ( DeleteChatMediaRequest )returns( CommonMsg ){} //ChatMedia
rpc GetChatMediaDetail ( GetChatMediaByIdRequest )returns( ChatMediaData ){} //ChatMedia详情
rpc GetChatMediaList ( GetChatMediaListRequest )returns( GetChatMediaListResp ){} //ChatMedia列表
rpc CreateChatAutoReplyRuler ( ChatAutoReplyRulerData )returns( CreateChatAutoReplyRulerResp ){} //
rpc UpdateChatAutoReplyRuler ( ChatAutoReplyRulerData )returns( CommonMsg ){} //
rpc SaveChatAutoReplyRuler ( ChatAutoReplyRulerData )returns( CommonMsg ){} //
rpc DeleteChatAutoReplyRuler ( DeleteChatAutoReplyRulerRequest )returns( CommonMsg ){} //
rpc GetChatAutoReplyRulerDetail ( GetChatAutoReplyRulerByIdRequest )returns( ChatAutoReplyRulerData ){} //
rpc GetChatAutoReplyRulerList ( GetChatAutoReplyRulerListRequest )returns( GetChatAutoReplyRulerListResp ){} //
}
message VerifySliderStatusRequest {
@ -187,7 +158,6 @@ message UserListRequest{
uint64 pageSize = 9;
string blurNameTel = 10;
repeated int64 ids = 11;
string nationality = 12;
}
message UserInfoResponse{
uint64 id = 1;
@ -208,7 +178,6 @@ message UserInfoResponse{
string subscriberNumber = 16;
string nickName = 17;
string telNum = 18;
string telAreaCode = 19;
}
message RealNameResponse{
uint64 id = 1;
@ -861,202 +830,3 @@ message SubmitInfoRequest{
string company = 4;
string phone = 5;
}
message CommonMsg{
string msg = 1;
}
enum MsgType{
UnknownMsgType = 0 ;//
TextMsgType = 1 ;//
ImageMsgType = 2 ;//
AudioMsgType = 3 ;//
VideoMsgType = 4 ;//
CardType = 5 ;//
}
message ChatRecordData{
int64 ID=1;
string createdAt=2;
string updatedAt=3;
int64 deletedAt=4;
string sessionId = 5; //UID
int64 userId = 6; //ID
string name = 7; //
string avatar = 8; //
MsgType msgType = 9; //
string content = 10; //
repeated ChatMediaData medias = 11; //
int32 waiterRead=12;// 1= 2=
int64 localStamp = 13; //
string domain =14;//
int32 role=15;//: 1= 2= 3=
}
message CreateChatRecordResp{
ChatRecordData data=1;
string msg=2;
}
message DeleteChatRecordRequest{
int64 id=1; //id
repeated int64 ids=2;//id列表
}
message GetChatRecordByIdRequest{
int64 id=1; //id
}
message GetChatRecordListRequest{
ChatRecordData query =1;
int64 page=2;
int64 pageSize=3;
string where=4;
string order=5;
}
message GetChatRecordListResp{
repeated ChatRecordData list=1;
int64 page=2;
int64 pageSize=3;
int64 Total=4;
}
message RegisterWaiterRequest{
string origin=1; //
int64 originId=2; //ID
string nickName=3; //
string avatar=4; //
string telNum=5; //
string invitationCode=6; //
string account=7;
}
message RegisterWaiterResp{
int64 userId=1;
}
message ChatMediaData{
int64 ID=1;
string createdAt=2;
string updatedAt=3;
int64 deletedAt=4;
string url = 5; //url
string md5 = 6; //md5值
string size = 7; //
string ext = 8; //
string convText=9; //
int64 duration=10;//
}
message CreateChatMediaResp{
ChatMediaData data=1;
string msg=2;
}
message DeleteChatMediaRequest{
int64 id=1; //id
repeated int64 ids=2;//id列表
}
message GetChatMediaByIdRequest{
int64 id=1; //id
}
message GetChatMediaListRequest{
ChatMediaData query =1;
int64 page=2;
int64 pageSize=3;
string where=4;
string order=5;
}
message GetChatMediaListResp{
repeated ChatMediaData list=1;
int64 page=2;
int64 pageSize=3;
int64 Total=4;
}
message GetChatUserListRequest2{
int64 page=1;
int64 pageSize=2;
string where=3;
string name=4;
repeated int64 userIdIn=5;
string account=6;
repeated int32 roleIn=7;
}
message ChatUser2{
int64 userId=1;
string name=2;
string avatar=3;
string origin=4;
int64 originId=5;
}
message GetChatUserListResp2{
repeated ChatUser2 list=1;
int64 page=2;
int64 pageSize=3;
int64 Total=4;
string where=5;
}
message ChatAutoReplyRulerData{
int64 ID = 1; //
string createdAt = 2; //
string updatedAt = 3; //
int64 deletedAt = 4; //
string title = 5; //
string ruler = 6; //
int32 status = 7; //: 1= 2=
string response =8; //
}
message CreateChatAutoReplyRulerResp{
ChatAutoReplyRulerData data=1;
string msg=2;
}
message DeleteChatAutoReplyRulerRequest{
int64 id=1; //id
repeated int64 ids=2;//id列表
}
message GetChatAutoReplyRulerByIdRequest{
int64 id=1; //id
}
message GetChatAutoReplyRulerListRequest{
ChatAutoReplyRulerData query =1;
int64 page=2;
int64 pageSize=3;
string where=4;
string order=5;
}
message GetChatAutoReplyRulerListResp{
repeated ChatAutoReplyRulerData list=1;
int64 page=2;
int64 pageSize=3;
int64 Total=4;
}
message ChatUserData{
int64 ID = 1; //
string createdAt = 2; //
string updatedAt = 3; //
int64 deletedAt = 4; //
string nickName = 5; //
string account = 6; //
int32 role = 7; // 1= 2= 3=
string origin = 8; //
int64 originId = 9; //ID
string avatar = 10; //
}
message CreateChatUserResp{
ChatUserData data=1;
string msg=2;
}
message DeleteChatUserRequest{
int64 id=1; //id
repeated int64 ids=2;//id列表
}
message GetChatUserByIdRequest{
int64 id=1; //id
}
message GetChatUserListRequest{
ChatUserData query =1;
int64 page=2;
int64 pageSize=3;
string where=4;
string order=5;
}
message GetChatUserListResp{
repeated ChatUserData list=1;
int64 page=2;
int64 pageSize=3;
int64 Total=4;
}

View File

@ -525,175 +525,3 @@ func (this *ClockLogListResponse) Validate() error {
func (this *SubmitInfoRequest) Validate() error {
return nil
}
func (this *CommonMsg) Validate() error {
return nil
}
func (this *ChatRecordData) Validate() error {
for _, item := range this.Medias {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Medias", err)
}
}
}
return nil
}
func (this *CreateChatRecordResp) 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 *DeleteChatRecordRequest) Validate() error {
return nil
}
func (this *GetChatRecordByIdRequest) Validate() error {
return nil
}
func (this *GetChatRecordListRequest) Validate() error {
if this.Query != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Query); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Query", err)
}
}
return nil
}
func (this *GetChatRecordListResp) Validate() error {
for _, item := range this.List {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("List", err)
}
}
}
return nil
}
func (this *RegisterWaiterRequest) Validate() error {
return nil
}
func (this *RegisterWaiterResp) Validate() error {
return nil
}
func (this *ChatMediaData) Validate() error {
return nil
}
func (this *CreateChatMediaResp) 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 *DeleteChatMediaRequest) Validate() error {
return nil
}
func (this *GetChatMediaByIdRequest) Validate() error {
return nil
}
func (this *GetChatMediaListRequest) Validate() error {
if this.Query != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Query); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Query", err)
}
}
return nil
}
func (this *GetChatMediaListResp) Validate() error {
for _, item := range this.List {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("List", err)
}
}
}
return nil
}
func (this *GetChatUserListRequest2) Validate() error {
return nil
}
func (this *ChatUser2) Validate() error {
return nil
}
func (this *GetChatUserListResp2) Validate() error {
for _, item := range this.List {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("List", err)
}
}
}
return nil
}
func (this *ChatAutoReplyRulerData) Validate() error {
return nil
}
func (this *CreateChatAutoReplyRulerResp) 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 *DeleteChatAutoReplyRulerRequest) Validate() error {
return nil
}
func (this *GetChatAutoReplyRulerByIdRequest) Validate() error {
return nil
}
func (this *GetChatAutoReplyRulerListRequest) Validate() error {
if this.Query != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Query); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Query", err)
}
}
return nil
}
func (this *GetChatAutoReplyRulerListResp) Validate() error {
for _, item := range this.List {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("List", err)
}
}
}
return nil
}
func (this *ChatUserData) Validate() error {
return nil
}
func (this *CreateChatUserResp) 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 *DeleteChatUserRequest) Validate() error {
return nil
}
func (this *GetChatUserByIdRequest) Validate() error {
return nil
}
func (this *GetChatUserListRequest) Validate() error {
if this.Query != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Query); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Query", err)
}
}
return nil
}
func (this *GetChatUserListResp) Validate() error {
for _, item := range this.List {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("List", err)
}
}
}
return nil
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-triple. DO NOT EDIT.
// versions:
// - protoc-gen-go-triple v1.0.8
// - protoc v4.24.0--rc1
// - protoc v3.20.3
// source: pb/bundle.proto
package bundle

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@ const _ = grpc_go.SupportPackageIsVersion7
type CastClient interface {
MediaUserList(ctx context.Context, in *MediaUserListReq, opts ...grpc_go.CallOption) (*MediaUserListResp, common.ErrorWithAttachment)
UpdateMediaAccount(ctx context.Context, in *UpdateMediaAccountReq, opts ...grpc_go.CallOption) (*UpdateMediaAccountResp, common.ErrorWithAttachment)
UnbindManager(ctx context.Context, in *UnbindManagerReq, opts ...grpc_go.CallOption) (*UnbindManagerResp, common.ErrorWithAttachment)
UnbindManager(ctx context.Context, in *UnbindManagerReq, opts ...grpc_go.CallOption) (*emptypb.Empty, common.ErrorWithAttachment)
BindManager(ctx context.Context, in *BindManagerReq, opts ...grpc_go.CallOption) (*emptypb.Empty, common.ErrorWithAttachment)
UpdateWorkImage(ctx context.Context, in *UpdateWorkImageReq, opts ...grpc_go.CallOption) (*UpdateWorkImageResp, common.ErrorWithAttachment)
UpdateWorkVideo(ctx context.Context, in *UpdateWorkVideoReq, opts ...grpc_go.CallOption) (*UpdateWorkVideoResp, common.ErrorWithAttachment)
@ -40,11 +40,6 @@ type CastClient interface {
UpdateStatus(ctx context.Context, in *UpdateStatusReq, opts ...grpc_go.CallOption) (*emptypb.Empty, common.ErrorWithAttachment)
MediaAccounts(ctx context.Context, in *MediaAccountsReq, opts ...grpc_go.CallOption) (*MediaAccountsResp, common.ErrorWithAttachment)
MediaWorks(ctx context.Context, in *MediaWorksReq, opts ...grpc_go.CallOption) (*MediaWorksResp, common.ErrorWithAttachment)
RePublish(ctx context.Context, in *RePublishReq, opts ...grpc_go.CallOption) (*RePublishResp, common.ErrorWithAttachment)
DelWork(ctx context.Context, in *DelWorkReq, opts ...grpc_go.CallOption) (*emptypb.Empty, common.ErrorWithAttachment)
WorkInfo(ctx context.Context, in *WorkInfoReq, opts ...grpc_go.CallOption) (*WorkInfoResp, common.ErrorWithAttachment)
OAuthYoutubeUrl(ctx context.Context, in *OAuthYoutubeUrlReq, opts ...grpc_go.CallOption) (*OAuthYoutubeUrlResp, common.ErrorWithAttachment)
OAuthYoutubeToken(ctx context.Context, in *OAuthYoutubeTokenReq, opts ...grpc_go.CallOption) (*OAuthYoutubeTokenResp, common.ErrorWithAttachment)
}
type castClient struct {
@ -54,7 +49,7 @@ type castClient struct {
type CastClientImpl struct {
MediaUserList func(ctx context.Context, in *MediaUserListReq) (*MediaUserListResp, error)
UpdateMediaAccount func(ctx context.Context, in *UpdateMediaAccountReq) (*UpdateMediaAccountResp, error)
UnbindManager func(ctx context.Context, in *UnbindManagerReq) (*UnbindManagerResp, error)
UnbindManager func(ctx context.Context, in *UnbindManagerReq) (*emptypb.Empty, error)
BindManager func(ctx context.Context, in *BindManagerReq) (*emptypb.Empty, error)
UpdateWorkImage func(ctx context.Context, in *UpdateWorkImageReq) (*UpdateWorkImageResp, error)
UpdateWorkVideo func(ctx context.Context, in *UpdateWorkVideoReq) (*UpdateWorkVideoResp, error)
@ -63,11 +58,6 @@ type CastClientImpl struct {
UpdateStatus func(ctx context.Context, in *UpdateStatusReq) (*emptypb.Empty, error)
MediaAccounts func(ctx context.Context, in *MediaAccountsReq) (*MediaAccountsResp, error)
MediaWorks func(ctx context.Context, in *MediaWorksReq) (*MediaWorksResp, error)
RePublish func(ctx context.Context, in *RePublishReq) (*RePublishResp, error)
DelWork func(ctx context.Context, in *DelWorkReq) (*emptypb.Empty, error)
WorkInfo func(ctx context.Context, in *WorkInfoReq) (*WorkInfoResp, error)
OAuthYoutubeUrl func(ctx context.Context, in *OAuthYoutubeUrlReq) (*OAuthYoutubeUrlResp, error)
OAuthYoutubeToken func(ctx context.Context, in *OAuthYoutubeTokenReq) (*OAuthYoutubeTokenResp, error)
}
func (c *CastClientImpl) GetDubboStub(cc *triple.TripleConn) CastClient {
@ -94,8 +84,8 @@ func (c *castClient) UpdateMediaAccount(ctx context.Context, in *UpdateMediaAcco
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/UpdateMediaAccount", in, out)
}
func (c *castClient) UnbindManager(ctx context.Context, in *UnbindManagerReq, opts ...grpc_go.CallOption) (*UnbindManagerResp, common.ErrorWithAttachment) {
out := new(UnbindManagerResp)
func (c *castClient) UnbindManager(ctx context.Context, in *UnbindManagerReq, opts ...grpc_go.CallOption) (*emptypb.Empty, common.ErrorWithAttachment) {
out := new(emptypb.Empty)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/UnbindManager", in, out)
}
@ -148,43 +138,13 @@ func (c *castClient) MediaWorks(ctx context.Context, in *MediaWorksReq, opts ...
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/MediaWorks", in, out)
}
func (c *castClient) RePublish(ctx context.Context, in *RePublishReq, opts ...grpc_go.CallOption) (*RePublishResp, common.ErrorWithAttachment) {
out := new(RePublishResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/RePublish", in, out)
}
func (c *castClient) DelWork(ctx context.Context, in *DelWorkReq, opts ...grpc_go.CallOption) (*emptypb.Empty, common.ErrorWithAttachment) {
out := new(emptypb.Empty)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/DelWork", in, out)
}
func (c *castClient) WorkInfo(ctx context.Context, in *WorkInfoReq, opts ...grpc_go.CallOption) (*WorkInfoResp, common.ErrorWithAttachment) {
out := new(WorkInfoResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/WorkInfo", in, out)
}
func (c *castClient) OAuthYoutubeUrl(ctx context.Context, in *OAuthYoutubeUrlReq, opts ...grpc_go.CallOption) (*OAuthYoutubeUrlResp, common.ErrorWithAttachment) {
out := new(OAuthYoutubeUrlResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/OAuthYoutubeUrl", in, out)
}
func (c *castClient) OAuthYoutubeToken(ctx context.Context, in *OAuthYoutubeTokenReq, opts ...grpc_go.CallOption) (*OAuthYoutubeTokenResp, common.ErrorWithAttachment) {
out := new(OAuthYoutubeTokenResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/OAuthYoutubeToken", in, out)
}
// CastServer is the server API for Cast service.
// All implementations must embed UnimplementedCastServer
// for forward compatibility
type CastServer interface {
MediaUserList(context.Context, *MediaUserListReq) (*MediaUserListResp, error)
UpdateMediaAccount(context.Context, *UpdateMediaAccountReq) (*UpdateMediaAccountResp, error)
UnbindManager(context.Context, *UnbindManagerReq) (*UnbindManagerResp, error)
UnbindManager(context.Context, *UnbindManagerReq) (*emptypb.Empty, error)
BindManager(context.Context, *BindManagerReq) (*emptypb.Empty, error)
UpdateWorkImage(context.Context, *UpdateWorkImageReq) (*UpdateWorkImageResp, error)
UpdateWorkVideo(context.Context, *UpdateWorkVideoReq) (*UpdateWorkVideoResp, error)
@ -193,11 +153,6 @@ type CastServer interface {
UpdateStatus(context.Context, *UpdateStatusReq) (*emptypb.Empty, error)
MediaAccounts(context.Context, *MediaAccountsReq) (*MediaAccountsResp, error)
MediaWorks(context.Context, *MediaWorksReq) (*MediaWorksResp, error)
RePublish(context.Context, *RePublishReq) (*RePublishResp, error)
DelWork(context.Context, *DelWorkReq) (*emptypb.Empty, error)
WorkInfo(context.Context, *WorkInfoReq) (*WorkInfoResp, error)
OAuthYoutubeUrl(context.Context, *OAuthYoutubeUrlReq) (*OAuthYoutubeUrlResp, error)
OAuthYoutubeToken(context.Context, *OAuthYoutubeTokenReq) (*OAuthYoutubeTokenResp, error)
mustEmbedUnimplementedCastServer()
}
@ -212,7 +167,7 @@ func (UnimplementedCastServer) MediaUserList(context.Context, *MediaUserListReq)
func (UnimplementedCastServer) UpdateMediaAccount(context.Context, *UpdateMediaAccountReq) (*UpdateMediaAccountResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateMediaAccount not implemented")
}
func (UnimplementedCastServer) UnbindManager(context.Context, *UnbindManagerReq) (*UnbindManagerResp, error) {
func (UnimplementedCastServer) UnbindManager(context.Context, *UnbindManagerReq) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method UnbindManager not implemented")
}
func (UnimplementedCastServer) BindManager(context.Context, *BindManagerReq) (*emptypb.Empty, error) {
@ -239,21 +194,6 @@ func (UnimplementedCastServer) MediaAccounts(context.Context, *MediaAccountsReq)
func (UnimplementedCastServer) MediaWorks(context.Context, *MediaWorksReq) (*MediaWorksResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method MediaWorks not implemented")
}
func (UnimplementedCastServer) RePublish(context.Context, *RePublishReq) (*RePublishResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method RePublish not implemented")
}
func (UnimplementedCastServer) DelWork(context.Context, *DelWorkReq) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method DelWork not implemented")
}
func (UnimplementedCastServer) WorkInfo(context.Context, *WorkInfoReq) (*WorkInfoResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method WorkInfo not implemented")
}
func (UnimplementedCastServer) OAuthYoutubeUrl(context.Context, *OAuthYoutubeUrlReq) (*OAuthYoutubeUrlResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method OAuthYoutubeUrl not implemented")
}
func (UnimplementedCastServer) OAuthYoutubeToken(context.Context, *OAuthYoutubeTokenReq) (*OAuthYoutubeTokenResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method OAuthYoutubeToken not implemented")
}
func (s *UnimplementedCastServer) XXX_SetProxyImpl(impl protocol.Invoker) {
s.proxyImpl = impl
}
@ -601,151 +541,6 @@ func _Cast_MediaWorks_Handler(srv interface{}, ctx context.Context, dec func(int
return interceptor(ctx, in, info, handler)
}
func _Cast_RePublish_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(RePublishReq)
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("RePublish", 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 _Cast_DelWork_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(DelWorkReq)
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("DelWork", 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 _Cast_WorkInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(WorkInfoReq)
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("WorkInfo", 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 _Cast_OAuthYoutubeUrl_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(OAuthYoutubeUrlReq)
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("OAuthYoutubeUrl", 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 _Cast_OAuthYoutubeToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(OAuthYoutubeTokenReq)
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("OAuthYoutubeToken", 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)
}
// Cast_ServiceDesc is the grpc_go.ServiceDesc for Cast service.
// It's only intended for direct use with grpc_go.RegisterService,
// and not to be introspected or modified (even as a copy)
@ -797,26 +592,6 @@ var Cast_ServiceDesc = grpc_go.ServiceDesc{
MethodName: "MediaWorks",
Handler: _Cast_MediaWorks_Handler,
},
{
MethodName: "RePublish",
Handler: _Cast_RePublish_Handler,
},
{
MethodName: "DelWork",
Handler: _Cast_DelWork_Handler,
},
{
MethodName: "WorkInfo",
Handler: _Cast_WorkInfo_Handler,
},
{
MethodName: "OAuthYoutubeUrl",
Handler: _Cast_OAuthYoutubeUrl_Handler,
},
{
MethodName: "OAuthYoutubeToken",
Handler: _Cast_OAuthYoutubeToken_Handler,
},
},
Streams: []grpc_go.StreamDesc{},
Metadata: "pb/fiee/cast.proto",

File diff suppressed because it is too large Load Diff

View File

@ -1,135 +0,0 @@
syntax = "proto3";
package secFilings;
//import "descriptor.proto";
//import "validator.proto";
option go_package = "./;secFilings";
service SecFilings{
rpc CreateSecFiling(CreateSecFilingReq) returns (CommonResp) {}
rpc UpdateSecFiling(UpdateSecFilingReq) returns (CommonResp) {}
rpc DetailSecFiling(DetailSecFilingReq) returns (SecFilingDetailResp) {}
rpc ListSecFiling(ListSecFilingReq) returns (SecFilingListResp) {}
rpc DeleteSecFiling(DeleteSecFilingReq)returns(CommonResp){}
rpc IsSecFilingExist(IsSecFilingExistReq) returns (IsSecFilingExistResp) {}
rpc UpdateSecFilingStatus(UpdateSecFilingStatusReq) returns(CommonResp) {}
rpc ListFormType(ListFormTypeReq) returns (FormTypeListResp) {}
rpc WebListSecFiling(WebListSecFilingReq) returns (WebListSecFilingResp) {}
}
message ListFormTypeReq{
int32 page = 1;
int32 pageSize = 2;
}
message FormTypeListResp{
int64 total = 1;
repeated FormType formType = 2;
}
message FormType{
int32 id = 1;
string formType = 2;
}
message IsSecFilingExistReq{
string filingDate = 1;
string form = 2;
string finalLink = 3;
}
message IsSecFilingExistResp{
bool exist = 1;
}
message CommonResp{
string msg = 1 [json_name="msg"];
string filingKey = 2[json_name="filing_key"];
}
message SecFiling{
int32 idx = 1 [json_name="idx"];
string filingKey = 2[json_name="filing_key"];
string filingDate = 3[json_name="filing_date"];
string form = 4[json_name="form"];
string description = 5[json_name="description"];
string formDescription = 6[json_name="form_description"];
string fileLink = 7[json_name="file_link"];
repeated DataFiles dataFiles = 8[json_name="data_files"];
string pdfFile = 9[json_name="pdf_file"];
string wordFile = 10[json_name="word_file"];
string excelFile = 11[json_name="excel_file"];
int32 status = 12[json_name="status"];
string operator = 13[json_name="operator"];
int32 operatorId = 14[json_name="operator_id"];
string createdAt =15[json_name="created_at"];
string updatedAt=16[json_name="updated_at"];
}
message DataFiles {
string description = 1[json_name="description"];
string fileUrl = 2[json_name="file_url"];
}
message CreateSecFilingReq{
string filingDate = 1;
string form = 2;
string description = 3;
string formDescription = 4;
string fileLink = 5;
repeated DataFiles dataFiles = 6;
string pdfFile = 7;
string wordFile = 8;
string excelFile = 9;
string operator = 10;
int32 operatorId = 11;
}
message UpdateSecFilingReq{
string filingKey = 1;
string form = 2;
string description = 3;
string formDescription = 4;
string fileLink = 5;
repeated DataFiles dataFiles = 6;
string pdfFile = 7;
string wordFile = 8;
string excelFile = 9;
string operator = 10;
int32 operatorId = 11;
string filingDate = 12;
}
message DetailSecFilingReq{
string filingKey = 1;
}
message SecFilingDetailResp{
string msg = 1;
SecFiling data = 2;
}
message ListSecFilingReq{
uint32 page = 1;
uint32 pageSize = 2;
string form = 3;
string filingDateBegin = 4;
string filingDateEnd = 5;
int32 status = 6;
}
message SecFilingListResp{
string msg = 1 [json_name="msg"];
uint32 total = 2 [json_name="total"];
repeated SecFiling data = 3 [json_name="data"];
}
message WebListSecFilingReq{
uint32 page = 1;
uint32 pageSize = 2;
string year = 3;
string sortField = 4;
string sortOrder = 5;
}
message WebListSecFilingResp{
string msg = 1 [json_name="msg"];
uint32 total = 2 [json_name="total"];
repeated SecFiling data = 3 [json_name="data"];
}
message DeleteSecFilingReq {
string filingKey = 1;
string operator = 2;
int32 operatorId = 3;
}
message UpdateSecFilingStatusReq{
string filingKey = 1;
int32 status = 2;
string operator = 3;
int32 operatorId = 4;
}

View File

@ -1,118 +0,0 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: secFilings.proto
package secFilings
import (
fmt "fmt"
math "math"
proto "github.com/golang/protobuf/proto"
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 *ListFormTypeReq) Validate() error {
return nil
}
func (this *FormTypeListResp) Validate() error {
for _, item := range this.FormType {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("FormType", err)
}
}
}
return nil
}
func (this *FormType) Validate() error {
return nil
}
func (this *IsSecFilingExistReq) Validate() error {
return nil
}
func (this *IsSecFilingExistResp) Validate() error {
return nil
}
func (this *CommonResp) Validate() error {
return nil
}
func (this *SecFiling) Validate() error {
for _, item := range this.DataFiles {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("DataFiles", err)
}
}
}
return nil
}
func (this *DataFiles) Validate() error {
return nil
}
func (this *CreateSecFilingReq) Validate() error {
for _, item := range this.DataFiles {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("DataFiles", err)
}
}
}
return nil
}
func (this *UpdateSecFilingReq) Validate() error {
for _, item := range this.DataFiles {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("DataFiles", err)
}
}
}
return nil
}
func (this *DetailSecFilingReq) Validate() error {
return nil
}
func (this *SecFilingDetailResp) 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 *ListSecFilingReq) Validate() error {
return nil
}
func (this *SecFilingListResp) 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 *WebListSecFilingReq) Validate() error {
return nil
}
func (this *WebListSecFilingResp) 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 *DeleteSecFilingReq) Validate() error {
return nil
}
func (this *UpdateSecFilingStatusReq) Validate() error {
return nil
}

View File

@ -1,507 +0,0 @@
// Code generated by protoc-gen-go-triple. DO NOT EDIT.
// versions:
// - protoc-gen-go-triple v1.0.8
// - protoc v3.20.3
// source: secFilings.proto
package secFilings
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
// SecFilingsClient is the client API for SecFilings 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 SecFilingsClient interface {
CreateSecFiling(ctx context.Context, in *CreateSecFilingReq, opts ...grpc_go.CallOption) (*CommonResp, common.ErrorWithAttachment)
UpdateSecFiling(ctx context.Context, in *UpdateSecFilingReq, opts ...grpc_go.CallOption) (*CommonResp, common.ErrorWithAttachment)
DetailSecFiling(ctx context.Context, in *DetailSecFilingReq, opts ...grpc_go.CallOption) (*SecFilingDetailResp, common.ErrorWithAttachment)
ListSecFiling(ctx context.Context, in *ListSecFilingReq, opts ...grpc_go.CallOption) (*SecFilingListResp, common.ErrorWithAttachment)
DeleteSecFiling(ctx context.Context, in *DeleteSecFilingReq, opts ...grpc_go.CallOption) (*CommonResp, common.ErrorWithAttachment)
IsSecFilingExist(ctx context.Context, in *IsSecFilingExistReq, opts ...grpc_go.CallOption) (*IsSecFilingExistResp, common.ErrorWithAttachment)
UpdateSecFilingStatus(ctx context.Context, in *UpdateSecFilingStatusReq, opts ...grpc_go.CallOption) (*CommonResp, common.ErrorWithAttachment)
ListFormType(ctx context.Context, in *ListFormTypeReq, opts ...grpc_go.CallOption) (*FormTypeListResp, common.ErrorWithAttachment)
WebListSecFiling(ctx context.Context, in *WebListSecFilingReq, opts ...grpc_go.CallOption) (*WebListSecFilingResp, common.ErrorWithAttachment)
}
type secFilingsClient struct {
cc *triple.TripleConn
}
type SecFilingsClientImpl struct {
CreateSecFiling func(ctx context.Context, in *CreateSecFilingReq) (*CommonResp, error)
UpdateSecFiling func(ctx context.Context, in *UpdateSecFilingReq) (*CommonResp, error)
DetailSecFiling func(ctx context.Context, in *DetailSecFilingReq) (*SecFilingDetailResp, error)
ListSecFiling func(ctx context.Context, in *ListSecFilingReq) (*SecFilingListResp, error)
DeleteSecFiling func(ctx context.Context, in *DeleteSecFilingReq) (*CommonResp, error)
IsSecFilingExist func(ctx context.Context, in *IsSecFilingExistReq) (*IsSecFilingExistResp, error)
UpdateSecFilingStatus func(ctx context.Context, in *UpdateSecFilingStatusReq) (*CommonResp, error)
ListFormType func(ctx context.Context, in *ListFormTypeReq) (*FormTypeListResp, error)
WebListSecFiling func(ctx context.Context, in *WebListSecFilingReq) (*WebListSecFilingResp, error)
}
func (c *SecFilingsClientImpl) GetDubboStub(cc *triple.TripleConn) SecFilingsClient {
return NewSecFilingsClient(cc)
}
func (c *SecFilingsClientImpl) XXX_InterfaceName() string {
return "secFilings.SecFilings"
}
func NewSecFilingsClient(cc *triple.TripleConn) SecFilingsClient {
return &secFilingsClient{cc}
}
func (c *secFilingsClient) CreateSecFiling(ctx context.Context, in *CreateSecFilingReq, opts ...grpc_go.CallOption) (*CommonResp, common.ErrorWithAttachment) {
out := new(CommonResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/CreateSecFiling", in, out)
}
func (c *secFilingsClient) UpdateSecFiling(ctx context.Context, in *UpdateSecFilingReq, opts ...grpc_go.CallOption) (*CommonResp, common.ErrorWithAttachment) {
out := new(CommonResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/UpdateSecFiling", in, out)
}
func (c *secFilingsClient) DetailSecFiling(ctx context.Context, in *DetailSecFilingReq, opts ...grpc_go.CallOption) (*SecFilingDetailResp, common.ErrorWithAttachment) {
out := new(SecFilingDetailResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/DetailSecFiling", in, out)
}
func (c *secFilingsClient) ListSecFiling(ctx context.Context, in *ListSecFilingReq, opts ...grpc_go.CallOption) (*SecFilingListResp, common.ErrorWithAttachment) {
out := new(SecFilingListResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/ListSecFiling", in, out)
}
func (c *secFilingsClient) DeleteSecFiling(ctx context.Context, in *DeleteSecFilingReq, opts ...grpc_go.CallOption) (*CommonResp, common.ErrorWithAttachment) {
out := new(CommonResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/DeleteSecFiling", in, out)
}
func (c *secFilingsClient) IsSecFilingExist(ctx context.Context, in *IsSecFilingExistReq, opts ...grpc_go.CallOption) (*IsSecFilingExistResp, common.ErrorWithAttachment) {
out := new(IsSecFilingExistResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/IsSecFilingExist", in, out)
}
func (c *secFilingsClient) UpdateSecFilingStatus(ctx context.Context, in *UpdateSecFilingStatusReq, opts ...grpc_go.CallOption) (*CommonResp, common.ErrorWithAttachment) {
out := new(CommonResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/UpdateSecFilingStatus", in, out)
}
func (c *secFilingsClient) ListFormType(ctx context.Context, in *ListFormTypeReq, opts ...grpc_go.CallOption) (*FormTypeListResp, common.ErrorWithAttachment) {
out := new(FormTypeListResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/ListFormType", in, out)
}
func (c *secFilingsClient) WebListSecFiling(ctx context.Context, in *WebListSecFilingReq, opts ...grpc_go.CallOption) (*WebListSecFilingResp, common.ErrorWithAttachment) {
out := new(WebListSecFilingResp)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/WebListSecFiling", in, out)
}
// SecFilingsServer is the server API for SecFilings service.
// All implementations must embed UnimplementedSecFilingsServer
// for forward compatibility
type SecFilingsServer interface {
CreateSecFiling(context.Context, *CreateSecFilingReq) (*CommonResp, error)
UpdateSecFiling(context.Context, *UpdateSecFilingReq) (*CommonResp, error)
DetailSecFiling(context.Context, *DetailSecFilingReq) (*SecFilingDetailResp, error)
ListSecFiling(context.Context, *ListSecFilingReq) (*SecFilingListResp, error)
DeleteSecFiling(context.Context, *DeleteSecFilingReq) (*CommonResp, error)
IsSecFilingExist(context.Context, *IsSecFilingExistReq) (*IsSecFilingExistResp, error)
UpdateSecFilingStatus(context.Context, *UpdateSecFilingStatusReq) (*CommonResp, error)
ListFormType(context.Context, *ListFormTypeReq) (*FormTypeListResp, error)
WebListSecFiling(context.Context, *WebListSecFilingReq) (*WebListSecFilingResp, error)
mustEmbedUnimplementedSecFilingsServer()
}
// UnimplementedSecFilingsServer must be embedded to have forward compatible implementations.
type UnimplementedSecFilingsServer struct {
proxyImpl protocol.Invoker
}
func (UnimplementedSecFilingsServer) CreateSecFiling(context.Context, *CreateSecFilingReq) (*CommonResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateSecFiling not implemented")
}
func (UnimplementedSecFilingsServer) UpdateSecFiling(context.Context, *UpdateSecFilingReq) (*CommonResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateSecFiling not implemented")
}
func (UnimplementedSecFilingsServer) DetailSecFiling(context.Context, *DetailSecFilingReq) (*SecFilingDetailResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method DetailSecFiling not implemented")
}
func (UnimplementedSecFilingsServer) ListSecFiling(context.Context, *ListSecFilingReq) (*SecFilingListResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListSecFiling not implemented")
}
func (UnimplementedSecFilingsServer) DeleteSecFiling(context.Context, *DeleteSecFilingReq) (*CommonResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteSecFiling not implemented")
}
func (UnimplementedSecFilingsServer) IsSecFilingExist(context.Context, *IsSecFilingExistReq) (*IsSecFilingExistResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsSecFilingExist not implemented")
}
func (UnimplementedSecFilingsServer) UpdateSecFilingStatus(context.Context, *UpdateSecFilingStatusReq) (*CommonResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateSecFilingStatus not implemented")
}
func (UnimplementedSecFilingsServer) ListFormType(context.Context, *ListFormTypeReq) (*FormTypeListResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListFormType not implemented")
}
func (UnimplementedSecFilingsServer) WebListSecFiling(context.Context, *WebListSecFilingReq) (*WebListSecFilingResp, error) {
return nil, status.Errorf(codes.Unimplemented, "method WebListSecFiling not implemented")
}
func (s *UnimplementedSecFilingsServer) XXX_SetProxyImpl(impl protocol.Invoker) {
s.proxyImpl = impl
}
func (s *UnimplementedSecFilingsServer) XXX_GetProxyImpl() protocol.Invoker {
return s.proxyImpl
}
func (s *UnimplementedSecFilingsServer) XXX_ServiceDesc() *grpc_go.ServiceDesc {
return &SecFilings_ServiceDesc
}
func (s *UnimplementedSecFilingsServer) XXX_InterfaceName() string {
return "secFilings.SecFilings"
}
func (UnimplementedSecFilingsServer) mustEmbedUnimplementedSecFilingsServer() {}
// UnsafeSecFilingsServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to SecFilingsServer will
// result in compilation errors.
type UnsafeSecFilingsServer interface {
mustEmbedUnimplementedSecFilingsServer()
}
func RegisterSecFilingsServer(s grpc_go.ServiceRegistrar, srv SecFilingsServer) {
s.RegisterService(&SecFilings_ServiceDesc, srv)
}
func _SecFilings_CreateSecFiling_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateSecFilingReq)
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("CreateSecFiling", 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 _SecFilings_UpdateSecFiling_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateSecFilingReq)
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("UpdateSecFiling", 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 _SecFilings_DetailSecFiling_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(DetailSecFilingReq)
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("DetailSecFiling", 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 _SecFilings_ListSecFiling_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(ListSecFilingReq)
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("ListSecFiling", 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 _SecFilings_DeleteSecFiling_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteSecFilingReq)
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("DeleteSecFiling", 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 _SecFilings_IsSecFilingExist_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(IsSecFilingExistReq)
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("IsSecFilingExist", 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 _SecFilings_UpdateSecFilingStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateSecFilingStatusReq)
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("UpdateSecFilingStatus", 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 _SecFilings_ListFormType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(ListFormTypeReq)
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("ListFormType", 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 _SecFilings_WebListSecFiling_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(WebListSecFilingReq)
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("WebListSecFiling", 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)
}
// SecFilings_ServiceDesc is the grpc_go.ServiceDesc for SecFilings service.
// It's only intended for direct use with grpc_go.RegisterService,
// and not to be introspected or modified (even as a copy)
var SecFilings_ServiceDesc = grpc_go.ServiceDesc{
ServiceName: "secFilings.SecFilings",
HandlerType: (*SecFilingsServer)(nil),
Methods: []grpc_go.MethodDesc{
{
MethodName: "CreateSecFiling",
Handler: _SecFilings_CreateSecFiling_Handler,
},
{
MethodName: "UpdateSecFiling",
Handler: _SecFilings_UpdateSecFiling_Handler,
},
{
MethodName: "DetailSecFiling",
Handler: _SecFilings_DetailSecFiling_Handler,
},
{
MethodName: "ListSecFiling",
Handler: _SecFilings_ListSecFiling_Handler,
},
{
MethodName: "DeleteSecFiling",
Handler: _SecFilings_DeleteSecFiling_Handler,
},
{
MethodName: "IsSecFilingExist",
Handler: _SecFilings_IsSecFilingExist_Handler,
},
{
MethodName: "UpdateSecFilingStatus",
Handler: _SecFilings_UpdateSecFilingStatus_Handler,
},
{
MethodName: "ListFormType",
Handler: _SecFilings_ListFormType_Handler,
},
{
MethodName: "WebListSecFiling",
Handler: _SecFilings_WebListSecFiling_Handler,
},
},
Streams: []grpc_go.StreamDesc{},
Metadata: "secFilings.proto",
}

View File

@ -1,4 +1,3 @@
ls api/account/*.pb.go | xargs -n1 -IX bash -c 'sed s/,omitempty// X > X.tmp && mv X{.tmp,}';
ls api/bundle/*.pb.go | xargs -n1 -IX bash -c 'sed s/,omitempty// X > X.tmp && mv X{.tmp,}';
ls api/order/*.pb.go | xargs -n1 -IX bash -c 'sed s/,omitempty// X > X.tmp && mv X{.tmp,}';
ls api/secFilings/*.pb.go | xargs -n1 -IX bash -c 'sed s/,omitempty// X > X.tmp && mv X{.tmp,}';

View File

@ -21,7 +21,6 @@ import (
"fmt"
"fonchain-fiee/cmd/config"
"fonchain-fiee/pkg/cache"
"fonchain-fiee/pkg/logger"
"fonchain-fiee/pkg/router"
)
@ -45,7 +44,6 @@ func bootstrap() (err error) {
fmt.Println(configEnv)
fmt.Println(config.AppConfig)
logger.LogInit(config.AppConfig)
////redis
redisConfig := cache.RedisConfig{
RedisDB: configEnv.Redis.RedisDB,

View File

@ -114,9 +114,6 @@ type System struct {
HttpPort string
Host string
RedirectUri string
Domain string
ErpHost string
FieeHost string
}
type Oss struct {
AccessKeyId string
@ -126,14 +123,6 @@ type Oss struct {
BaseDir string
CdnHost string
}
type ZapLog struct {
Level string
Filename string
MaxSize int
MaxAge int
MaxBackups int
}
type Mobile struct {
SK string
AK string
@ -153,7 +142,6 @@ type Config struct {
Mobile Mobile `toml:"mobile"`
Ai Ai `toml:"ai"`
Oss Oss `toml:"oss"`
ZapLog ZapLog `toml:"zapLog"`
}
/********start-配置信息*********/

View File

@ -1,33 +0,0 @@
dubbo:
registries:
demoZK:
protocol: zookeeper
timeout: 5s
address: 127.0.0.1:2181
consumer:
references:
AccountClientImpl:
protocol: tri
retries: 0
interface: com.fontree.microservices.common.Account
filter: echo,metrics,token,accesslog,sign,tps,generic_service,execute
params:
.accessKeyId: "Accountksl"
.secretAccessKey: "BSDY-FDF1-Fontree_account"
AccountFieeClientImpl:
protocol: tri
retries: 0
interface: com.fontree.microservices.common.micro.account.fiee
# filter: cshutdown,sign,fonDomainFilter,fonValidateFilter
# params:
# .accessKeyId: "Accountksl"
# .secretAccessKey: "BSDY-FDF1-Fontree_account"
BundleClientImpl:
protocol: tri
retries: 0
interface: com.fontree.microservices.fiee.bundle # must be compatible with grpc or dubbo-java
SecFilingsClientImpl:
protocol: tri
retries: 0
interface: com.fontree.microservices.fiee.SecFiling

View File

@ -1,11 +1,10 @@
[system]
Domain = "app"
Domain = "artistinfo"
AppMode = "dev"
HttpPort = ":8085"
Host = "https://common.szjixun.cn"
RedirectUri = "/api/redirect/url"
ErpHost = "http://114.218.158.24:9020"
FieeHost = "http://114.218.158.24:9020"
[bos]
Ak = "ALTAKxrqOQHnAN525Tb2GX4Bhe"
Sk = "d2ecaa9d75114d3b9f42b99014198306"
@ -35,10 +34,3 @@ Password = "Gy.123456"
[stripe]
Webhookkey = "whsec_uOQpG6IZTqtfLuePIDtfLCGJPqedSCCN"
[zapLog]
level = "info"
filename = "logs/fiee_zap.log"
max_size = 5
max_age = 30
max_backups = 30

View File

@ -4,8 +4,8 @@ dubbo:
protocol: zookeeper
timeout: 3s
# address: 121.229.45.214:9004
address: 172.16.100.93:2181
# address: 127.0.0.1:2181
# address: 172.16.100.93:2181
address: 127.0.0.1:2181
# address: 114.218.158.24:2181
consumer:
filter: tracing
@ -37,53 +37,11 @@ dubbo:
interface: com.fontree.microservices.common.micro.account.fiee
# filter: echo,metrics,token,accesslog,sign,tps,generic_service,execute,pshutdown,auth,fonValidateFilter
PaymentCentClientImpl:
protocol: tri
retries: 0
interface: com.fontree.microservices.common.payment.cent # must be compatible with grpc or dubbo-java
interface: com.fontree.microservices.common.payment # must be compatible with grpc or dubbo-java
filter: cshutdown,sign,auth
params:
.accessKeyId: "Paymentksl"
.secretAccessKey: "BSDY-FDF1-Fontree_payment"
CastClientImpl:
protocol: tri
interface: com.fontree.microservices.fiee.multicast
SecFilingsClientImpl:
protocol: tri
retries: 0
interface: com.fontree.microservices.fiee.SecFiling
logger:
zap-config:
level: error # 日志级别
development: false
disableCaller: false
disableStacktrace: false
encoding: "json"
# zap encoder 配置
encoderConfig:
messageKey: "message"
levelKey: "level"
timeKey: "time"
nameKey: "logger"
callerKey: "caller"
stacktraceKey: "stacktrace"
lineEnding: ""
levelEncoder: "capitalColor"
timeEncoder: "iso8601"
durationEncoder: "seconds"
callerEncoder: "short"
nameEncoder: ""
EncodeTime: zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000"),
EncodeDuration: zapcore.SecondsDurationEncoder,
outputPaths:
- "stderr"
errorOutputPaths:
- "stderr"
lumberjack-config:
# 写日志的文件名称
filename: "runtime/logs/fiee.log"
# 每个日志文件长度的最大大小,单位是 MiB。默认 100MiB
maxSize: 5
# 日志保留的最大天数(只保留最近多少天的日志)
maxAge: 30
# 只保留最近多少个日志文件,用于控制程序总日志的大小
maxBackups: 30
# 是否使用本地时间,默认使用 UTC 时间
localTime: true
# 是否压缩日志文件,压缩方法 gzip
compress: false

View File

@ -1,11 +1,10 @@
[system]
Domain = "app"
Domain = "artistinfo"
AppMode = "prod"
HttpPort = ":8085"
Host = "https://common.szjixun.cn"
RedirectUri = "/api/redirect/url"
ErpHost = "https://erpapi.fontree.cn"
FieeHost = "https://erpapi.fiee.com"
[bos]
Ak = "ALTAKxrqOQHnAN525Tb2GX4Bhe"
Sk = "d2ecaa9d75114d3b9f42b99014198306"
@ -35,10 +34,3 @@ CdnHost = "https://e-cdn.fontree.cn"
[stripe]
Webhookkey = "whsec_Mol32WD1KcKHUdYsSwap0LR03q2g9qNY"
[zapLog]
level = "info"
filename = "logs/fiee_zap.log"
max_size = 5
max_age = 30
max_backups = 30

View File

@ -45,47 +45,3 @@ dubbo:
CastClientImpl:
protocol: tri
interface: com.fontree.microservices.fiee.multicast
SecFilingsClientImpl:
protocol: tri
retries: 0
interface: com.fontree.microservices.fiee.SecFiling
logger:
zap-config:
level: error # 日志级别
development: false
disableCaller: false
disableStacktrace: false
encoding: "json"
# zap encoder 配置
encoderConfig:
messageKey: "message"
levelKey: "level"
timeKey: "time"
nameKey: "logger"
callerKey: "caller"
stacktraceKey: "stacktrace"
lineEnding: ""
levelEncoder: "capitalColor"
timeEncoder: "iso8601"
durationEncoder: "seconds"
callerEncoder: "short"
nameEncoder: ""
EncodeTime: zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000"),
EncodeDuration: zapcore.SecondsDurationEncoder,
outputPaths:
- "stderr"
errorOutputPaths:
- "stderr"
lumberjack-config:
# 写日志的文件名称
filename: "runtime/logs/fiee.log"
# 每个日志文件长度的最大大小,单位是 MiB。默认 100MiB
maxSize: 5
# 日志保留的最大天数(只保留最近多少天的日志)
maxAge: 30
# 只保留最近多少个日志文件,用于控制程序总日志的大小
maxBackups: 30
# 是否使用本地时间,默认使用 UTC 时间
localTime: true
# 是否压缩日志文件,压缩方法 gzip
compress: false

View File

@ -1,11 +1,10 @@
[system]
Domain = "app"
Domain = "artistinfo"
AppMode = "test"
HttpPort = ":8085"
Host = "https://common.szjixun.cn"
RedirectUri = "/api/redirect/url"
ErpHost = "http://114.218.158.24:9020"
FieeHost = "http://114.218.158.24:9020"
[bos]
Ak = "ALTAKxrqOQHnAN525Tb2GX4Bhe"
Sk = "d2ecaa9d75114d3b9f42b99014198306"
@ -22,14 +21,6 @@ BucketName = "fontree-test"
BaseDir = "fiee"
CdnHost = "https://cdn-test.szjixun.cn"
[oss]
AccessKeyId="LTAI5tLz1fSK53FQAEC9uNSb"
AccessKeysecret ="oGB9chrQzQzITXR2IGv37Ji5WxZh4j"
Endpoint = "oss-cn-hangzhou.aliyuncs.com"
BucketName = "fontree-test"
BaseDir = "fiee"
CdnHost = "https://cdn-test.szjixun.cn"
[redis]
RedisDB = "2"
RedisAddr = "172.16.100.114:6379"
@ -43,10 +34,3 @@ Password = "Gy.123456"
[stripe]
Webhookkey = "whsec_uOQpG6IZTqtfLuePIDtfLCGJPqedSCCN"
[zapLog]
level = "info"
filename = "logs/fiee_zap.log"
max_size = 5
max_age = 30
max_backups = 30

View File

@ -37,53 +37,11 @@ dubbo:
interface: com.fontree.microservices.common.micro.account.fiee
# filter: echo,metrics,token,accesslog,sign,tps,generic_service,execute,pshutdown,auth,fonValidateFilter
PaymentCentClientImpl:
protocol: tri
retries: 0
interface: com.fontree.microservices.common.payment.cent # must be compatible with grpc or dubbo-java
interface: com.fontree.microservices.common.payment # must be compatible with grpc or dubbo-java
filter: cshutdown,sign,auth
params:
.accessKeyId: "Paymentksl"
.secretAccessKey: "BSDY-FDF1-Fontree_payment"
CastClientImpl:
protocol: tri
interface: com.fontree.microservices.fiee.multicast
SecFilingsClientImpl:
protocol: tri
retries: 0
interface: com.fontree.microservices.fiee.SecFiling
logger:
zap-config:
level: error # 日志级别
development: false
disableCaller: false
disableStacktrace: false
encoding: "json"
# zap encoder 配置
encoderConfig:
messageKey: "message"
levelKey: "level"
timeKey: "time"
nameKey: "logger"
callerKey: "caller"
stacktraceKey: "stacktrace"
lineEnding: ""
levelEncoder: "capitalColor"
timeEncoder: "iso8601"
durationEncoder: "seconds"
callerEncoder: "short"
nameEncoder: ""
EncodeTime: zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000"),
EncodeDuration: zapcore.SecondsDurationEncoder,
outputPaths:
- "stderr"
errorOutputPaths:
- "stderr"
lumberjack-config:
# 写日志的文件名称
filename: "runtime/logs/fiee.log"
# 每个日志文件长度的最大大小,单位是 MiB。默认 100MiB
maxSize: 5
# 日志保留的最大天数(只保留最近多少天的日志)
maxAge: 30
# 只保留最近多少个日志文件,用于控制程序总日志的大小
maxBackups: 30
# 是否使用本地时间,默认使用 UTC 时间
localTime: true
# 是否压缩日志文件,压缩方法 gzip
compress: false

18
go.mod
View File

@ -1,14 +1,11 @@
module fonchain-fiee
go 1.21.3
toolchain go1.23.6
go 1.18
replace (
//github.com/fonchain_enterprise/utils/objstorage => ../../tyfon-/utils/objstorage
github.com/fonchain/utils/voice => ../utils/voice
github.com/fonchain_enterprise/utils/aes => ../utils/aes
github.com/fonchain_enterprise/utils/objstorage => ../utils/objstorage
//github.com/fonchain_enterprise/utils/objstorage => ../../tyfon-/utils/objstorage
)
//
@ -49,11 +46,11 @@ require (
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.11.2 // indirect
github.com/goccy/go-json v0.10.2
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gorilla/websocket v1.5.0
github.com/gorilla/websocket v1.5.0 // indirect
github.com/jinzhu/copier v0.3.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/k0kubun/pp v3.0.1+incompatible // indirect
@ -105,7 +102,6 @@ require (
github.com/PuerkitoBio/goquery v1.8.1
github.com/disintegration/imaging v1.6.2
github.com/envoyproxy/protoc-gen-validate v0.1.0
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
github.com/go-redis/redis v6.15.9+incompatible
@ -114,14 +110,14 @@ require (
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/spf13/viper v1.7.1
github.com/u2takey/ffmpeg-go v0.5.0
golang.org/x/image v0.0.0-20220902085622-e7cb96979f69
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8
)
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/aliyun/alibaba-cloud-sdk-go v1.61.18 // 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
@ -133,7 +129,6 @@ require (
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/dorlolo/simpleRequest v1.2.7 // indirect
github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5 // indirect
github.com/emicklei/go-restful/v3 v3.7.4 // indirect
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect
@ -173,7 +168,6 @@ require (
github.com/spf13/jwalterweatherman v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/tealeg/xlsx v1.0.5 // 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

12
go.sum
View File

@ -71,9 +71,8 @@ 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/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA=
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/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=
@ -188,8 +187,6 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dorlolo/simpleRequest v1.2.7 h1:I6AlEhMBSZPNQ4QjpCevhpxsPRDa3lgDOxJYYfmPTU8=
github.com/dorlolo/simpleRequest v1.2.7/go.mod h1:koVT8DQu+JK40UoMNBQjt+zomlCW8FqE0ffEzjTOWYY=
github.com/dubbogo/go-zookeeper v1.0.3/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c=
github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5 h1:XoR8SSVziXe698dt4uZYDfsmHpKLemqAgFyndQsq5Kw=
github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c=
@ -287,7 +284,6 @@ github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@ -837,8 +833,6 @@ github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gt
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ=
github.com/tevid/gohamcrest v1.1.1 h1:ou+xSqlIw1xfGTg1uq1nif/htZ2S3EzRqLm2BP+tYU0=
github.com/tevid/gohamcrest v1.1.1/go.mod h1:3UvtWlqm8j5JbwYZh80D/PVBt0mJ1eJiYgZMibh0H/k=
@ -979,9 +973,8 @@ golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8H
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 h1:Lj6HJGCSn5AjxRAH2+r35Mir4icalbqku+CLUtjnvXY=
golang.org/x/image v0.0.0-20220902085622-e7cb96979f69/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -1372,7 +1365,6 @@ 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.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=

View File

@ -17,6 +17,7 @@ func TestGptContent(t *testing.T) {
want string
wantErr bool
}{
// TODO: Add test cases.
{args: args{content: "i want many nice cars"}},
{args: args{content: "you are so beautiful,i like(把前面文字翻译成中文,去除斜杠,本括号内的忽略)"}},
{args: args{content: "有一个美丽的蓝色天空,天空下边站着一个小孩,小孩穿着绿色的衣服,绿色的帽子,帽子上有个毛毛虫(把前面文字翻译成英语,如果前面是英语则原样返回,去除斜杠,本括号内的忽略)"}},

View File

@ -1,126 +0,0 @@
// Package jwt -----------------------------
// @file : common.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/12 18:07
// -------------------------------------------
package jwt
import (
"context"
"fmt"
"fonchain-fiee/api/account"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/cmd/config"
"fonchain-fiee/pkg/common/m"
"fonchain-fiee/pkg/e"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/utils/secret"
"github.com/gin-gonic/gin"
)
// ParseToChatUser 将token信息转换为聊天室用户信息
func ParseToChatUser(c *gin.Context) (chatUserInfo *accountFiee.ChatUserData, code e.ErrorCodeType) {
//domain := c.GetHeader("Domain")
//if domain == "" {
// domain = c.GetHeader("domain")
// if domain == "" {
// domain = config.AppConfig.System.Domain
// }
//}
fmt.Println("ParseToChatUser ----------- 1")
var domain string
var err error
token := c.GetHeader(e.Authorization)
if token == "" {
fmt.Println("token is empty")
code = e.NotLogin
return
}
ctx := context.Background()
var originId int64 = 0
var newChatUser *accountFiee.ChatUserData
check := true
var fieeJwtInfo *Claims
fieeJwtInfo, err = ParseToken(token, m.JWTSecret)
if err != nil {
fmt.Printf("fiee token parse err:%v\n", err)
check = false
} else {
check = true
domain = config.AppConfig.System.Domain
originId = int64(fieeJwtInfo.ID)
newChatUser = &accountFiee.ChatUserData{
NickName: fieeJwtInfo.NickName,
Account: fieeJwtInfo.Phone,
Role: 1,
Origin: config.AppConfig.System.Domain,
OriginId: int64(fieeJwtInfo.ID),
}
domain = config.AppConfig.System.Domain
fmt.Printf("fiee token decrypt success, domain:%s , originId:%d", domain, originId)
}
fmt.Println("ParseToChatUser ----------- 2")
if !check { //erp用户校验
fmt.Println("ParseToChatUser ----------- 2.1")
token, err = secret.GetJwtFromStr(token)
if err != nil {
check = false
} else {
var fontreeJwtInfo *account.DecryptJwtResponse
fontreeJwtInfo, err = service.AccountProvider.DecryptJwt(ctx, &account.DecryptJwtRequest{Token: token, Domain: e.ErpDomain})
if err != nil || fontreeJwtInfo.IsOffline {
check = false
} else {
check = true
domain = e.ErpDomain
originId = int64(fontreeJwtInfo.ID)
newChatUser = &accountFiee.ChatUserData{
NickName: fontreeJwtInfo.NickName,
Account: fontreeJwtInfo.Account,
Role: 2,
Origin: e.ErpDomain,
OriginId: int64(fontreeJwtInfo.ID),
}
fmt.Printf("fontree token decrypt success, domain:%s , originId:%d\n", domain, originId)
}
}
}
fmt.Println("ParseToChatUser ----------- 3")
if !check {
fmt.Println("ParseToChatUser ----------- 3.1")
fmt.Println("fontree token decrypt err:", err)
code = e.NotLogin
return
}
fmt.Println("ParseToChatUser ----------- 4")
var userQueryRes *accountFiee.GetChatUserListResp
userQueryRes, err = service.AccountFieeProvider.GetChatUserList(c, &accountFiee.GetChatUserListRequest{
Query: &accountFiee.ChatUserData{Origin: domain, OriginId: originId},
Page: 1,
PageSize: 1,
})
if err != nil {
fmt.Println("ParseToChatUser ----------- 4.1")
fmt.Println("获取chat user 失败", err)
code = e.ErrorNotExistUser
return
}
if userQueryRes.Total == 0 {
fmt.Println("ParseToChatUser ----------- 4.2")
createRes, errs := service.AccountFieeProvider.CreateChatUser(c, newChatUser)
if errs == nil {
chatUserInfo = createRes.Data
} else {
fmt.Println("创建chat user 失败", errs)
code = e.ErrorNotExistUser
}
return
} else {
fmt.Println("ParseToChatUser ----------- 4.3")
chatUserInfo = userQueryRes.List[0]
}
return
}

View File

@ -57,43 +57,6 @@ var EnMessages = map[string]string{
"服务器错误": "Server error",
"验证失败,请控制拼图对齐缺口": "Verification failed, please control puzzle alignment gap",
"滑块验证状态不存在,请退出重试": "The slider verification status does not exist. Please exit and try again",
"语言不能为空": "The language cannot be empty",
"排序参数需为正整数": "The sorting parameter must be a positive integer",
"请先创建中文版本套餐": "Please create the Chinese version bundle first",
"增值服务不存在": "Value-added service does not exist",
"所选增值服务币种与套餐币种不一致": "The selected value-added service currency is not the same as the bundle currency",
"文件转换失败": "File conversion failed",
"每种增值服务类型只可选择一个": "Each type of value-added service can only be selected once",
"保存套餐与增值服务关联失败": "Failed to save bundle with value-added service association",
"删除套餐与增值服务关联失败": "Failed to delete bundle with value-added service association",
"查询套餐与增值服务关联失败": "Failed to query bundle with value-added service association",
"更新套餐与增值服务关联失败": "Failed to update bundle with value-added service association",
"查询增值服务失败": "Failed to query value-added service",
"更新套餐状态失败": "Failed to update bundle status",
"查询增值服务详情失败": "Failed to query value-added service details",
"序列化转换失败": "Serialization conversion failed",
"保存套餐历史记录失败": "Failed to save bundle history record",
"原价不能为空": "Original price cannot be empty",
"原价格式转换失败": "Original price format conversion failed",
"数量参数需为0-99": "Quantity parameter must be between 0 and 99",
"优惠单价需小于等于原价": "The discounted price must be less than or equal to the original price",
"请先创建中文版本增值服务": "Please create the Chinese version value-added service first",
"保存增值服务失败": "Failed to save value-added service",
"保存增值服务历史记录失败": "Failed to save value-added service history record",
"更新增值服务失败": "Failed to update value-added service",
"查询增值服务列表失败": "Failed to query value-added service list",
"计算价格失败": "Failed to calculate price",
"更新成功": "Update successful",
"保存成功": "Save successful",
"优惠单价转换失败": "Discount unit price conversion failed",
"符号错误": "Symbol error",
"条件存在冲突,请重新设置": "Condition conflict exists, please reconfigure",
"币种已修改,已取消关联部分增值服务": "Currency has been modified, some value-added services have been unlinked",
"币种已修改,已取消关联部分套餐": "Currency has been modified, some packages have been unlinked",
"新增增值服务成功": "Successfully added value-added service",
"状态值无效": "Invalid status value",
"套餐已上架,请勿重复操作": "Plan is already published, do not repeat the operation",
"套餐已下架,请勿重复操作": "Plan is already unpublished, do not repeat the operation",
"请先实名": "Please use your real name first",
"实名审核中": "Real-name verification is underway",
"实名审核失败": "The real-name verification failed",
@ -149,43 +112,6 @@ var DeDEMessages = map[string]string{
"服务器错误": "Serverfehler",
"验证失败,请控制拼图对齐缺口": "Überprüfung fehlgeschlagen, bitte Steuerung Puzzle-Ausrichtungslücke",
"滑块验证状态不存在,请退出重试": "Die krümmbestätigung existiert nicht. Bitte beenden sie den vorgang",
"语言不能为空": "Sprache darf nicht leer sein",
"排序参数需为正整数": "Sortierparameter muss eine positive ganze Zahl sein",
"请先创建中文版本套餐": "Bitte erstelle das Chinese Version-Paket",
"增值服务不存在": "Der Werbeangebot existiert nicht",
"所选增值服务币种与套餐币种不一致": "Die ausgewählte Währung des Werbeangebots stimmt nicht mit der Währung des Pakets überein",
"文件转换失败": "Datei-Umwandlung fehlgeschlagen",
"每种增值服务类型只可选择一个": "Jeder Werbeangebotstyp kann nur einmal ausgewählt werden",
"保存套餐与增值服务关联失败": "Fehler beim Speichern des Pakets mit Werbeangebot",
"删除套餐与增值服务关联失败": "Fehler beim Löschen des Pakets mit Werbeangebot",
"查询套餐与增值服务关联失败": "Fehler beim Abrufen des Pakets mit Werbeangebot",
"更新套餐与增值服务关联失败": "Fehler beim Aktualisieren des Pakets mit Werbeangebot",
"查询增值服务失败": "Fehler beim Abrufen des Werbeangebots",
"更新套餐状态失败": "Fehler beim Aktualisieren des Paketstatus",
"查询增值服务详情失败": "Fehler beim Abrufen der Werbeangebotsdetails",
"序列化转换失败": "Fehler beim Serialisieren",
"保存套餐历史记录失败": "Fehler beim Speichern des Pakethistorie",
"原价不能为空": "Der reguläre Preis darf nicht leer sein",
"原价格式转换失败": "Fehler beim Umwandeln des regulären Preises",
"数量参数需为0-99": "Die Anzahlsmusterparameter muss eine positive ganze Zahl sein",
"优惠单价需小于等于原价": "Der Rabattpreis muss kleiner oder gleich dem regulären Preis sein",
"请先创建中文版本增值服务": "Bitte erstelle das Chinese Version-Werbeangebot",
"保存增值服务失败": "Fehler beim Speichern des Werbeangebots",
"保存增值服务历史记录失败": "Fehler beim Speichern des Werbeangebots-Historie",
"更新增值服务失败": "Fehler beim Aktualisieren des Werbeangebots",
"查询增值服务列表失败": "Fehler beim Abrufen der Werbeangebotsliste",
"计算价格失败": "Fehler beim Berechnen des Preises",
"更新成功": "Aktualisierung erfolgreich",
"保存成功": "Speichern erfolgreich",
"优惠单价转换失败": "Rabatt-Einzelpreisumrechnung fehlgeschlagen",
"符号错误": "Symbolfehler",
"条件存在冲突,请重新设置": "Bedingungskonflikt vorhanden, bitte neu konfigurieren",
"币种已修改,已取消关联部分增值服务": "Währung wurde geändert, einige Mehrwertdienste wurden getrennt",
"币种已修改,已取消关联部分套餐": "Währung wurde geändert, einige Pakete wurden getrennt",
"新增增值服务成功": "Mehrwertdienst erfolgreich hinzugefügt",
"状态值无效": "Ungültiger Statuswert",
"套餐已上架,请勿重复操作": "Paket ist bereits veröffentlicht, bitte nicht wiederholen",
"套餐已下架,请勿重复操作": "Paket ist bereits zurückgezogen, bitte nicht wiederholen",
"请先实名": "Bitte, nur der name",
"实名审核中": "Contest läuft",
"实名审核失败": "Die confirmation hat versagt",
@ -241,44 +167,6 @@ var JaJPMessages = map[string]string{
"服务器错误": "サーバーエラー",
"验证失败,请控制拼图对齐缺口": "検証に失敗しました。パズルの整列ギャップを制御してください",
"滑块验证状态不存在,请退出重试": "スライダー検証状態が存在しません,リトライをログアウトしてください",
"语言不能为空": "言語が空です",
"排序参数需为正整数": "ソートパラメーターは正の整数でなければなりません",
"请先创建中文版本套餐": "最初に中国語バージョンのパッケージを作成してください",
"增值服务不存在": "付加サービスは存在しません",
"所选增值服务币种与套餐币种不一致": "選択した付加サービスの通貨とパッケージの通貨が一致しません",
"文件转换失败": "ファイル変換に失敗しました",
"每种增值服务类型只可选择一个": "各種付加サービスタイプは一つしか選択できません",
"保存套餐与增值服务关联失败": "パッケージと付加サービスの関連付けの保存に失敗しました",
"删除套餐与增值服务关联失败": "パッケージと付加サービスの関連付けの削除に失敗しました",
"查询套餐与增值服务关联失败": "パッケージと付加サービスの関連付けの検索に失敗しました",
"更新套餐与增值服务关联失败": "パッケージと付加サービスの関連付けの更新に失敗しました",
"查询增值服务失败": "付加サービスの検索に失敗しました",
"更新套餐状态失败": "パッケージステータスの更新に失敗しました",
"查询增值服务详情失败": "付加サービスの詳細検索に失敗しました",
"序列化转换失败": "シリアライズ変換に失敗しました",
"保存套餐历史记录失败": "パッケージ履歴の保存に失敗しました",
"原价不能为空": "原価は空にできません",
"原价格式转换失败": "原価のフォーマット変換に失敗しました",
"数量参数需为0-99": "数量パラメーターは0-99でなければなりません",
"优惠单价需小于等于原价": "割引単価は原価以下でなければなりません",
"请先创建中文版本增值服务": "最初に中国語バージョンの付加サービスを作成してください",
"保存增值服务失败": "付加サービスの保存に失敗しました",
"保存增值服务历史记录失败": "付加サービス履歴の保存に失敗しました",
"更新增值服务失败": "付加サービスの更新に失敗しました",
"查询增值服务列表失败": "付加サービスリストの検索に失敗しました",
"计算价格失败": "価格計算に失敗しました",
"更新成功": "更新が成功しました",
"保存成功": "保存が成功しました",
"优惠单价转换失败": "割引単価変換に失敗しました",
"符号错误": "記号エラー",
"条件存在冲突,请重新设置": "条件が競合しています、再設定してください",
"币种已修改,已取消关联部分增值服务": "通貨が変更され、一部の付加サービスの関連付けが解除されました",
"币种已修改,已取消关联部分套餐": "通貨が変更され、一部のパッケージの関連付けが解除されました",
"新增增值服务成功": "付加サービスの追加に成功しました",
"状态值无效": "状態値が無効です",
"套餐已上架,请勿重复操作": "プランはすでに公開済みです、重複操作は避けてください",
"套餐已下架,请勿重复操作": "プランはすでに非公開です、重複操作は避けてください",
"请先实名": "まずは実名でお願いします",
"实名审核中": "実名審査中です",
"实名审核失败": "実名検証失敗です",
@ -334,44 +222,6 @@ var ZhTWMessages = map[string]string{
"服务器错误": "服務器錯誤",
"验证失败,请控制拼图对齐缺口": "驗證失敗,請控制拼圖對齊缺口",
"滑块验证状态不存在,请退出重试": "滑塊驗證狀態不存在,請退出重試",
"语言不能为空": "語言不能為空",
"排序参数需为正整数": "排序參數需為正整數",
"请先创建中文版本套餐": "請先建立中文版本套餐",
"增值服务不存在": "增值服務不存在",
"所选增值服务币种与套餐币种不一致": "所選增值服務幣種與套餐幣種不一致",
"文件转换失败": "文件轉換失敗",
"每种增值服务类型只可选择一个": "每種增值服務類型只可選擇一個",
"保存套餐与增值服务关联失败": "保存套餐與增值服務關聯失敗",
"删除套餐与增值服务关联失败": "刪除套餐與增值服務關聯失敗",
"查询套餐与增值服务关联失败": "查詢套餐與增值服務關聯失敗",
"更新套餐与增值服务关联失败": "更新套餐與增值服務關聯失敗",
"查询增值服务失败": "查詢增值服務失敗",
"更新套餐状态失败": "更新套餐狀態失敗",
"查询增值服务详情失败": "查詢增值服務詳情失敗",
"序列化转换失败": "序列化轉換失敗",
"保存套餐历史记录失败": "保存套餐歷史記錄失敗",
"原价不能为空": "原價不能為空",
"原价格式转换失败": "原價格式轉換失敗",
"数量参数需为0-99": "數量參數需為0-99",
"优惠单价需小于等于原价": "優惠單價需小於等於原價",
"请先创建中文版本增值服务": "請先建立中文版本增值服務",
"保存增值服务失败": "保存增值服務失敗",
"保存增值服务历史记录失败": "保存增值服務歷史記錄失敗",
"更新增值服务失败": "更新增值服務失敗",
"查询增值服务列表失败": "查詢增值服務列表失敗",
"计算价格失败": "計算價格失敗",
"更新成功": "更新成功",
"保存成功": "儲存成功",
"优惠单价转换失败": "優惠單價轉換失敗",
"符号错误": "符號錯誤",
"条件存在冲突,请重新设置": "條件存在衝突,請重新設定",
"币种已修改,已取消关联部分增值服务": "幣種已修改,已取消關聯部分增值服務",
"币种已修改,已取消关联部分套餐": "幣種已修改,已取消關聯部分套餐",
"新增增值服务成功": "新增增值服務成功",
"状态值无效": "狀態值無效",
"套餐已上架,请勿重复操作": "套餐已上架,請勿重複操作",
"套餐已下架,请勿重复操作": "套餐已下架,請勿重複操作",
"请先实名": "請先實名",
"实名审核中": "實名審覈中",
"实名审核失败": "實名審覈失敗",
@ -380,10 +230,4 @@ var ZhTWMessages = map[string]string{
"展示数量不能超过5个": "展示數量不能超過5個",
"查询失败": "查詢失敗",
"操作失败": "操作失敗",
"参数缺失": "參數缺失",
"创建失败": "創建失敗",
"更新失败": "更新失敗",
"删除失败": "刪除失敗",
"更新状态失败": "更新狀態失敗",
}

View File

@ -1,167 +0,0 @@
// Package ws -----------------------------
// @file : hertzWSUpgrade.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2022/6/28 14:14
// -------------------------------------------
package ws
import (
"encoding/json"
"fonchain-fiee/pkg/e"
"fonchain-fiee/pkg/serializer"
"strings"
)
// 消息结构
type WSMessage struct {
Type string `json:"type"`
Data string `json:"data"`
}
// websocket消息内容
type WsInfo struct {
Type WsType `json:"type"` //消息类型
Content interface{} `json:"content"` //消息内容
From string `json:"from"` //发送者 0为服务端,客户端填写clientId
To string `json:"to"` //接收者 接收消息的用户id
Mark string `json:"mark"`
//Conn *websocket.Conn `json:"-"` //客户端发送消息使用
}
type WsSessionInfo struct {
Type WsType `json:"type"` //消息类型
//SessionId string `json:"sessionId"` //会话Id
Content interface{} `json:"content"` //消息内容
}
// 身份认证消息
type AuthorizationInfo struct {
Type WsType `json:"type"` //消息类型
Content AuthInfo `json:"content"`
}
type AuthInfo struct {
Auth string `json:"auth"`
Domain string `json:"domain"`
}
// 注册消息
type WsRegisterInfo struct {
Type WsType `json:"type"` //消息类型
Content UserInfo `json:"content"` //消息内容
From string `json:"from"` //发送者 0为服务端,客户端填写clientId
To string `json:"to"` //接收者 接收消息的用户id
//Conn *websocket.Conn `json:"-"` //客户端发送消息使用
}
type UserInfo struct {
Uuid string `json:"uuid"` //画家uid
UserId int64 `json:"userId"` //用户id
ClientId string `json:"clientId,omitempty"` //服务端临时签发的客户端uid
}
type TempClientInfo struct {
ClientId string `json:"clientId"`
}
func WsMessageRegisterCallback(clientId string) []byte {
var errMsg = WsInfo{
Type: RegisterType,
Content: map[string]string{
"clientId": clientId,
},
From: "0",
To: clientId,
}
byteMsg, _ := json.Marshal(errMsg)
return byteMsg
}
func WsErrorMessage(wsType WsType, clientId string, code e.ErrorCodeType, err error) []byte {
var ers string
if err != nil {
ers = err.Error()
}
var content = serializer.Response{
Code: code,
Err: ers,
Msg: code.String(),
}
var errMsg = WsInfo{
Type: wsType,
Content: content,
From: "0",
To: clientId,
}
byteMsg, _ := json.Marshal(errMsg)
return byteMsg
}
func WsErrorPermissionDenied(wsType WsType, clientId string) []byte {
var content = serializer.Response{
Code: e.PermissionDenied,
Err: "Permission Denied",
Msg: "拒绝访问",
}
var errMsg = WsInfo{
Type: wsType,
Content: content,
From: "0",
To: clientId,
}
byteMsg, _ := json.Marshal(errMsg)
return byteMsg
}
func WsErrorInvalidDataFormat(clientId string) []byte {
var content = serializer.Response{
Status: e.Failed,
Code: e.Failed,
Err: "Invalid Data Format",
Msg: "发送失败",
}
var errMsg = WsInfo{
Type: ErrorType,
Content: content,
From: "0",
To: clientId,
}
byteMsg, _ := json.Marshal(errMsg)
return byteMsg
}
func WsErrorUnknownMessageType(clientId string) []byte {
var errMsg = WsInfo{
Type: ErrorType,
Content: "Unknown notice type",
From: "0",
To: clientId,
}
byteMsg, _ := json.Marshal(errMsg)
return byteMsg
}
func WsErrorConnection(clientId string, err string, marks ...string) []byte {
mark := ""
if marks != nil {
mark = strings.Join(marks, ";")
}
var errMsg = WsInfo{
Type: ErrorType,
Content: "Connection error:" + err,
From: "0",
To: clientId,
Mark: mark,
}
byteMsg, _ := json.Marshal(errMsg)
return byteMsg
}
func WsChatMessage(clientId string, targetClientId string, msg string) []byte {
var errMsg = WsInfo{
Type: ChatType,
Content: msg,
From: clientId,
To: targetClientId,
}
byteMsg, _ := json.Marshal(errMsg)
return byteMsg
}

View File

@ -1,392 +0,0 @@
// Package ws -----------------------------
// @file : chatRoom.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2022/10/21 18:17:17
// -------------------------------------------
package ws
import (
"encoding/json"
"fmt"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/utils"
"github.com/gorilla/websocket"
"go.uber.org/zap"
"log"
"runtime"
"strconv"
"sync"
"time"
)
const (
// Time allowed to write a notice to the peer.
writeWait = 10 * time.Second
// Time allowed to read the next pong notice from the peer.
pongWait = 60 * time.Second
// Send pings to peer with this period. Must be less than pongWait.
pingPeriod = (pongWait * 9) / 10
// Maximum notice size allowed from peer.
maxMessageSize = 1024
)
func NewChatRoom() *ChatRoom {
var room = ChatRoom{
clientsRwLocker: &sync.RWMutex{},
clients: make(map[int64]map[string]*Client),
register: make(clientChan),
UnRegister: make(clientChan),
broadcast: make(broadcastChan),
eventBus: []*EventListener{},
EventRwLocker: &sync.RWMutex{},
}
go room.Run()
return &room
}
type broadcastMessage struct {
UserIds []int64
message []byte
}
type ChatRoomEvent struct {
ListenEvent []ListenEvent
message []byte
SenderId int64
ReceiverIds []int64
}
type (
// Client类型数据管道
clientChan chan *Client
broadcastChan chan *broadcastMessage
)
type ChatRoom struct {
clientsRwLocker *sync.RWMutex
EventRwLocker *sync.RWMutex
//clients 客户端信息存储
//// 支持多客户端连接 map[userId]map[clientId]*Client
clients map[int64]map[string]*Client
//会话 map[sessionId][]*Client
Session map[string][]*Client
//register register 注册管道
register clientChan
//unRegister 注销管道 接收需要注销的客户端
UnRegister clientChan
// 消息广播管道
broadcast broadcastChan
// 事件广播管道,向其它程序推送消息
eventBus []*EventListener
}
func (o *ChatRoom) Run() {
//消息分发
for {
select {
// 注册事件
case newClient := <-o.register:
o.pushEvent(EventUserJoin, EventProgressBefore, nil, newClient)
o.clientsRwLocker.Lock()
//添加到客户端集合中
if o.clients[newClient.UserId] == nil {
o.clients[newClient.UserId] = make(map[string]*Client)
}
o.clients[newClient.UserId][newClient.ClientId] = newClient
//添加到会话集合中
if o.Session == nil {
o.Session = make(map[string][]*Client)
}
if newClient.Waiter {
//客服人员没有默认会话窗口,而是自动加入所有用户的会话
for sessionId, _ := range o.Session {
sessionId := sessionId
if sessionId != newClient.SessionId {
for _, client := range o.clients[newClient.UserId] {
o.Session[sessionId] = append(o.Session[sessionId], client)
}
}
}
// 将自己加入会话
o.Session[newClient.SessionId] = append(o.Session[newClient.SessionId], newClient)
} else {
//普通用户添加会话的逻辑
_, ok := o.Session[newClient.SessionId]
if !ok {
o.Session[newClient.SessionId] = make([]*Client, 0)
//把客服拉入会话
for userId, clientInfo := range o.clients {
if userId == newClient.UserId {
continue
}
for i, client := range clientInfo {
if client != nil && client.Waiter {
//把客服人员客户端加入会话中
o.Session[newClient.SessionId] = append(o.Session[newClient.SessionId], clientInfo[i])
}
}
}
}
// 将自己加入会话
o.Session[newClient.SessionId] = append(o.Session[newClient.SessionId], newClient)
}
o.clientsRwLocker.Unlock() // 统一在最后解锁
o.pushEvent(EventUserJoin, EventProgressAfter, nil, newClient)
//注销事件
case client := <-o.UnRegister:
o.pushEvent(EventUserLeave, EventProgressBefore, nil, client)
//panic 恢复
defer func() {
if r := recover(); r != "" {
const size = 64 << 10
buf := make([]byte, size)
buf = buf[:runtime.Stack(buf, false)]
err, ok := r.(error)
if !ok {
err = fmt.Errorf("%v", r)
}
log.Fatal("close webosocket connection occured panic , recovered!", zap.Any("client", client), zap.Error(err), zap.String("stack", string(buf)))
}
}()
fmt.Println("ws客户端注销事件触发")
//从客户端集合中删除
if _, ok := o.clients[client.UserId]; ok {
if client != nil && client.Conn != nil {
//_ = client.Conn.WriteMessage(websocket.CloseMessage, []byte{})
_ = client.Conn.Close()
}
o.clients[client.UserId][client.ClientId] = nil
delete(o.clients[client.UserId], client.ClientId)
fmt.Printf("ws客户端%s 被注销\n", client.ClientId)
}
o.pushEvent(EventUserLeave, EventProgressAfter, nil, client)
// 消息群发事件
case messageInfo := <-o.broadcast:
o.Broadcast(messageInfo.message, messageInfo.UserIds...)
}
}
}
func (o *ChatRoom) Register(c *Client) (sessionId string) {
if c.SessionId == "" && !c.Waiter {
//这里的c经常拿不到sessionId所以使用userId固定死
//c.SessionId = fmt.Sprintf("%d-%d", c.UserId, time.Now().Unix())
c.SessionId = fmt.Sprintf("%d", c.UserId)
}
o.register <- c
return c.SessionId
}
// SendSessionMessage
// sendUserId: 发送消息的用户id消息提醒时此用户将会被排除
// sessionId 会话id
// msgType 消息类型
// message: 消息内容
func (o *ChatRoom) SendSessionMessage(sender *accountFiee.ChatUserData, sessionId string, msgType WsType, message any) (userIdInSession []int64, err error) {
fmt.Println("ChatRoom.SendSessionMessage ------------------1")
o.clientsRwLocker.Lock()
defer o.clientsRwLocker.Unlock()
var msg = WsSessionInfo{
Type: msgType,
Content: message,
}
fmt.Println("ChatRoom.SendSessionMessage ------------------2")
msgBytes, _ := json.Marshal(msg)
if o.Session[sessionId] == nil {
err = fmt.Errorf("该会话不存在或已失效")
return
}
fmt.Println("ChatRoom.SendSessionMessage ------------------3")
usableClients := []*Client{}
fmt.Printf("sessionId:[%s],客户端数量%d\n", sessionId, len(o.Session[sessionId]))
pushed := false
for i, client := range o.Session[sessionId] {
if client != nil {
_, exist := o.clients[client.UserId][client.ClientId]
if exist {
usableClients = append(usableClients, o.Session[sessionId][i])
if !pushed {
go o.pushEvent(EventChatMessage, EventProgressBefore, sender, o.Session[sessionId][i], message)
pushed = true
}
}
}
fmt.Printf("client:%+v\n", client)
pushed = false
if client != nil && (client.UserId != sender.ID || sender.Role == 3) {
client.Send <- msgBytes
if !pushed {
go o.pushEvent(EventChatMessage, EventProgressAfter, sender, o.Session[sessionId][i], message)
pushed = true
}
userIdInSession = append(userIdInSession, client.UserId)
}
//client.Send <- msgBytes
}
o.Session[sessionId] = usableClients
fmt.Printf("sessionId:[%s],客户端数量%d\n", sessionId, len(o.Session[sessionId]))
fmt.Println("userIdInSession", userIdInSession)
return
}
func (o *ChatRoom) GetUserIdInSession(sessionId string, withoutUserId ...int64) (userIds []int64) {
fmt.Printf("sessionId:%s withoutUserId:%d\n", sessionId, withoutUserId)
fmt.Println("GetUserIdInSession 1")
if o.Session[sessionId] != nil {
fmt.Printf("GetUserIdInSession 2,o.Session[sessionId]:%+v", o.Session[sessionId])
for _, client := range o.Session[sessionId] {
fmt.Println("session one of userId", client.UserId)
var jump bool
if withoutUserId != nil {
for _, userId := range withoutUserId {
if client.UserId == userId {
jump = true
break
}
}
}
if !jump {
fmt.Println("ADD USER", client.UserId)
userId := client.UserId
userIds = append(userIds, userId)
}
}
}
//针对app没有连接上websocket(聊天室没有检查到用户的客户端此时websocket无法发送通知)但是需要推送app通知给用户的情况进行优化
fmt.Println("GetUserIdInSession 3,userIds:", userIds)
if len(userIds) == 0 {
sessionUserId, _ := strconv.Atoi(sessionId)
add := true
if sessionUserId != 0 {
for _, v := range withoutUserId {
if v == int64(sessionUserId) {
add = false
break
}
}
}
if add {
userIds = append(userIds, int64(sessionUserId))
}
fmt.Println("GetUserIdInSession 4,userIds:", userIds)
}
userIds = utils.Unique(userIds)
fmt.Println("GetUserIdInSession 5,userIds:", userIds)
return
}
// func (o *ChatRoom) RegisterClient(c *Client) {
// o.register <- c
// }
//
// func (o *ChatRoom) DeleteClient(c *Client) {
// o.unRegister <- c
// }
func (o *ChatRoom) Broadcast(message []byte, userIds ...int64) {
fmt.Println("Broadcast -------1")
// 如果userIds为空则群发,否则找到这个用户的ws对象
var clientsToSend []*Client
if userIds == nil {
for _, userClients := range o.clients {
for _, cli := range userClients {
if cli != nil {
clientsToSend = append(clientsToSend, cli)
}
}
}
} else {
for _, userId := range userIds {
userClients, ok := o.clients[userId]
if !ok {
continue
}
for _, cli := range userClients {
if cli != nil {
clientsToSend = append(clientsToSend, cli)
}
}
}
}
// 使用有限的goroutine池发送消息
fmt.Println("Broadcast -------2")
var wg sync.WaitGroup
for _, cli := range clientsToSend {
wg.Add(1)
go func(client *Client) {
defer wg.Done()
err := client.Conn.SetWriteDeadline(time.Now().Add(writeWait))
err = client.Conn.WriteMessage(websocket.TextMessage, message)
if err != nil {
o.UnRegister <- client
}
}(cli)
}
wg.Wait()
fmt.Println("Broadcast -------3 end")
}
// RegisterEventListener 注册聊天室事件监听者
func (o *ChatRoom) RegisterEventListener(listenerChan *EventListener) {
o.EventRwLocker.Lock()
defer o.EventRwLocker.Unlock()
o.eventBus = append(o.eventBus, listenerChan)
}
// 注销监听者
func (o *ChatRoom) UnRegisterEventListener(listenerChan *EventListener) {
o.EventRwLocker.Lock()
defer o.EventRwLocker.Unlock()
var registerListenerList []*EventListener
for i, listener := range o.eventBus {
if listener.Name == listenerChan.Name {
continue
}
registerListenerList = append(registerListenerList, o.eventBus[i])
}
o.eventBus = registerListenerList
}
// pushEvent 推送聊天室事件
func (o *ChatRoom) pushEvent(eventType EventType, progress EventProgress, chatUser *accountFiee.ChatUserData, client *Client, data ...any) {
//o.EventRwLocker.Lock()
//defer o.EventRwLocker.Unlock()
for _, listener := range o.eventBus {
hit := false
for _, need := range listener.ListenEvents {
if need.EventType == eventType && need.ProgressType == progress {
hit = true
break
}
}
if hit == false {
continue
}
msg := ""
if data != nil {
msg = fmt.Sprintf("%v", data[0])
}
listener.Chan <- ListenEventData{
ListenEvent: ListenEvent{
EventType: eventType,
ProgressType: progress,
},
ChatUser: chatUser,
Client: client,
Msg: msg,
Data: data,
}
fmt.Printf("chatRooom 推送事件给%s eventType:%v progress:%v", listener.Name, eventType, progress)
}
}

View File

@ -1,117 +0,0 @@
// Package ws -----------------------------
// @file : client.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2022/10/21 18:18:05
// -------------------------------------------
package ws
import (
"context"
"fmt"
"github.com/gorilla/websocket"
uuid "github.com/satori/go.uuid"
"go.uber.org/zap"
"log"
"strings"
"time"
)
var (
// 注册事件最大等待时间
limitRegisterWaitTime = time.Second * 6
limitReadTime = time.Second * 5
)
// NewClient 创建客户端实例
//
// param userId 用户id
// param uid 用户uuid
// param conn 客户端websocket连接对象
// return *Client
func NewClient(userId int64, uid string, conn *websocket.Conn, room *ChatRoom) *Client {
uidobj, _ := uuid.NewV4()
var v = &Client{
Room: room,
UserId: userId,
Uuid: uid,
ClientId: strings.Replace(uidobj.String(), "-", "", -1),
Conn: conn,
Send: make(chan []byte, 500),
}
return v
}
type Client struct {
Room *ChatRoom `json:"-" `
UserId int64 `json:"userId" ` //用户id
Uuid string `json:"uuid"` //画家uid
ClientId string `json:"clientId"` //为用户不同设备分配不同的客户端ID
Conn *websocket.Conn `json:"-"`
Send chan []byte
SessionId string `json:"sessionId"` //会话ID同一个用户多客户端登录会话ID相同
Waiter bool `json:"waiter"` //是否是客服
}
func (c *Client) Reading(ctx context.Context, handleFunc ...func(sourceData []byte, cli *Client)) {
defer func() {
c.Room.UnRegister <- c
ctx.Done()
return
}()
//c.Conn.SetReadLimit(maxMessageSize)
c.Conn.SetReadDeadline(time.Now().Add(pongWait))
//接收到ping命令后更新读取时间
c.Conn.SetPongHandler(func(string) error {
c.Conn.SetReadDeadline(time.Now().Add(pongWait))
return nil
})
for {
msgType, byteData, err := c.Conn.ReadMessage()
if msgType == -1 {
return
}
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
log.Println("ws连接已关闭", zap.Error(err))
}
break
}
if handleFunc != nil {
handleFunc[0](byteData, c)
} else {
HandleMessage(byteData, c)
}
}
}
func (c *Client) WriteWait() {
ticker := time.NewTicker(pingPeriod)
defer func() {
ticker.Stop()
c.Conn.Close()
}()
for {
select {
case msg, ok := <-c.Send:
if !ok {
// 聊天室关闭了管道
c.Conn.WriteControl(websocket.CloseMessage, []byte{}, time.Now().Add(writeWait))
return
}
// 设置写入超时
err := c.Conn.SetWriteDeadline(time.Now().Add(writeWait))
fmt.Printf("设置写超时 err check:%v\n", err)
fmt.Printf("发送消息:%+v\n", string(msg))
err = c.Conn.WriteMessage(websocket.TextMessage, msg)
fmt.Printf("发送消息结束 err check:%v\n", err)
case <-ticker.C:
fmt.Println("ping websocket client")
err := c.Conn.SetWriteDeadline(time.Now().Add(writeWait))
fmt.Printf("ping 设置写超时 err check:%v\n", err)
if err := c.Conn.WriteControl(websocket.PingMessage, nil, time.Now().Add(pongWait)); err != nil {
return
}
}
}
}

View File

@ -1,57 +0,0 @@
// Package ws -----------------------------
// @file : consts.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/14 09:44
// -------------------------------------------
package ws
import "fonchain-fiee/api/accountFiee"
// websocket 消息类型
type WsType int
const (
RegisterType WsType = iota //用户注册消息
ErrorType //错误消息
TestType //测试消息
ChatType //聊天消息
NewChatMsgType //新消息通知
AuthorizationType //token校验通知
)
// 事件总线中的事件类型
type EventType string
const (
EventConnection EventType = "connection" //websocket连接事件
EventUserJoin EventType = "user_join" //用户/客服加入聊天事件
EventUserLeave EventType = "user_leave" //用户离开事件
EventChatMessage EventType = "chat_message" //聊天消息传递事件
)
// before
type EventProgress string
const (
EventProgressBefore EventProgress = "before"
EventProgressAfter EventProgress = "after"
)
type ListenEvent struct {
EventType EventType `json:"type"`
ProgressType EventProgress `json:"progress"`
}
type ListenEventData struct {
ListenEvent
Client *Client
ChatUser *accountFiee.ChatUserData
Msg string
Data any
}
type ListenEventChan chan ListenEventData
type EventListener struct {
Name string
ListenEvents []ListenEvent //需要监听的事件列表
Chan ListenEventChan
}

View File

@ -1,21 +0,0 @@
// Package utils -----------------------------
// @file : hertzWSUpgrade.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2022/6/28 14:19
// -------------------------------------------
package ws
import (
"github.com/gorilla/websocket"
"net/http"
)
var UpGrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
// 检查请求的来源是否允许websocket连接可根据需求自行实现
return true
},
}

View File

@ -1,53 +0,0 @@
# wsscoket 对接说明
## 客户端对接测试页面
[{{服务端地址}}/ws/client](http://127.0.0.1:8088/ws/client)
## 客户端对接websocket流程
### websocket的连接
1. 客户端登录后获取uuid
2. 连接服务端websocket后在10s内发送一下格式的数据否则websocket连接将断开。
uuid请添加登录后获取的如果uuid不正确连接也会断开
```json
{
"type": "register",
"from": "",
"to": "0",
"content": {
"uuid":"用户的uuid"
}
}
```
注册成功后服务端将返回客户端临时id
```json
{"clientId":"02de5759-3f0a-47fa-a79f-afe61c39c5aa"}
```
### weboscket 数据发送测试
消息类型`type="test"`时,客户端将会把`content`内容原路返回,以此来测试最基本的通讯功能。
```json
{
"type": "test",
"from": "用户clientId",
"to": "0",
"content": {
"demo":"testdemo"
}
}
```
### websocket消息类型说明
#### 错误消息
在websocket通讯过程中服务端会对客户端发送过来的消息进行验证。
| type字段 | content字段 | 说明 |
|--------|----------------------|------------------------------|
| Error | Permission denied | 拒绝访问。 此报错一般出现在首次连接验证uuid的时候 |
| Error | Invalid data format | 无效的数据格式。消息内容未按照指定格式书写 |
| Error | Unknown message type | 未知的消息类型。接收到了未定义的type |
**错误消息示例:**
```json
{"type":"Error","content":"Permission denied","from":"0","to":"tempId"}
//{"type":"Error","content":"Invalid data format","from":"0","to":""}
//{"type":"Error","content":"Unknown notice type","from":"0","to":"0"}
```

View File

@ -1,197 +0,0 @@
// Package ws -----------------------------
// @file : handler.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2022/10/23 11:13:43
// -------------------------------------------
package ws
import (
"context"
"encoding/json"
"fmt"
"fonchain-fiee/api/account"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/cmd/config"
"fonchain-fiee/pkg/common/jwt"
"fonchain-fiee/pkg/common/m"
"fonchain-fiee/pkg/e"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/utils/secret"
)
func AuthorizationVerify(sourceData []byte) (userInfo *accountFiee.ChatUserData, ok bool, err error) {
fmt.Println("AuthorizationVerify ----------------1")
var msg AuthorizationInfo
err = json.Unmarshal(sourceData, &msg)
if err != nil {
return
}
fmt.Println("AuthorizationVerify ----------------2")
if msg.Type != AuthorizationType {
return
}
fmt.Println("AuthorizationVerify ----------------3")
if msg.Content.Auth == "" {
return
}
fmt.Println("AuthorizationVerify ----------------4")
var check = true
var ctx = context.Background()
var accountInfo accountFiee.ChatUserData
//fiee token校验
switch msg.Content.Domain {
case "app":
var fieeJwtInfo *jwt.Claims
fieeJwtInfo, err = jwt.ParseToken(msg.Content.Auth, m.JWTSecret)
if err != nil {
check = false
fmt.Printf("fiee token parse err:%v\n", err)
} else {
fmt.Printf("fieeJwtInfo :%#v\n", fieeJwtInfo)
accountInfo.Origin = config.AppConfig.System.Domain
//accountInfo.OriginId = int64(fieeJwtInfo.ID)
accountInfo.Account = fieeJwtInfo.Account
accountInfo.NickName = fieeJwtInfo.NickName
infoReq := &accountFiee.UserByTelRequest{
Tel: fieeJwtInfo.Phone,
Domain: config.AppConfig.System.Domain,
}
var accInfo *accountFiee.UserInfoResponse
accInfo, err = service.AccountFieeProvider.UserByTel(ctx, infoReq)
if err != nil {
check = false
fmt.Printf("err:%#v\n", err)
} else if accInfo != nil {
fmt.Printf("fiee accInfo :%#v\n", accInfo)
accountInfo.OriginId = int64(accInfo.Id)
accountInfo.Account = accInfo.TelNum
accountInfo.Avatar = accInfo.GroupPhoto
if accInfo.Name != "" {
accountInfo.NickName = accInfo.Name
}
}
}
case "fontree":
msg.Content.Auth, err = secret.GetJwtFromStr(msg.Content.Auth)
if err != nil {
fmt.Println("token解析失败", err.Error())
check = false
} else {
var fontreeJwtInfo *account.DecryptJwtResponse
fontreeJwtInfo, err = service.AccountProvider.DecryptJwt(ctx, &account.DecryptJwtRequest{Token: msg.Content.Auth, Domain: e.ErpDomain})
if err != nil || fontreeJwtInfo.IsOffline {
check = false
} else {
check = true
fmt.Printf("fontreeJwtInfo is %#v\n", fontreeJwtInfo)
accountInfo.Origin = e.ErpDomain
accountInfo.OriginId = int64(fontreeJwtInfo.ID)
accountInfo.Account = fontreeJwtInfo.Account
accountInfo.NickName = fontreeJwtInfo.NickName
}
}
}
if !check {
return
}
//查询是否已经注册
var chatUserQuery *accountFiee.GetChatUserListResp
chatUserQuery, err = service.AccountFieeProvider.GetChatUserList(ctx, &accountFiee.GetChatUserListRequest{
Query: &accountFiee.ChatUserData{OriginId: accountInfo.OriginId, Origin: msg.Content.Domain},
Page: 1,
PageSize: 1,
})
//如果找不到聊天用户则创建
if err != nil || chatUserQuery.Total == 0 {
//注册客服
var createUserRes *accountFiee.CreateChatUserResp
var createChatUserReq = &accountFiee.ChatUserData{
NickName: accountInfo.NickName,
Account: accountInfo.Account,
Role: 1,
Origin: msg.Content.Domain,
OriginId: accountInfo.OriginId,
}
if msg.Content.Domain == e.ErpDomain {
createChatUserReq.Role = 2
}
createUserRes, err = service.AccountFieeProvider.CreateChatUser(ctx, createChatUserReq)
if err != nil {
return
}
userInfo = createUserRes.GetData()
fmt.Printf("注册聊天用户:%#v\n", userInfo)
} else {
userInfo = chatUserQuery.List[0]
if msg.Content.Domain == config.AppConfig.System.Domain && (accountInfo.NickName != userInfo.NickName || accountInfo.Account != userInfo.Account || accountInfo.Avatar != userInfo.Avatar) {
_, _ = service.AccountFieeProvider.UpdateChatUser(ctx, &accountFiee.ChatUserData{
NickName: accountInfo.NickName,
ID: userInfo.ID,
Account: accountInfo.Account,
Avatar: accountInfo.Avatar,
})
userInfo.NickName = accountInfo.NickName
userInfo.Account = accountInfo.Account
userInfo.Avatar = accountInfo.Avatar
}
fmt.Printf("获取聊天用户:%#v\n", userInfo)
}
ok = true
return
}
func HandleMessage(sourceData []byte, cli *Client) {
var msg WsInfo
err := json.Unmarshal(sourceData, &msg)
if err != nil {
cli.Send <- WsErrorInvalidDataFormat(msg.From)
return
}
switch msg.Type {
default:
cli.Send <- WsErrorUnknownMessageType(msg.From)
//fmt.Printf("不支持的ws业务消息%#v\n", msg)
case TestType:
var newMsg = WsInfo{
Type: TestType,
Content: msg.Content,
From: "0",
To: msg.From,
}
byteMsg, _ := json.Marshal(newMsg)
cli.Send <- byteMsg
case ChatType:
if msg.From == "" {
//客户端id不能为空
cli.Send <- WsErrorMessage(ChatType, "null", e.ErrInvalidClientId, nil)
return
}
var chatInfo ChatInfo
_ = json.Unmarshal(sourceData, &chatInfo)
//解析Content
if clients, ok := cli.Room.clients[chatInfo.Content.TargetUserId]; ok {
for _, targetObj := range clients {
if targetObj != nil {
targetObj.Send <- WsChatMessage(msg.From, chatInfo.Content.TargetClientId, chatInfo.Content.Msg)
}
}
} else {
//对方不在线
cli.Send <- WsErrorMessage(ChatType, msg.From, e.ErrTargetOutLine, nil)
}
}
}
type ChatInfo struct {
Type WsType `json:"type"` //消息类型
Content ChatContent `json:"content"` //消息内容
From string `json:"from"` //发送者 0为服务端,客户端填写clientId
To string `json:"to"` //接收者 接收消息的用户id
}
type ChatContent struct {
TargetUuid string `json:"targetUuid"`
TargetUserId int64 `json:"targetUserId"`
TargetClientId string `json:"targetClientId"`
Msg string `json:"msg"`
}

View File

@ -1,127 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Chat Example</title>
<script type="text/javascript">
window.onload = function () {
var conn;
var msg = document.getElementById("msg");
var log = document.getElementById("log");
function appendLog(item) {
var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1;
log.appendChild(item);
if (doScroll) {
log.scrollTop = log.scrollHeight - log.clientHeight;
}
}
//时间格式化
Date.prototype.Format = function (fmt) { // author: meizz
var o = {
"M+": this.getMonth() + 1, // 月份
"d+": this.getDate(), // 日
"h+": this.getHours(), // 小时
"m+": this.getMinutes(), // 分
"s+": this.getSeconds(), // 秒
"q+": Math.floor((this.getMonth() + 3) / 3), // 季度
"S": this.getMilliseconds() // 毫秒
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
document.getElementById("form").onsubmit = function () {
if (!conn) {
return false;
}
if (!msg.value) {
return false;
}
conn.send(msg.value);
var item = document.createElement("div");
var now = new Date().Format("yyyy-MM-dd hh:mm:ss:S")
item.innerText = "客户端发送消息:\t"+now+"\n\t\t"+msg.value+"\n\n";
appendLog(item);
msg.value = "";
return false;
};
if (window["WebSocket"]) {
conn = new WebSocket("ws://" + document.location.host + "/ws");
conn.onclose = function (evt) {
var item = document.createElement("div");
item.innerHTML = "<b>Connection closed.</b>";
appendLog(item);
};
conn.onmessage = function (evt) {
var messages = evt.data.split('\n');
var now = new Date().Format("yyyy-MM-dd hh:mm:ss:S")
for (var i = 0; i < messages.length; i++) {
var item = document.createElement("div");
item.innerText = "服务端回复消息:\t"+now+"\n\t\t"+messages[i]+"\n\n";
appendLog(item);
}
};
} else {
var item = document.createElement("div");
item.innerHTML = "<b>Your browser does not support WebSockets.</b>";
appendLog(item);
}
};
</script>
<style type="text/css">
html {
overflow: hidden;
}
body {
overflow: hidden;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
background: gray;
}
#log {
background: white;
margin: 0;
padding: 0.5em 0.5em 0.5em 0.5em;
position: absolute;
top: 0.5em;
left: 0.5em;
right: 0.5em;
bottom: 3em;
overflow: auto;
}
#form {
padding: 0 0.5em 0 0.5em;
margin: 0;
position: absolute;
bottom: 1em;
left: 0px;
width: 100%;
overflow: hidden;
}
input{
height: 50px;
font-size: larger;
}
</style>
</head>
<body>
<div id="log"></div>
<form id="form">
<input type="submit" value="Send" />
<input type="text" id="msg" size="64" autofocus />
</form>
</body>
</html>

View File

@ -23,6 +23,7 @@ var (
DriverUrl string
AppointUrl string
MaterialHost string
//TODO
//BosAk string
//BosSk string
//BosBucketName string
@ -30,6 +31,7 @@ var (
//BosUrl string
//BosHttp string
//BosDomain string
//TODO
ProjectMapDir string
JaegerHost string
JaegerOpen bool

View File

@ -1,63 +0,0 @@
// Package e -----------------------------
// @file : chatCode.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/12 16:57
// -------------------------------------------
package e
import "fmt"
type ErrorCodeType int
func (e ErrorCodeType) String() string {
return GetCodeMsg(e)
}
func (e ErrorCodeType) Error() string {
return GetCodeMsg(e)
}
func (e ErrorCodeType) Int() int {
return int(e)
}
func GetCodeMsg(e ErrorCodeType) string {
v, ok := msgFlags[e]
if !ok {
return fmt.Sprintf("未知错误:[%d]", e)
}
return v
}
var msgFlags = map[ErrorCodeType]string{
SUCCESS: "操作成功",
UpdatePasswordSuccess: "修改密码成功",
NotExistInentifier: "该第三方账号未绑定",
ERROR: "fail",
InvalidParams: "请求参数错误",
BindError: "参数绑定错误,类型不一致",
JsonUnmarshal: "Json解析错误",
ErrorDatabase: "数据库操作出错,请重试",
ErrorOss: "OSS配置错误",
InvalidToken: "Token验证失败",
ErrorUploadFile: "上传失败",
ErrorUploadVideoCover: "视频截取封面错误",
ErrorUploadValidParam: "上传参数非法",
ErrorFileReadErr: "读取文件错误",
ErrorFileNotExists: "文件不存在",
ErrorChunkNotGt: "分块数量不一致",
ErrorChunk: "读取分块错误",
ErrorUploadBos: "上传bos错误",
ErrorFileCreate: "文件创建错误",
ErrInvalidDataFormat: "无效的数据格式",
ErrInvalidClientId: "无效的客户端ID",
ErrRegisterFailed: "注册失败",
ErrUnRegistered: "未注册客户端",
PermissionDenied: "拒绝访问",
ErrChatSendErr: "消息发送失败",
NotLogin: "请先登录",
ErrorNotExistUser: "用户不存在",
}

View File

@ -13,7 +13,6 @@ const (
const (
DomainAdmin = "blockchain"
ErpDomain = "fontree"
)
const (
@ -23,7 +22,6 @@ const (
const (
ErrNotLogin = "请先登录"
ErrOffline = "您已经下线"
InvalidStatus = "状态非法"
)
const (
@ -141,15 +139,6 @@ const (
ERROR_Text_Irregularity = 90018
ERROR_Text_Length = 90019
ERROR_NoPermission = 90020
//聊天室
ErrInvalidDataFormat = 80100 //无效的数据格式
ErrInvalidClientId = 80101 //无效的客户端id
ErrRegisterFailed = 80102 //注册失败
ErrUnRegistered = 80103 //未注册
PermissionDenied = 80104 //拒绝访问
ErrChatSendErr = 80105 //聊天记录发送失败
ErrTargetOutLine = 80106 //目标离线
)
const (
Push = 1

View File

@ -1,56 +0,0 @@
package e
import "strings"
type FileType int
// 定义文件类型值
const (
Video FileType = 1
Audio FileType = 2
Image FileType = 3
File FileType = 4
Other FileType = 5
)
// 根据扩展名映射到文件类型值
var extensionToType = map[string]FileType{
// 视频文件
".3g2": Video, ".3gp": Video, ".asf": Video, ".avi": Video, ".divx": Video, ".drc": Video,
".flv": Video, ".h261": Video, ".h264": Video, ".mkv": Video, ".mov": Video, ".mp4": Video, ".mpg": Video,
".mpeg": Video, ".mpv": Video, ".mxf": Video, ".nuv": Video, ".qt": Video, ".rm": Video,
".rmvb": Video, ".srt": Video, ".swf": Video, ".vob": Video, ".vp6": Video, ".vp8": Video, ".webm": Video,
".wmv": Video, ".xesc": Video,
// 音频文件
".aac": Audio, ".aax": Audio, ".ac3": Audio, ".act": Audio, ".au": Audio, ".flac": Audio,
".m4a": Audio, ".m4p": Audio, ".m4r": Audio, ".mid": Audio, ".midi": Audio, ".mp2": Audio,
".mp3": Audio, ".mpa": Audio, ".mpc": Audio, ".ogg": Audio, ".wav": Audio, ".wma": Audio, ".wv": Audio,
// 图像文件
".bmp": Image, ".gif": Image, ".ico": Image, ".jpeg": Image, ".jpg": Image, ".jpe": Image,
".png": Image, ".psd": Image, ".tiff": Image, ".webp": Image,
// 普通文件
".a": File, ".abw": File, ".azw": File, ".bin": File, ".bz2": File, ".c": File, ".cab": File,
".class": File, ".conf": File, ".crt": File, ".css": File, ".csv": File, ".dat": File, ".deb": File,
".dll": File, ".dms": File, ".doc": File, ".docx": File, ".eot": File, ".eps": File, ".exe": File,
".gz": File, ".h": File, ".htm": File, ".html": File, ".iso": File, ".jar": File,
".js": File, ".json": File, ".log": File, ".m3u": File, ".m3u8": File, ".md": File, ".msi": File,
".otf": File, ".pcap": File, ".pdf": File, ".ppt": File, ".pptx": File, ".rar": File, ".rpm": File,
".rss": File, ".run": File, ".sh": File, ".sql": File, ".svg": File, ".tar": File, ".tgz": File,
".ttf": File, ".txt": File, ".vsd": File, ".weba": File,
".wps": File, ".xml": File, ".xpi": File, ".zip": File, ".z": File,
// 未知文件扩展名
"": Other,
}
// DetectFileTypeByExtension 通过文件扩展名判断文件类型并返回对应的值
func DetectFileTypeByExtension(extension string) FileType {
extension = strings.ToLower(extension)
if fileType, exists := extensionToType[extension]; exists {
return fileType
}
return Other
}

View File

@ -146,13 +146,10 @@ var MsgFlags = map[int]string{
ERROR_Text_Irregularity: "文字内容不合规",
ERROR_Text_Length: "文本长度超出限制",
ERROR_NoPermission: "您暂无权限,请联系客服",
ErrInvalidClientId: "无效的客户端ID",
}
const (
ErrorCreateFeedback = "请勿重复提交"
ErrorBalanceInsufficient = "余额不足"
)
// GetMsg 获取状态码对应信息

View File

@ -29,7 +29,7 @@ package e
ERR_NOT_NEED_BALANCE = "无需查询余额"
ErrNoBalance = "余额不足"
ErrNoBalance = "假期余额不足"
ErrHourNoBalance = "请假时长超出范围"
ErrApplyTime = "无效的请假时间"
@ -165,7 +165,7 @@ var errorMessagesZhCN = map[string]string{
"ERR_NOT_NEED_BALANCEZhCN": "无需查询余额",
"ErrNoBalanceZhCN": "余额不足",
"ErrNoBalanceZhCN": "假期余额不足",
"ErrHourNoBalanceZhCN": "请假时长超出范围",
"ErrApplyTimeZhCN": "无效的请假时间",
@ -325,7 +325,7 @@ var errorMessagesZhTW = map[string]string{
"ERR_NOT_NEED_BALANCEZhTW": "無需查詢餘額",
"ErrNoBalanceZhTW": "餘額不足",
"ErrNoBalanceZhTW": "假期餘額不足",
"ErrHourNoBalanceZhTW": "請假時長超出範圍",
"ErrApplyTimeZhTW": "無效的請假時間",

View File

@ -1,54 +0,0 @@
package logger
import (
"fonchain-fiee/cmd/config"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
)
func LogInit(appConfig *config.Config) *zap.Logger {
var err error
writeSyncer := getLogWriter(appConfig.ZapLog.Filename, appConfig.ZapLog.MaxSize, appConfig.ZapLog.MaxBackups, appConfig.ZapLog.MaxAge)
encoder := getEncoder()
var l = new(zapcore.Level)
err = l.UnmarshalText([]byte(appConfig.ZapLog.Level))
if err != nil {
return nil
}
var core zapcore.Core
//if appConfig.System.Mode == "dev" {
// 进入开发模式,日志输出到终端
consoleEncoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())
core = zapcore.NewTee(
zapcore.NewCore(encoder, writeSyncer, l),
zapcore.NewCore(consoleEncoder, zapcore.Lock(os.Stdout), zapcore.DebugLevel),
)
//} else {
// core = zapcore.NewCore(encoder, writeSyncer, l)
//}
lg := zap.New(core, zap.AddCaller())
zap.ReplaceGlobals(lg)
return lg
}
func getEncoder() zapcore.Encoder {
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.TimeKey = "time"
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
encoderConfig.EncodeDuration = zapcore.SecondsDurationEncoder
encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder
return zapcore.NewJSONEncoder(encoderConfig)
}
func getLogWriter(filename string, maxSize, maxBackup, maxAge int) zapcore.WriteSyncer {
lumberJackLogger := &lumberjack.Logger{
Filename: filename,
MaxSize: maxSize,
MaxBackups: maxBackup,
MaxAge: maxAge,
}
return zapcore.AddSync(lumberJackLogger)
}

View File

@ -24,17 +24,14 @@ func NewLogger() gin.HandlerFunc {
latencyTime := endTime.Sub(startTime) // 请求方式
path := c.Request.URL.Path
query := c.Request.URL.RawQuery
if _, err := c.FormFile("file"); err != nil {
data, _ := io.ReadAll(c.Request.Body)
log.Printf("[%s] %s %d %s %s %s %s %s %s", path, c.Request.Method, c.Writer.Status(), query,
string(data), c.ClientIP(), c.Request.UserAgent(), c.Errors.ByType(gin.ErrorTypePrivate).String(), latencyTime.String())
c.Request.Body = io.NopCloser(bytes.NewBuffer(data))
}
val := c.GetHeader("Accept-Language")
if val == "" {
c.Request.Header.Set("Accept-Language", "zh-CN")
}
log.Printf("[%s] %s %d %s %s %s %s %s %s", path, c.Request.Method, c.Writer.Status(), query,
string(data), c.ClientIP(), c.Request.UserAgent(), c.Errors.ByType(gin.ErrorTypePrivate).String(), latencyTime.String())
c.Request.Body = io.NopCloser(bytes.NewBuffer(data))
c.Next()
}
}

View File

@ -1,25 +0,0 @@
package cast
type ApprovalDetailResponse struct {
Status int `json:"status"`
Data Data `json:"data"`
Msg string `json:"msg"`
Code int `json:"code"`
Error *string `json:"error"`
Err string `json:"err"`
Keys []string `json:"keys"`
Positions *interface{} `json:"positions"`
}
type Data struct {
Count int `json:"Count"`
Data []Item `json:"data"`
Status int `json:"Status"`
}
type Item struct {
ID int `json:"ID"`
Domain string `json:"Domain"`
Status int `json:"Status"`
Reply string `json:"Reply"`
}

View File

@ -1,10 +0,0 @@
package cast
type BalanceTypeEnum int32
// 定义枚举值
const (
BalanceTypeAccountValue BalanceTypeEnum = 1
BalanceTypeImageValue BalanceTypeEnum = 2
BalanceTypeVideoValue BalanceTypeEnum = 3
)

View File

@ -1,10 +0,0 @@
package cast
type OAuthPlatformReq struct {
MediaAccountUuid string `json:"mediaAccountUuid" form:"mediaAccountUuid" binding:"required"`
PlatformID int `json:"platformID" form:"platformID" binding:"required"`
}
type OAuthPlatformResp struct {
Url string `json:"url"`
}

View File

@ -1,11 +0,0 @@
package cast
const (
WorkStatusPending = 1 // 待提交
WorkStatusReviewing = 2 // 审核中
WorkStatusReviewFailed = 3 // 审核失败
WorkStatusArtistConfirming = 4 // 待艺人确认
WorkStatusArtistRejected = 5 // 艺人驳回
WorkStatusPublishSuccess = 6 // 发布成功
WorkStatusPublishFailed = 7 // 发布失败
)

View File

@ -1,5 +0,0 @@
package query
type RemindReq struct {
WorkUuid string `json:"workUuid"`
}

View File

@ -1,18 +0,0 @@
package app
import (
"fonchain-fiee/pkg/middleware"
"fonchain-fiee/pkg/service"
serviceCast "fonchain-fiee/pkg/service/app/cast"
"github.com/gin-gonic/gin"
)
func MediaAppRouter(r *gin.RouterGroup) {
auth := r.Group("")
auth.Use(middleware.CheckLogin(service.AccountFieeProvider))
media := auth.Group("app/media")
{
media.POST("user-accounts", serviceCast.UserAccounts)
media.POST("work-list", serviceCast.MediaWorks)
}
}

View File

@ -12,7 +12,6 @@ func BundleRouter(r *gin.RouterGroup) {
bundleRoute := r.Group("bundle")
bundleRoute.Use(middleware.CheckWebLogin(service.AccountProvider))
bundleAppRoute := r.Group("bundle")
bundleAppNoAuthRoute := r.Group("bundle")
bundleAppRoute.Use(middleware.CheckLogin(service.AccountFieeProvider))
// 套餐
{
@ -22,7 +21,6 @@ func BundleRouter(r *gin.RouterGroup) {
bundleClientRoute.POST("update", bundle.UpdateBundle)
bundleClientRoute.POST("remove", bundle.DeleteBundle)
bundleClientRoute.POST("bundle-list", bundle.BundleList)
bundleClientRoute.POST("add-value/only", bundle.OnlyAddValueListByOrderNo)
bundleExtend := bundleClientRoute.Group("extend")
{
@ -35,16 +33,9 @@ func BundleRouter(r *gin.RouterGroup) {
bundleBalance.POST("used-record", bundle.GetUsedRecordList)
}
}
bundleClientRouteV2 := bundleRoute.Group("system/v2")
bundleAppRoute = bundleAppRoute.Group("common")
{
bundleClientRouteV2.POST("save", bundle.SaveBundleV2)
bundleClientRouteV2.POST("update/shelfStatus", bundle.HandShelf)
bundleClientRouteV2.POST("bundle-list", bundle.BundleListV2)
bundleClientRouteV2.POST("bundle-detail", bundle.BundleDetailV2)
}
bundleAppRouteV1 := bundleAppRoute.Group("common")
{
bundleAppRouteV1.POST("bundle-list", bundle.BundleList)
bundleAppRoute.POST("bundle-list", bundle.BundleList)
bundleAppRoute.POST("pending-confirmation-list", bundle.GetToBeComfirmedWorks) // 作品状态变更的待确认记录
@ -54,16 +45,7 @@ func BundleRouter(r *gin.RouterGroup) {
bundleAppRoute.POST("work-detail", bundle.GetWorkDetail)
bundleAppRoute.POST("work-confirm", bundle.WorkConfirm)
}
bundleAppRouteV2 := bundleAppRoute.Group("app/system/v2")
{
bundleAppRouteV2.POST("add-value/only", bundle.OnlyAddValueListByOrderNo)
}
bundleAppNoAuthRouteV2 := bundleAppNoAuthRoute.Group("app/system/v2")
{
bundleAppNoAuthRouteV2.POST("bundle-list", bundle.BundleListH5V2)
bundleAppNoAuthRouteV2.POST("bundle-detail", bundle.BundleDetailV2)
}
}
}

View File

@ -24,9 +24,6 @@ func BundleOrderRouter(r *gin.RouterGroup) {
{
bundleOrderClientWebRoute.POST("bundle-order-list", bundle.OrderRecordsList)
bundleOrderClientWebRoute.POST("bundle-order-list-V2", bundle.OrderRecordsListV2)
bundleOrderClientWebRoute.POST("bundle-order-list-download", bundle.OrderRecordsListDownload)
bundleOrderClientWebRoute.POST("reconciliation-list", bundle.GetReconciliationList)
bundleOrderClientWebRoute.POST("reconciliation-list-download", bundle.GetReconciliationListDownload)
}
bundleOrderClientAppRoute := bundleOrderRoute.Group("common/app")
{
@ -43,7 +40,6 @@ func BundleOrderRouter(r *gin.RouterGroup) {
{
bundleOrderAppRoute.POST("order-signature", bundle.CreateBundleOrderSignature)
bundleOrderAppRoute.POST("order-add-signature", bundle.CreateBundleOrderAddSignature)
bundleOrderAppRoute.POST("order-del", bundle.DeleteBundleOrder)
bundleOrderAppRoute.POST("update-pay", bundle.UpdateBundleOrderStatusPaid)
bundleOrderAppRoute.POST("order-detail", bundle.OrderRecordsDetail)

View File

@ -17,23 +17,11 @@ func MediaRouter(r *gin.RouterGroup) {
media.POST("unbind-manager", serviceCast.UnbindManager)
media.POST("bind-manager", serviceCast.BindManager)
media.POST("update-account", serviceCast.UpdateMediaAccount)
media.POST("oauth-url", serviceCast.OAuthUrl)
}
mediaNoLogin := r.Group("media")
{
mediaNoLogin.GET("oauth2callback", serviceCast.OAuth2Callback)
mediaNoLogin.GET("test", serviceCast.Test)
}
work := auth.Group("work")
{
work.POST("update-work-image", serviceCast.UpdateWorkImage)
work.POST("update-work-video", serviceCast.UpdateWorkVideo)
work.POST("update-approval", serviceCast.UpdateApproval)
work.POST("list", serviceCast.WorkList)
work.POST("detail", serviceCast.WorkDetail)
work.POST("republish", serviceCast.RePublish)
work.POST("delete", serviceCast.DelWork)
work.POST("remind", serviceCast.Remind)
}
}

View File

@ -2,10 +2,8 @@ package router
import (
"fonchain-fiee/pkg/middleware"
"fonchain-fiee/pkg/router/app"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/account"
"fonchain-fiee/pkg/service/asChat"
"fonchain-fiee/pkg/service/auth"
"fonchain-fiee/pkg/service/file"
"fonchain-fiee/pkg/service/governance"
@ -27,10 +25,7 @@ import (
func NewRouter() *gin.Engine {
//使用默认gin路由
r := gin.Default()
wsGroup := r.Group("api/fiee")
wsGroup.Use(
middleware.GinRecovery(true),
)
r.Use(gzip.Gzip(gzip.BestSpeed)) // 中间件占用绝大部分内存
//加入日志中间件,跨域中间件
r.Use(middleware.NewLogger(), middleware.Cors(), middleware.GinRecovery(true))
@ -38,7 +33,6 @@ func NewRouter() *gin.Engine {
privateGroup.Use(middleware.NewLogger(), middleware.Cors(), middleware.GinRecovery(true))
//加入日志中间件,跨域中间件
v1 := r.Group("api/fiee")
v1.Use(middleware.NewLogger(), middleware.Cors(), middleware.GinRecovery(true))
GiteaRoute(v1)
v1.GET("test", func(c *gin.Context) {
@ -51,8 +45,7 @@ func NewRouter() *gin.Engine {
BundleOrderRouter(privateGroup)
ValueAddBundleRouter(privateGroup)
MediaRouter(privateGroup)
SecFilingRouter(privateGroup)
app.MediaAppRouter(privateGroup)
{
v1.POST("version", version.Version) //版本号公共
}
@ -118,27 +111,6 @@ func NewRouter() *gin.Engine {
redirectRoute.POST("sdk/down/v2", auth.DownImgV2)
redirectRoute.POST("sdk/down/v3", auth.DownImgV3)
}
//========================================================================================
// 客服聊天
{
// websocket数据接收
wsGroup.GET("aschat/ws", asChat.ChatHandlerIns.Connection)
v1.POST("aschat/message/new", asChat.ChatHandlerIns.NewMessage)
v1.POST("aschat/media/upload", asChat.ChatHandlerIns.Upload)
v1.POST("aschat/message/list", asChat.ChatHandlerIns.MessageList)
v1.POST("aschat/user/stat", asChat.ChatHandlerIns.UserMessageStat)
v1.POST("aschat/voicetotext", asChat.ChatHandlerIns.VoiceToText)
v1.POST("aschat/userDetail", asChat.ChatHandlerIns.UserDetail)
v1.POST("aschat/autoReplyRuler/create", asChat.Handler.CreateChatAutoReplyRuler)
v1.POST("aschat/autoReplyRuler/delete", asChat.Handler.DeleteChatAutoReplyRuler)
v1.POST("aschat/autoReplyRuler/update", asChat.Handler.UpdateChatAutoReplyRuler)
v1.POST("aschat/autoReplyRuler/detail", asChat.Handler.GetChatAutoReplyRulerDetail)
v1.POST("aschat/autoReplyRuler/query", asChat.Handler.GetChatAutoReplyRulerList)
v1.POST("/test/user/log/erp", asChat.Handler.ErpLoginDemo)
v1.POST("/test/user/log/fiee", asChat.Handler.FieeLoginDemo)
v1.POST("/aschat/test", asChat.Handler.Test)
}
{
// 素材库

View File

@ -1,35 +0,0 @@
package router
import (
"fonchain-fiee/pkg/middleware"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/secfilings"
"github.com/gin-gonic/gin"
)
func SecFilingRouter(r *gin.RouterGroup) {
SecFilingRouter := r.Group("sec-filing")
SecNoAuthRouter := r.Group("sec-filing")
SecFilingRouter.Use(middleware.CheckWebLogin(service.AccountProvider))
// sec-filing
secFilingRoute := SecFilingRouter.Group("system")
{
secFilingRoute.POST("create", secfilings.CreateSecFiling)
secFilingRoute.POST("update", secfilings.UpdateSecFiling)
secFilingRoute.POST("list", secfilings.ListSecFiling)
secFilingRoute.POST("detail", secfilings.DetailSecFiling)
secFilingRoute.POST("delete", secfilings.DeleteSecFiling)
secFilingRoute.POST("get", secfilings.GetSecFilings)
secFilingRoute.POST("update/status", secfilings.UpdateSecFilingStatus)
secFilingRoute.POST("form/list", secfilings.GetFormList)
}
secNoAUthRouter := SecNoAuthRouter.Group("web")
{
secNoAUthRouter.POST("list", secfilings.WebListSecFiling)
secNoAUthRouter.POST("detail", secfilings.DetailSecFiling)
}
}

View File

@ -23,22 +23,10 @@ func ValueAddBundleRouter(r *gin.RouterGroup) {
bundleClientRoute.POST("list", bundle.ValueAddBundleList)
bundleClientRoute.POST("detail", bundle.ValueAddBundleDetail)
}
bundleClientRouteV2 := valueAddBundleRoute.Group("system/v2")
{
bundleClientRouteV2.POST("save", bundle.SaveValueAddService)
bundleClientRouteV2.POST("list", bundle.ValueAddServiceList)
bundleClientRouteV2.POST("detail", bundle.ValueAddServiceDetail)
}
valueAddBundleAppRouteV1 := valueAddBundleAppRoute.Group("system")
valueAddBundleAppRoute = valueAddBundleAppRoute.Group("system")
{
valueAddBundleAppRouteV1.POST("list", bundle.ValueAddBundleList)
}
valueAddBundleAppRouteV2 := valueAddBundleAppRoute.Group("system/v2")
{
valueAddBundleAppRouteV2.POST("list", bundle.ValueAddServiceList)
valueAddBundleAppRouteV2.POST("detail", bundle.ValueAddServiceDetail)
valueAddBundleAppRouteV2.POST("detail/lang", bundle.ValueAddServiceLangDetail)
valueAddBundleAppRoute.POST("list", bundle.ValueAddBundleList)
}
}

View File

@ -1,13 +1,11 @@
package serializer
import "fonchain-fiee/pkg/e"
// Response 基础序列化器
type Response struct {
Status int `json:"status"`
Data interface{} `json:"data"`
Msg string `json:"msg"`
Code e.ErrorCodeType `json:"code"`
Code int `json:"code"`
Error error `json:"error"`
Err string `json:"err"`
Keys []string `json:"keys"`

View File

@ -156,7 +156,7 @@ func SendMsg(c *gin.Context) {
service.Error(c, err)
return
}
service.Success1(c, "发送成功", res)
service.Success(c, res)
return
} else {
res, err := service.AccountFieeProvider.SendMsg(context.Background(), &req)
@ -165,7 +165,7 @@ func SendMsg(c *gin.Context) {
return
}
service.Success1(c, "发送成功", res)
service.Success(c, res)
return
}

View File

@ -1,57 +0,0 @@
package cast
import (
"fmt"
"fonchain-fiee/api/cast"
"fonchain-fiee/cmd/config"
"fonchain-fiee/pkg/model/login"
"fonchain-fiee/pkg/service"
"github.com/gin-gonic/gin"
)
func UserAccounts(ctx *gin.Context) {
var req *cast.MediaAccountsReq = &cast.MediaAccountsReq{}
var err error
if config.AppConfig.System.AppMode != "dev" {
userInfo := login.GetUserInfoFromC(ctx)
req.ArtistUuid = fmt.Sprint(userInfo.ID)
} else {
req.ArtistUuid = "61"
}
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
if err = req.Validate(); err != nil {
service.Error(ctx, err)
return
}
resp, err := service.CastProvider.MediaAccounts(ctx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
return
}
func MediaWorks(ctx *gin.Context) {
var req *cast.MediaWorksReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
if err = req.Validate(); err != nil {
service.Error(ctx, err)
return
}
resp, err := service.CastProvider.MediaWorks(ctx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
return
}

View File

@ -1,226 +0,0 @@
package asChat
import (
"encoding/json"
"fmt"
"fonchain-fiee/api/account"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/cmd/config"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/asChat/dto"
"fonchain-fiee/pkg/utils"
"fonchain-fiee/pkg/utils/secret"
"fonchain-fiee/pkg/utils/stime"
"math/rand"
"time"
"github.com/gin-gonic/gin"
)
var Handler = &ChatAutoReplyRulerHandler{}
type ChatAutoReplyRulerHandler struct {
}
// 创建自动回复规则
func (a *ChatAutoReplyRulerHandler) CreateChatAutoReplyRuler(c *gin.Context) {
var req dto.ChatAutoReplyData
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, err)
return
}
rulerBytes, _ := json.Marshal(req.Rules)
protoReq := accountFiee.ChatAutoReplyRulerData{
Title: req.Title,
Ruler: string(rulerBytes),
Response: req.Response,
}
_, err := service.AccountFieeProvider.CreateChatAutoReplyRuler(c, &protoReq)
if err != nil {
service.Error(c, err)
return
}
err = ChatHandlerIns.robot.ReloadRules(c)
if err != nil {
service.Error(c, err)
return
}
service.Success(c)
}
// 删除自动回复规则
func (a *ChatAutoReplyRulerHandler) DeleteChatAutoReplyRuler(c *gin.Context) {
var req accountFiee.DeleteChatAutoReplyRulerRequest
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, err)
return
}
_, err := service.AccountFieeProvider.DeleteChatAutoReplyRuler(c, &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c)
}
// 更新自动回复规则
func (a *ChatAutoReplyRulerHandler) UpdateChatAutoReplyRuler(c *gin.Context) {
var req dto.ChatAutoReplyData
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, err)
return
}
protoReq := req.ToProtoData()
_, err := service.AccountFieeProvider.UpdateChatAutoReplyRuler(c, protoReq)
if err != nil {
service.Error(c, err)
return
}
err = ChatHandlerIns.robot.ReloadRules(c)
if err != nil {
service.Error(c, err)
return
}
service.Success(c)
}
// 使用id查询自动回复规则
func (a *ChatAutoReplyRulerHandler) GetChatAutoReplyRulerDetail(c *gin.Context) {
var req accountFiee.GetChatAutoReplyRulerByIdRequest
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, err)
return
}
resp, err := service.AccountFieeProvider.GetChatAutoReplyRulerDetail(c, &req)
if err != nil {
service.Error(c, err)
return
}
tmp := dto.ChatAutoReplyData{}
tmp.Parse(resp)
service.Success(c, tmp)
}
// 批量查询自动回复规则
func (a *ChatAutoReplyRulerHandler) GetChatAutoReplyRulerList(c *gin.Context) {
var req dto.GetChatAutoReplyRulerListRequest
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, err)
return
}
var protoReq = accountFiee.GetChatAutoReplyRulerListRequest{Query: &accountFiee.ChatAutoReplyRulerData{}}
utils.RequestDataConvert(&req, &protoReq)
if req.RuleType != "" {
protoReq.Where = fmt.Sprintf("ruler LIKE '%%%s\":{\"enable\":true%%'", req.RuleType)
}
resp, err := service.AccountFieeProvider.GetChatAutoReplyRulerList(c, &protoReq)
if err != nil {
service.Error(c, err)
return
}
var data []dto.ChatAutoReplyData
for _, v := range resp.List {
tmp := dto.ChatAutoReplyData{}
tmp.Parse(v)
data = append(data, tmp)
}
service.Success(c, map[string]interface{}{
"data": data,
"page": resp.Page,
"pagesize": resp.PageSize,
"total": resp.Total,
})
}
func (a *ChatAutoReplyRulerHandler) ErpLoginDemo(c *gin.Context) {
var req dto.ErpLoginDemoReq
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, err)
return
}
loginRes, err := service.AccountProvider.Login(c, &account.LoginRequest{
Domain: "fontree",
TelNum: req.TelNum,
Password: req.Password,
})
if err != nil {
if err.Error() == "没有找到数据" || err.Error() == "No data found" {
registerRequest := account.RegistRequest{
Domain: "fontree",
NickName: req.TelNum,
TelNum: req.TelNum,
Password: req.Password,
EnterDate: time.Now().Format(stime.Format_Normal_YMD),
Extend: &account.Extend{JumpTo: "onsite"}, //origin-老平台 onsite 当前
JobNum: fmt.Sprintf("%d", rand.Intn(1000)),
}
registerRes, errs := service.AccountProvider.Register(c, &registerRequest)
if errs != nil {
service.Error(c, errs)
return
}
service.Success(c, registerRes)
} else {
service.Error(c, err)
}
return
}
departmentName := ""
if loginRes.AccountInfo != nil && len(loginRes.AccountInfo.Departments) > 0 {
departmentName = loginRes.AccountInfo.Departments[0].Name
}
loginRes.Token, err = secret.CombineSecret("xxx", departmentName, loginRes.Token)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, loginRes)
}
func (a *ChatAutoReplyRulerHandler) FieeLoginDemo(c *gin.Context) {
var req dto.ErpLoginDemoReq
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, err)
return
}
loginRes, err := service.AccountFieeProvider.Login(c, &accountFiee.LoginRequest{
Domain: config.AppConfig.System.Domain,
TelNum: req.TelNum,
Password: req.Password,
})
if err != nil {
if err.Error() == "账号不存在" || err.Error() == "Account does not exist" {
registerRequest := accountFiee.RegistRequest{
Domain: config.AppConfig.System.Domain,
NickName: req.TelNum,
TelNum: req.TelNum,
//Password: req.Password,
//EnterDate: time.Now().Format(stime.Format_Normal_YMD),
//Extend: &account.Extend{JumpTo: "onsite"}, //origin-老平台 onsite 当前
//JobNum: fmt.Sprintf("%d", rand.Intn(1000)),
}
registerRes, errs := service.AccountFieeProvider.Register(c, &registerRequest)
if errs != nil {
service.Error(c, errs)
return
}
service.Success(c, registerRes)
} else {
service.Error(c, err)
}
return
}
//departmentName := ""
//if loginRes.AccountInfo != nil && len(loginRes.AccountInfo.Departments) > 0 {
// departmentName = loginRes.AccountInfo.Departments[0].Name
//}
//loginRes.Token, err = secret.CombineSecret("xxx", departmentName, loginRes.Token)
//if err != nil {
// service.Error(c, err)
// return
//}
service.Success(c, loginRes)
}
func (a *ChatAutoReplyRulerHandler) Test(c *gin.Context) {
fmt.Println(c.GetHeader("domain"))
}

View File

@ -1,250 +0,0 @@
// Package asChat -----------------------------
// @file : cache.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2024/9/11 下午5:18
// -------------------------------------------
package chatCache
import (
"context"
"errors"
"fmt"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/cache"
"fonchain-fiee/pkg/service/asChat/dto"
"github.com/go-redis/redis"
"github.com/goccy/go-json"
"go.uber.org/zap"
"log"
"strings"
"sync"
"time"
)
const CacheChatRecordKey = "fiee:chatRecord"
const CacheSessionKey = "fiee:chatSession"
const CacheNewMsgStatKey = "fiee:newMsgStat"
var chatCacheLocker sync.RWMutex
type ChatCache struct {
NewMessageStatExpireAfter time.Duration //消息统计的数据过期时间
}
// ------------------------------存储用户的会话ID--------------------------------
func (cr ChatCache) GetUserSessionCacheKey(userId int64) string {
return fmt.Sprintf("%s:%d", CacheSessionKey, userId)
}
func (cr ChatCache) SaveUserSession(userId int64, sessionId string) {
chatCacheLocker.Lock()
defer chatCacheLocker.Unlock()
////var c = context.Background()
err := cache.RedisClient.Set(cr.GetUserSessionCacheKey(userId), sessionId, 0).Err()
if err != nil {
log.Print("保存用户会话失败", zap.Error(err))
}
}
func (cr ChatCache) GetUserSession(userId int64) (sessionId string) {
fmt.Println("GetUserSession-1")
chatCacheLocker.RLock()
defer chatCacheLocker.RUnlock()
//var c = context.Background()
sessionId, err := cache.RedisClient.Get(cr.GetUserSessionCacheKey(userId)).Result()
fmt.Println("GetUserSession-2")
if err != nil {
if err.Error() == "redis: nil" {
err = nil
} else {
log.Print("获取用户会话失败", zap.Error(err))
}
}
fmt.Println("GetUserSession-3, sessionId:", sessionId)
return
}
// ------------------------------存储会话的聊天记录--------------------------------
func (cr ChatCache) GetChatRecordCacheKey(sessionId string) string {
return fmt.Sprintf("%s:%s", CacheChatRecordKey, sessionId)
}
func (cr ChatCache) AddChatRecord(sessionId string, data ...*accountFiee.ChatRecordData) (err error) {
////var c = context.Background()
messages := cr.GetChatRecord(sessionId)
fmt.Printf("AddChatRecord add data:%+v\n", data)
messages = append(messages, data...)
cacheBytes, _ := json.Marshal(messages)
fmt.Println("Marshal result", string(cacheBytes))
err = cache.RedisClient.Set(cr.GetChatRecordCacheKey(sessionId), cacheBytes, 2*time.Hour).Err()
return
}
func (cr ChatCache) CoverChatRecord(sessionId string, data []*accountFiee.ChatRecordData) (err error) {
chatCacheLocker.Lock()
defer chatCacheLocker.Unlock()
//var c = context.Background()
cacheBytes, _ := json.Marshal(data)
err = cache.RedisClient.Set(cr.GetChatRecordCacheKey(sessionId), cacheBytes, 2*time.Hour).Err()
return
}
func (cr ChatCache) GetChatRecord(sessionId string) (data []*accountFiee.ChatRecordData) {
chatCacheLocker.RLock()
defer chatCacheLocker.RUnlock()
data = make([]*accountFiee.ChatRecordData, 0)
//var c = context.Background()
messages, err := cache.RedisClient.Get(cr.GetChatRecordCacheKey(sessionId)).Bytes()
if err != nil {
if err.Error() == "redis: nil" {
err = nil
}
//log.Print("获取聊天记录失败", zap.Error(err))
return
}
//fmt.Printf("cache data: %+v", string(messages))
if len(messages) > 0 {
_ = json.Unmarshal(messages, &data)
}
return
}
// ------------------------------存储新消息统计--------------------------------
func (cr ChatCache) GetNewMsgStatCacheKey(ownerId int64) string {
return fmt.Sprintf("%s:%d", CacheNewMsgStatKey, ownerId)
}
// 消息数量自增
func (cr ChatCache) IncreaseNewMessageTotal(ownerId int64, sessionId string) (err error) {
chatCacheLocker.Lock()
defer chatCacheLocker.Unlock()
ctx := context.Background()
data := cr.GetNewMessageStat(ctx, ownerId)
if len(data) > 0 {
foundIndex := -1
for i, v := range data {
if v.SessionId == sessionId {
foundIndex = i
break
}
}
if foundIndex > -1 {
data[foundIndex].Total += 1
}
//将foundIndex之后的所有元素右移动一位
if foundIndex > 0 {
elementToMove := data[foundIndex]
copy(data[1:], data[0:foundIndex])
data[0] = elementToMove
} else if foundIndex == -1 {
data = append([]dto.UserMsgStatic{{SessionId: sessionId, Total: 1}}, data...)
}
} else {
data = []dto.UserMsgStatic{{SessionId: sessionId, Total: 1}}
}
return cr.coverOwnerNewMessageStat(ctx, ownerId, data)
}
// 重置新消息数量
func (cr ChatCache) ResetNewMessageTotal(ownerId int64, sessionId string, total ...int64) error {
fmt.Printf("ResetNewMessageTotal: %d ,sessionId:%s ,total:%v\n", ownerId, sessionId, total)
chatCacheLocker.Lock()
defer chatCacheLocker.Unlock()
var tl int64
if len(total) > 0 {
tl = total[0]
}
fmt.Println("ResetNewMessageTotal tl:", tl)
ctx := context.Background()
data := cr.GetNewMessageStat(ctx, ownerId)
fmt.Printf("ResetNewMessageTotal data:%+v\n", data)
found := false
for i, v := range data {
if v.SessionId == sessionId {
found = true
data[i].Total = tl
fmt.Println("ResetNewMessageTotal found!")
break
}
}
if !found {
fmt.Println("ResetNewMessageTotal not found!")
data = append(data, dto.UserMsgStatic{
SessionId: sessionId,
Total: tl,
})
}
err := cr.coverOwnerNewMessageStat(ctx, ownerId, data)
fmt.Println("ResetNewMessageTotal result", err)
return err
}
func (cr ChatCache) RecountNewMessageTotal(ownerId int64) {
//var c = context.Background()
var keys []string
var err error
keys, err = cache.RedisClient.Keys(CacheChatRecordKey + "*").Result()
if err != nil {
log.Print("获取聊天记录所有缓存KEY失败", zap.Error(err))
return
}
var countMap = make(map[string]int)
for _, key := range keys {
var messages []byte
var data []*accountFiee.ChatRecordData
messages, err = cache.RedisClient.Get(key).Bytes()
if err != nil {
if err.Error() == "redis: nil" {
err = nil
}
log.Print("获取聊天记录失败", zap.Error(err))
data = make([]*accountFiee.ChatRecordData, 0)
continue
}
if len(messages) > 0 {
_ = json.Unmarshal(messages, &data)
}
lastIndex := strings.Count(key, ":")
var sessionId = strings.Split(key, ":")[lastIndex]
countMap[sessionId] = 0
for _, v := range data {
if v.WaiterRead == 2 { //统计未读消息数量
countMap[sessionId]++
}
}
}
for sessionId, count := range countMap {
err = cr.ResetNewMessageTotal(ownerId, sessionId, int64(count))
if err != nil {
log.Print("重置新消息数量统计",
zap.String("function", "RecountNewMessageTotal"),
zap.Int64("ownerId", ownerId),
zap.String("sessionId", sessionId),
zap.Int("count", count),
zap.Error(err),
)
}
}
return
}
// erp获取最新的消息统计
func (cr ChatCache) GetNewMessageStat(ctx context.Context, ownerId int64) (result []dto.UserMsgStatic) {
//chatCacheLocker.RLock()
//defer chatCacheLocker.RUnlock()
result = make([]dto.UserMsgStatic, 0)
vals, err := cache.RedisClient.Get(cr.GetNewMsgStatCacheKey(ownerId)).Bytes()
if err != nil && errors.Is(err, redis.Nil) {
log.Print("从缓存获取新消息统计失败", zap.Error(err), zap.Int64("ownerId", ownerId))
return
}
if vals != nil {
_ = json.Unmarshal(vals, &result)
}
return
}
// 覆盖指定erp用户的新消息统计
func (cr ChatCache) coverOwnerNewMessageStat(ctx context.Context, ownerId int64, data []dto.UserMsgStatic) (err error) {
value, _ := json.Marshal(data)
//err = cache.RedisClient.Set(ctx, cr.GetNewMsgStatCacheKey(ownerId), value, cr.NewMessageStatExpireAfter).Err()
err = cache.RedisClient.Set(cr.GetNewMsgStatCacheKey(ownerId), value, 0).Err()
return
}

View File

@ -1,33 +0,0 @@
// package asChat -----------------------------
// @file : chatRoom.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2022/10/21 18:17:17
// -------------------------------------------
package consts
import (
"encoding/json"
"fonchain-fiee/pkg/common/ws"
)
var (
ChatRoom = ws.NewChatRoom()
)
type WsInfo struct {
Type ws.WsType `json:"type"` //消息类型
Content any `json:"content"`
}
func WsMessageRegisterCallback(clientId string, sessionId string) []byte {
var errMsg = WsInfo{
Type: ws.RegisterType,
Content: map[string]string{
//"clientId": clientId,
"sessionId": sessionId,
},
}
byteMsg, _ := json.Marshal(errMsg)
return byteMsg
}

View File

@ -1,7 +0,0 @@
// Package consts -----------------------------
// @file : consts.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/13 17:40
// -------------------------------------------
package consts

View File

@ -1,220 +0,0 @@
// Package asChat -----------------------------
// @file : dto.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2024/9/10 下午6:28
// -------------------------------------------
package dto
import (
"encoding/json"
"fonchain-fiee/api/accountFiee"
"log"
"time"
)
type Message struct {
MsgType accountFiee.MsgType `json:"msgType"`
Text string `json:"text"` //文本内容
Media []MessageMedia `json:"media"`
LocalStamp int64 `json:"localStamp"`
}
type MessageMedia struct {
MediaId int64 `json:"mediaId"` //媒体文件id
MediaSize string `json:"mediaSize"` //媒体文件大小
Ext string `json:"ext"` //后缀格式
Url string `json:"url"` //文件地址
ConvText string `json:"convText"` //语音转文字内容,需要调用语音转文字接口后才会有值
Duration int64 `json:"duration"` //时长 单位:毫秒
}
// 客户端发送消息请求使用api发送消息
type NewMessageRequest struct {
Waiter bool `json:"waiter"` //是否是客服发送,客服没有userId
Robot bool `json:"-"` //是否机器人发送
SessionId string `json:"sessionId"`
Message
AtUserId int64 `json:"atUserId"` //指定发送给sessionId中的某一个用户
}
// 服务端接收到消息后使用websocket发送给userId关联的客户端通知客户端有新消息然后调用接口获取消息
type NewMessageNotice struct {
Name string `json:"name"` //名字
UserId int64 `json:"userId"` //用户id
SessionId string `json:"sessionId"`
MessageId int64 `json:"messageId"` //消息id
//NewMsgTotal int64 `json:"newMsgTotal"` //新消息数量
//Active bool `json:"active"` //是否在线
}
// 获取会话列表
type SessionType struct {
NewMessageNotice
RecentMessage []*Message `json:"recentMessage"` //最近消息
}
type MessageListType struct {
ID int64 `json:"ID"`
CreatedAt string `json:"createdAt"`
UserId int64 `json:"userId"`
Role int32 `json:"role,omitempty"`
Name string `json:"name"`
Message Message `json:"message"`
}
func (m *MessageListType) BuildMessage(data *accountFiee.ChatRecordData) {
m.ID = data.ID
m.CreatedAt = data.CreatedAt
m.UserId = data.UserId
m.Name = data.Name
m.Role = data.Role
switch data.MsgType {
default:
m.Message.MsgType = data.MsgType
m.Message.Text = data.Content
m.Message.LocalStamp = data.LocalStamp
if data.Medias != nil {
for _, media := range data.Medias {
m.Message.Media = append(m.Message.Media, MessageMedia{
MediaId: media.ID,
MediaSize: media.Size,
Ext: media.Ext,
Url: media.Url,
ConvText: media.ConvText,
Duration: media.Duration,
})
}
}
case accountFiee.MsgType_TextMsgType:
m.Message = Message{
MsgType: data.MsgType,
Text: data.Content,
Media: []MessageMedia{},
LocalStamp: data.LocalStamp,
}
case accountFiee.MsgType_ImageMsgType, accountFiee.MsgType_AudioMsgType, accountFiee.MsgType_VideoMsgType:
m.Message.MsgType = data.MsgType
m.Message.Text = data.Content
m.Message.LocalStamp = data.LocalStamp
if data.Medias != nil {
for _, media := range data.Medias {
m.Message.Media = append(m.Message.Media, MessageMedia{
MediaId: media.ID,
MediaSize: media.Size,
Ext: media.Ext,
Url: media.Url,
ConvText: media.ConvText,
Duration: media.Duration,
})
}
}
}
}
func (m *MessageListType) ToJson() string {
jsonBytes, _ := json.Marshal(m)
return string(jsonBytes)
}
type UserMsgStatic struct {
UserId int64 `json:"userId"` //用户id
Name string `json:"name"` //名称
ArtistUid string `json:"artistUid,omitempty"`
SessionId string `json:"sessionId"` //会话id
Total int64 `json:"total"` //新消息数量
//NewMessageTime string `json:"newMessageTime"` //最新消息的创建时间
}
type MessageListRequest struct {
SessionId string `json:"sessionId"` //不传则获取自己的会话消息里列表
CurrentId int64 `json:"currentId"` //组合查询条件1基于某个消息id向前或向后查找。两种组合条件不能同时使用
Direction int `json:"direction"` //组合查询条件1方向 1=向前查找 2=向后查找
Recent bool `json:"recent"` //组合查询条件2查找最新的若干条消息。两种组合条件不能同时使用
InHour time.Duration `json:"inHour"` //组合查询条件2可选查询指定小时内的数据
PageSize int64 `json:"pageSize"` //查找数量
}
type VoiceToTextRequest struct {
MediaId int64 `json:"mediaId"`
}
type ArtistInfoRequest struct {
UserId int64 `json:"userId"`
}
type ArtistInfo struct {
Tnum string `json:"tnum"`
ArtistName string `json:"artistName"`
Age int64 `json:"age"`
Sex string `json:"sex"`
NativePlace string `json:"nativePlace"`
TelNum string `json:"telNum"`
RecentPhoto string `json:"recentPhoto"`
}
type GetChatAutoReplyRulerListRequest struct {
Page int64 `json:"page"`
PageSize int64 `json:"pageSize"`
accountFiee.ChatAutoReplyRulerData
RuleType string `json:"ruleType"`
}
type ErpLoginDemoReq struct {
TelNum string `json:"telNum"`
Password string `json:"password"`
Nickname string `json:"nickname"`
RealName string `json:"realName"`
}
type ChatAutoReplyData struct {
ID int64 `json:"id"`
Title string `json:"title"`
Rules map[string]*AutoReplyRule `json:"rules"`
Response string `json:"response"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
Status int32 `json:"status"`
}
func (r *ChatAutoReplyData) ToProtoData() (data *accountFiee.ChatAutoReplyRulerData) {
jsonBytes, _ := json.Marshal(r.Rules)
data = &accountFiee.ChatAutoReplyRulerData{
ID: r.ID,
CreatedAt: r.CreatedAt,
UpdatedAt: r.UpdatedAt,
Title: r.Title,
Ruler: string(jsonBytes),
Status: r.Status,
Response: r.Response,
}
return
}
func (r *ChatAutoReplyData) Parse(data *accountFiee.ChatAutoReplyRulerData) {
err := json.Unmarshal([]byte(data.Ruler), &r.Rules)
log.Printf("ChatAutoReplyData parse err:%v\n", err)
r.ID = data.ID
r.CreatedAt = data.CreatedAt
r.UpdatedAt = data.UpdatedAt
r.Title = data.Title
r.Status = data.Status
r.Response = data.Response
}
type AutoReplyRule struct {
Enable bool `json:"enable"`
Content string `json:"content,omitempty"`
SecondDuration time.Duration `json:"secondDuration,omitempty"`
}
type UserDetailReq struct {
ChatUserId int64 `json:"chatUserId"` //注意是聊天用户IDchat_user表不是账号服务ID
}
type UserDetailResp struct {
UserId uint64 `json:"userId"`
ChatUserId int64 `json:"chatUserId"`
RnStatus int32 `json:"rnStatus"` //状态 1:未实名 2:审核中 3:审核失败 4:审核通过
SubNum string `json:"subNum"`
RealName string `json:"realName"`
Age string `json:"age"`
Gender string `json:"gender"`
NativePlace string `json:"nativePlace"`
Phone string `json:"phone"`
GroupPhoto string `json:"groupPhoto"`
}

View File

@ -1,614 +0,0 @@
// package asChat -----------------------------
// @file : handler.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2022/10/23 11:13:43
// -------------------------------------------
package asChat
import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/common/jwt"
"fonchain-fiee/pkg/common/ws"
"fonchain-fiee/pkg/e"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/asChat/chatCache"
"fonchain-fiee/pkg/service/asChat/consts"
"fonchain-fiee/pkg/service/asChat/dto"
"fonchain-fiee/pkg/service/asChat/logic"
"fonchain-fiee/pkg/service/asChat/robot"
"fonchain-fiee/pkg/service/upload"
"fonchain-fiee/pkg/utils/stime"
"io"
"log"
"path"
"slices"
"sort"
"strconv"
"strings"
"time"
"github.com/fonchain/utils/voice"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
uuid "github.com/satori/go.uuid"
"go.uber.org/zap"
)
var ChatHandlerIns = NewChatHandler()
func NewChatHandler() ChatHandler {
c := ChatHandler{
cache: chatCache.ChatCache{NewMessageStatExpireAfter: 10 * time.Minute},
}
c.robot = robot.NewRobot(&c.cache)
return c
}
type ChatHandler struct {
cache chatCache.ChatCache
robot *robot.Robot
}
func (cr ChatHandler) Connection(c *gin.Context) {
conn, err := ws.UpGrader.Upgrade(c.Writer, c.Request, nil)
conn.SetReadDeadline(time.Now().Add(time.Second * 10))
if err != nil {
log.Print("无法升级为websocket连接", zap.Error(err))
c.String(500, "无法转为websocket连接")
return
}
defer func() {
if conn != nil {
conn.Close()
}
}()
_, byteData, err := conn.ReadMessage()
if err != nil {
_ = conn.WriteMessage(websocket.TextMessage, ws.WsErrorConnection("null", err.Error(), "conn.ReadMessag1"))
return
}
fmt.Println("22222222222222,AuthorizationVerify")
var ok bool
var userInfo *accountFiee.ChatUserData
userInfo, ok, err = ws.AuthorizationVerify(byteData)
if err != nil {
_ = conn.WriteMessage(websocket.TextMessage, ws.WsErrorConnection("null", err.Error(), "AuthorizationVerify2"))
return
}
if !ok {
_ = conn.WriteMessage(websocket.TextMessage, ws.WsErrorConnection("null", "登录状态失效", "AuthorizationVerify2.1"))
return
}
fmt.Println("33333333333333,RecountNewMessageTotal")
conn.SetReadDeadline(time.Time{})
go cr.cache.RecountNewMessageTotal(userInfo.ID)
fmt.Println("44444444444444,ws.NewClient")
//注册ws客户端并发送clientId给ws客户端
var cli = ws.NewClient(userInfo.ID, "", conn, consts.ChatRoom)
cli.Waiter = userInfo.Role == 2
fmt.Println("55555555555555,GetUserSession")
//查询是否有历史的sessionId
cli.SessionId = cr.cache.GetUserSession(userInfo.ID)
consts.ChatRoom.Register(cli)
cr.cache.SaveUserSession(userInfo.ID, cli.SessionId)
fmt.Println("66666666666666666666666666")
go cli.WriteWait()
cli.Send <- consts.WsMessageRegisterCallback(cli.ClientId, cli.SessionId)
fmt.Println("777777777777777777777777")
// 处理websocket连接的逻辑
ctx, _ := context.WithCancel(context.Background())
cli.Reading(ctx, HandleMessage)
fmt.Println("88888888888888888888888888")
select {
case <-ctx.Done():
return
}
}
func (cr ChatHandler) NewMessage(c *gin.Context) {
var request dto.NewMessageRequest
if err := c.ShouldBindJSON(&request); err != nil {
service.Error(c, err)
return
}
if request.SessionId == "" {
service.Error(c, errors.New("sessionId不能为空"))
return
}
if request.MsgType == 0 {
service.Error(c, errors.New("msgType不能为空"))
return
}
fmt.Println("NewMessage 1111111111111111111111111111111")
//获取用户信息
chatUser, code := jwt.ParseToChatUser(c)
if code != 0 {
service.ErrWithCode(c, code)
return
}
err := logic.NewMessage(c, &cr.cache, chatUser, request)
if err != nil {
service.Error(c, err)
return
}
//fmt.Println("NewMessage 22222222222222222222222222222222222")
////存储入库
//if chatUser.NickName != "" {
// chatUser.NickName = fmt.Sprintf("未知用户(%d)", chatUser.ID)
//}
//fmt.Println("NewMessage 3333333333333333333333333333333333")
//var data = accountFiee.ChatRecordData{
// SessionId: request.SessionId,
// UserId: chatUser.ID,
// Name: chatUser.NickName,
// Avatar: "",
// MsgType: request.MsgType,
// Content: request.Message.Text,
// LocalStamp: request.LocalStamp,
// Medias: nil,
//}
//if len(request.Message.Media) > 0 {
// for _, media := range request.Message.Media {
// data.Medias = append(data.Medias, &accountFiee.ChatMediaData{
// ID: media.MediaId,
// })
// }
//}
//fmt.Println("NewMessage 4444444444444444444444444444444444")
//resp, err := service.AccountFieeProvider.CreateChatRecord(c, &data)
//if err != nil {
// service.Error(c, errors.New("创建失败"))
// return
//}
//fmt.Printf("CreateChatRecord resp:%+v\n", resp)
////录入缓存
//err = cr.cache.AddChatRecord(request.SessionId, resp.Data)
//if err != nil {
// service.Error(c, errors.New("创建失败"))
// return
//}
//fmt.Println("NewMessage 5 消息数量+1")
////新消息数量统计+1
//noticeUserId := consts.ChatRoom.GetUserIdInSession(request.SessionId, chatUser.ID)
//fmt.Println("NewMessage 5.1 消息数量配置结束")
//fmt.Printf("noticeUserId %+v\n", noticeUserId)
//for _, userId := range noticeUserId {
// fmt.Println("userId")
// cr.cache.IncreaseNewMessageTotal(userId, request.SessionId)
//}
//fmt.Println("NewMessage 6")
////发送websocket消息提醒通知
//var notice = dto.MessageListType{}
//notice.BuildMessage(resp.Data)
//fmt.Printf("ws消息提醒:%+v\n", notice)
//_, err = consts.ChatRoom.SendSessionMessage(chatUser.ID, request.SessionId, ws.NewChatMsgType, notice)
//if err != nil {
// log.Print("发送新消息通知失败", zap.Error(err), zap.Any("notice", notice))
//}
//cr.robot.Listen(&data)
//fmt.Println("NewMessage 7 -end")
////发送app推送(无横幅推送)
////go func() {
//// omitMessage := ""
//// switch request.MsgType {
//// case accountFiee.MsgType_TextMsgType:
//// runMsg := []rune(request.Text)
//// if len(runMsg) > 15 {
//// omitMessage = string(runMsg[:15]) + "..."
//// } else {
//// omitMessage = request.Text
//// }
//// case accountFiee.MsgType_ImageMsgType:
//// omitMessage = "[图片]"
//// case accountFiee.MsgType_AudioMsgType:
//// omitMessage = "[音频]"
//// case accountFiee.MsgType_VideoMsgType:
//// omitMessage = "[视频]"
//// default:
//// omitMessage = "新消息请查收"
//// }
//// for _, userId := range noticeUserId {
//// _ = asPusher.NewArtistinfoUniPush().NewChatMessageNotice(userId, omitMessage)
//// }
////}()
service.Success(c)
}
func (cr ChatHandler) MessageList(c *gin.Context) {
var request dto.MessageListRequest
if err := c.ShouldBindJSON(&request); err != nil {
service.Error(c, err)
return
}
//domain := c.GetHeader("domain")
//fmt.Println("MessageList domain:", domain)
if (request.Direction == 0 && !request.Recent) || (request.Direction > 0 && request.Recent) {
service.Error(c, errors.New("组合条件校验失败"))
return
}
if request.SessionId == "" {
service.Error(c, errors.New("sessionId不能为空"))
return
}
if request.PageSize < -1 {
service.Error(c, errors.New("pageSize校验错误"))
return
}
var resp = make([]*dto.MessageListType, 0)
if request.CurrentId == 0 && request.Direction == 1 {
service.Success(c, resp)
return
}
accessUser, code := jwt.ParseToChatUser(c)
if code != 0 {
service.ErrWithCode(c, code)
return
}
//if request.SessionId == "" {
// request.SessionId = cr.cache.GetUserSession(tokenResult.UserInfo.ID)
// if request.SessionId == "" {
// service.Success(c, resp)
// return
// }
//}
messages := cr.cache.GetChatRecord(request.SessionId)
//messages := []*accountFiee.ChatRecordData{}
var returnDataIdList = make([]int64, 0)
defer func() {
//获取最新数据时,重置新消息数量统计
if request.Direction == 1 || request.Recent {
cr.cache.ResetNewMessageTotal(accessUser.ID, request.SessionId)
}
//设置消息已被客服阅读,当客服重新通过通过websocket连接时这些消息将不被纳入新消息数量统计
if len(returnDataIdList) > 0 && accessUser.Role == 2 {
for _, hasReadId := range returnDataIdList {
for i, message := range messages {
if message.ID == hasReadId {
messages[i].WaiterRead = 1
}
}
}
err := cr.cache.CoverChatRecord(request.SessionId, messages)
if err != nil {
log.Print("设置消息已读失败", zap.Error(err))
}
for _, v := range messages {
_, err = service.AccountFieeProvider.SaveChatRecord(context.Background(), v)
if err != nil {
log.Print("设置消息已读失败", zap.Error(err))
}
}
}
}()
if len(messages) == 0 {
//从数据库获取
recordResp, err := service.AccountFieeProvider.GetChatRecordList(c, &accountFiee.GetChatRecordListRequest{
Query: &accountFiee.ChatRecordData{SessionId: request.SessionId},
Page: 1,
PageSize: -1,
//Where: fmt.Sprintf("id %s %d", utils.IfGec(request.Direction == 1, "<", ">"), request.CurrentId),
})
if err != nil {
service.Error(c, err)
return
}
messages = recordResp.List
err = cr.cache.CoverChatRecord(request.SessionId, messages)
if err != nil {
log.Print("覆盖聊天记录失败", zap.Error(err))
}
}
if request.Recent {
if int64(len(messages)) >= request.PageSize {
messages = messages[len(messages)-int(request.PageSize):]
}
var now = time.Now()
for _, message := range messages {
if request.InHour > 0 {
messageCreatedAt, _ := stime.StringToTime(message.CreatedAt)
if now.Sub(*messageCreatedAt) >= request.InHour*time.Hour {
continue
}
}
returnDataIdList = append(returnDataIdList, message.ID)
var msg = &dto.MessageListType{}
msg.BuildMessage(message)
resp = append(resp, msg)
}
} else {
sort.Slice(messages, func(i, j int) bool {
if request.Direction == 1 {
return messages[i].ID < messages[j].ID
} else {
return messages[i].ID > messages[j].ID
}
})
fmt.Printf("data is %+v\n", messages)
total := 0
for i, message := range messages {
switch request.Direction {
case 1: //向下查找找比CurrentId大的数据
if message.ID <= request.CurrentId {
continue
}
case 2: //向上查找找比CurrentId小的数据
if message.ID >= request.CurrentId {
continue
}
}
message := message
fmt.Println(i, message.ID)
if request.PageSize != -1 && int64(total+1) > request.PageSize {
continue
}
total++
returnDataIdList = append(returnDataIdList, message.ID)
var msg = &dto.MessageListType{}
msg.BuildMessage(message)
resp = append(resp, msg)
}
}
//二次排序
sort.Slice(resp, func(i, j int) bool {
return resp[i].ID < resp[j].ID
})
//优化空列表
for i, v := range resp {
if v.Message.Media == nil {
resp[i].Message.Media = []dto.MessageMedia{}
}
}
if accessUser.Role == 1 {
}
service.Success(c, resp)
}
func (cr ChatHandler) Upload(c *gin.Context) {
fmt.Println("111111111111")
//获取用户信息
chatUser, code := jwt.ParseToChatUser(c)
if code != 0 {
service.ErrWithCode(c, code)
return
}
fmt.Printf("chatUser is %#v\n", chatUser)
//获取文件对象
file, err := c.FormFile("file")
if err != nil {
log.Print("ERROR: upload file failed. ", zap.Error(err))
return
}
duration := c.PostForm("duration")
fmt.Println(duration)
ext := c.PostForm("ext")
fileExt := strings.ToLower(path.Ext(file.Filename))
if ext != "" {
fileExt = ext
}
fileType := e.DetectFileTypeByExtension(fileExt)
if fileType == e.Audio {
if !slices.Contains([]string{".mp4", ".aac", ".mp3", ".opus", ".wav"}, fileExt) {
service.Error(c, errors.New("不支持的格式"))
return
}
}
//计算md5
tmp, err := file.Open()
if err != nil {
service.Error(c, errors.New("上传失败"))
return
}
fileContent, err := io.ReadAll(tmp)
if err != nil {
service.Error(c, errors.New("文件读取失败"))
return
}
hash := md5.New()
_, err = hash.Write(fileContent)
if err != nil {
service.Error(c, errors.New("文件读取失败"))
return
}
md5Bytes := hash.Sum(nil) // 获取 MD5 字节切片
md5String := hex.EncodeToString(md5Bytes) // 转换为十六进制字符串表示
//检查文件是否存在
checkResp, err := service.AccountFieeProvider.GetChatMediaList(c, &accountFiee.GetChatMediaListRequest{Query: &accountFiee.ChatMediaData{Md5: md5String}, Page: 1, PageSize: 1})
if err != nil {
log.Print("md5查询附件失败", zap.Error(err))
}
if checkResp != nil && checkResp.Total > 0 {
service.Success(c, checkResp.List[0])
return
}
//文件不存在则上传文件
filename, _ := uuid.NewV4()
defer tmp.Close()
fileBuffer := bytes.NewBuffer(fileContent)
var bosUrl string
bosUrl, err = upload.UploadWithBuffer(fileBuffer, fmt.Sprintf("%d/%v%v", chatUser.ID, filename, fileExt))
if err != nil {
service.Error(c, err)
return
}
//存到数据库
var durationInt64, _ = strconv.ParseInt(duration, 10, 64)
var mediaData = accountFiee.ChatMediaData{
Url: bosUrl,
Md5: md5String,
Size: fmt.Sprintf("%d", file.Size),
Ext: fileExt,
Duration: durationInt64,
}
resp, err := service.AccountFieeProvider.CreateChatMedia(c, &mediaData)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, resp.Data)
}
func (cr ChatHandler) UserMessageStat(c *gin.Context) {
var request accountFiee.GetChatUserListRequest2
if err := c.ShouldBindJSON(&request); err != nil {
service.Error(c, err)
return
}
//获取用户信息
chatUser, code := jwt.ParseToChatUser(c)
if code != 0 {
service.ErrWithCode(c, code)
return
}
result := cr.cache.GetNewMessageStat(c, chatUser.ID)
if len(result) == 0 {
service.Success(c, result)
return
}
fmt.Printf("cache stat:%+v\n", result)
request.Page = 1
request.PageSize = int64(len(result))
for i, item := range result {
if item.UserId == 0 {
sessionId, _ := strconv.Atoi(item.SessionId)
item.UserId = int64(sessionId)
result[i].UserId = int64(sessionId)
}
request.UserIdIn = append(request.UserIdIn, item.UserId)
}
fmt.Printf("protoReq.UserIdIn:%+v\n", request.UserIdIn)
listRes, err := service.AccountFieeProvider.GetChatUserList2(c, &request)
if err != nil {
service.Error(c, err)
return
}
fmt.Printf("GetChatUserList:%+v\n", listRes)
for i, item := range result {
for _, user := range listRes.List {
if item.UserId == user.UserId {
user := user
result[i].Name = user.Name
//result[i].ArtistUid = user.ArtistUid
break
}
}
if result[i].Name == "" {
result[i].Name = logic.BeautifulZeroNameWithPhone(result[i].Name, result[i].UserId)
}
}
//筛选
if request.Account != "" || request.Name != "" {
newData := []dto.UserMsgStatic{}
for _, v := range listRes.List {
for _, vv := range result {
if v.UserId == vv.UserId {
vv := vv
newData = append(newData, vv)
}
}
}
result = newData
}
reverse(result)
if chatUser.Role == 1 {
userSessionId := fmt.Sprintf("%d", chatUser.ID)
newResp := []dto.UserMsgStatic{}
for _, v := range result {
if v.SessionId == userSessionId {
newResp = append(newResp, v)
service.Success(c, newResp)
return
}
}
}
service.Success(c, result)
}
func reverse(slice []dto.UserMsgStatic) {
for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 {
slice[i], slice[j] = slice[j], slice[i]
}
}
func (cr ChatHandler) VoiceToText(c *gin.Context) {
var req dto.VoiceToTextRequest
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, err)
return
}
detail, err := service.AccountFieeProvider.GetChatMediaDetail(c, &accountFiee.GetChatMediaByIdRequest{Id: req.MediaId})
if err != nil {
service.Error(c, err)
return
}
if detail.ConvText != "" {
service.Success(c, map[string]string{"convText": detail.ConvText})
return
}
voiceApi := voice.NewVoiceApi()
detail.ConvText, err = voiceApi.ToTextFromUrl(detail.Url)
if err != nil {
service.Error(c, errors.New("语音转文字失败"))
return
}
defer func() {
service.AccountFieeProvider.UpdateChatMedia(context.Background(), detail)
}()
service.Success(c, map[string]string{"convText": detail.ConvText})
}
func (cr ChatHandler) UserDetail(c *gin.Context) {
var req dto.UserDetailReq
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, err)
return
}
var chatUser *accountFiee.ChatUserData
if req.ChatUserId == 0 { //不传ChatUserId则从token获取
var code e.ErrorCodeType
chatUser, code = jwt.ParseToChatUser(c)
if code != 0 {
service.ErrWithCode(c, code)
return
}
} else {
var err error
chatUser, err = service.AccountFieeProvider.GetChatUserDetail(c, &accountFiee.GetChatUserByIdRequest{
Id: req.ChatUserId,
})
if err != nil {
service.Error(c, err)
return
}
}
//fmt.Printf("chatUser:%#v\n", chatUser)
//if chatUser.Origin == "fiee" {
// chatUser.Origin = "app"
//}
resp, err := service.AccountFieeProvider.Info(c, &accountFiee.InfoRequest{ID: uint64(chatUser.OriginId), Domain: chatUser.Origin})
if err != nil {
service.Error(c, err)
return
}
var detail = dto.UserDetailResp{
UserId: resp.Id,
ChatUserId: chatUser.ID,
RnStatus: resp.Status,
SubNum: resp.SubNum,
RealName: resp.Name,
Age: "∞",
Gender: resp.Sex,
NativePlace: resp.PlaceOfResidence,
Phone: resp.TelNum,
GroupPhoto: resp.GroupPhoto,
}
service.Success(c, detail)
}

View File

@ -1,13 +0,0 @@
// Package autoReply -----------------------------
// @file : intreface.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/13 16:15
// -------------------------------------------
package asChat
type IReplyRuler interface {
Name() string //规则名称
Check()
RunScript() string //运行脚本
}

View File

@ -1,113 +0,0 @@
// Package service -----------------------------
// @file : chat.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/13 19:04
// -------------------------------------------
package logic
import (
"context"
"errors"
"fmt"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/common/ws"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/asChat/chatCache"
"fonchain-fiee/pkg/service/asChat/consts"
"fonchain-fiee/pkg/service/asChat/dto"
"go.uber.org/zap"
"log"
"sync"
)
var cacheMap = make(map[int64]dto.NewMessageRequest)
var newMessageLocker sync.Mutex
func NewMessage(ctx context.Context, cache *chatCache.ChatCache, sender *accountFiee.ChatUserData, request dto.NewMessageRequest) (err error) {
newMessageLocker.Lock()
defer newMessageLocker.Unlock()
if request.SessionId == "" {
return errors.New("sessionId不能为空")
}
if request.MsgType == 0 {
return errors.New("msgType不能为空")
}
//短时间重复消息不发送
if request.AtUserId != 0 && request.Robot {
if msgRecord, ok := cacheMap[request.AtUserId]; ok {
if msgRecord.SessionId == "" {
cacheMap[request.AtUserId] = request
} else {
fmt.Println(request.LocalStamp - msgRecord.LocalStamp)
if msgRecord.Message.Text == request.Message.Text && request.LocalStamp-msgRecord.LocalStamp < 1 { //秒级
cacheMap[request.AtUserId] = request
return nil
} else {
cacheMap[request.AtUserId] = request
}
}
} else {
cacheMap[request.AtUserId] = request
}
}
//存储入库
if sender.NickName == "" {
//sender.NickName = fmt.Sprintf("未知用户(%d)", sender.ID)
sender.NickName = BeautifulZeroNameWithPhone(sender.NickName, sender.ID)
}
fmt.Println("NewMessage 3333333333333333333333333333333333")
var data = accountFiee.ChatRecordData{
SessionId: request.SessionId,
UserId: sender.ID,
Name: sender.NickName,
Avatar: sender.Avatar,
MsgType: request.MsgType,
Content: request.Message.Text,
LocalStamp: request.LocalStamp,
Medias: nil,
Role: sender.Role,
}
if len(request.Message.Media) > 0 {
for _, media := range request.Message.Media {
data.Medias = append(data.Medias, &accountFiee.ChatMediaData{
ID: media.MediaId,
})
}
}
fmt.Println("NewMessage 4444444444444444444444444444444444")
resp, err := service.AccountFieeProvider.CreateChatRecord(ctx, &data)
if err != nil {
return errors.New("消息发送失败")
}
fmt.Printf("CreateChatRecord resp:%+v\n", resp)
//录入缓存
err = cache.AddChatRecord(request.SessionId, resp.Data)
if err != nil {
log.Printf("cache.AddChatRecord 失败:%v", err)
return errors.New("消息发送失败")
}
fmt.Println("NewMessage 5 消息数量+1")
if sender.Role != 3 {
//新消息数量统计+1
noticeUserId := consts.ChatRoom.GetUserIdInSession(request.SessionId, sender.ID)
fmt.Println("NewMessage 5.1 消息数量配置结束")
fmt.Printf("noticeUserId %+v\n", noticeUserId)
for _, userId := range noticeUserId {
fmt.Println("userId")
_ = cache.IncreaseNewMessageTotal(userId, request.SessionId)
}
}
fmt.Println("NewMessage 6")
//发送websocket消息提醒通知
var notice = dto.MessageListType{}
notice.BuildMessage(resp.Data)
fmt.Printf("ws消息提醒:%+v\n", notice)
_, err = consts.ChatRoom.SendSessionMessage(sender, request.SessionId, ws.NewChatMsgType, notice)
if err != nil {
log.Print("发送新消息通知失败", zap.Error(err), zap.Any("notice", notice))
}
fmt.Println("NewMessage 7 -end")
return nil
}

View File

@ -1,42 +0,0 @@
package logic
import (
"context"
"fmt"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/utils"
)
// 对没有名字的name进行优化
func beautifulZeroName(name string, userId int64) string {
return utils.IfGec(name == "", fmt.Sprintf("未实名用户:%d", userId), name)
}
var userIdMapPhone = make(map[int64]string)
func BeautifulZeroNameWithPhone(name string, userId int64) string {
var ctx = context.Background()
if name == "" {
telNum, ok := userIdMapPhone[userId]
if ok {
return telNum
}
chatUserRes, err := service.AccountFieeProvider.GetChatUserDetail(ctx, &accountFiee.GetChatUserByIdRequest{Id: userId})
if err != nil {
return fmt.Sprintf("未实名用户:%d", userId)
} else {
if userRes, errs := service.AccountFieeProvider.Info(ctx, &accountFiee.InfoRequest{
Domain: chatUserRes.Origin,
ID: uint64(chatUserRes.OriginId),
Scene: "",
}); errs != nil {
return fmt.Sprintf("未实名用户:%d", userId)
} else {
userIdMapPhone[userId] = userRes.TelNum
return userRes.TelNum
}
}
}
return name
}

View File

@ -1,26 +0,0 @@
# asChat 客服聊天
## 聊天室主要流程与功能描述
1. 用户通过画家包登录
2. 打开客服页面。 画家宝客户端自动进行websocket连接后台会自动创建一个默认聊天室聊天室携带一个SessionId
3. 用户调用api接口发送消息。 服务端接收到消息后会通过websocket通知聊天室里面所有用户。
4. erp首次打开客服菜单时会进行websocket连接并调用一次api接口刷新消息列表。后续通过websocket接收消息推送收到消息时应主动调用一次消息列表刷新接口。
5. erp客服端发送消息时加入到此聊天室。
6. 用户端调用api接口获取新消息列表。
## 客户端应具备的其它功能
1. weboscket断开自动重连
2. 当通过websocket接收到错误类型的消息应具备对应的错误处理机制<p>
错误消息示例
```json
{"type":1,"content":"Connection error:登录状态失效","from":"0","to":"null"}
```
## 服务端应具备的功能
1. 通过redis缓存聊天消息
2. 通过redis缓存用户的sessionId避免ws断开后找不到之前的sessionId
3. 客服端由于不是画家宝用户没有userId。在websocket连接时如果找不到userId应该为其在画家宝创建一个账号。且经纪人不可见。
4. 由于没有创建聊天室的需求,所以每个用户使用一个聊天室即可。客服与之对话时,就自动加入用户端的聊天室
5. 新消息统计
- 当发送消息时,该聊天室中除了发信者以外,其它用户的新消息数都+1录入缓存。
- 当新客服人员加入时,没有新消息统计的缓存。~~他的新消息数量应该从创建时间开始计算~~,所以都是0。

View File

@ -1,39 +0,0 @@
// Package autoReply -----------------------------
// @file : KeywordsReplyRuler.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/13 16:21
// -------------------------------------------
package robot
import (
"time"
)
// 使用go开发一个自动回复功能
// 一个自动回复消息有多种触发条件:
// 1. 关键词触发
// 2. 进入聊天系统后直接发送
// 3. 若干秒不回复自动发送
//func (k KeywordsRuleChecker) Do(sessionId string, response string, chatRoom *ws.ChatRoom) (err error) {
// var notice = dto.MessageListType{}
// notice.BuildMessage(response)
// _, err = chatRoom.SendSessionMessage(1, sessionId, ws.NewChatMsgType, notice)
// return nil
//}
type AutoReply struct {
Response string `json:"response"`
Rules map[string]IRobotTask `json:"rules"`
}
type AutoReplyRule struct {
Enable bool `json:"enable"`
Keywords []string `json:"keywords"`
ReplyTimeout int `json:"replyTimeout"` // 回复超时时间
}
type AutoReplyManager struct {
replies []AutoReply
lastMessage time.Time
}

View File

@ -1,31 +0,0 @@
# robot 聊天机器人
web端和后端交互式时增删改查的规则配置是存放在rules对象中的。在数据库中rules字段是作为json字符串存放的。
```json
{
"title": "1",
"response": "11",
"rules": {
"keywords": {
"enable": true,
"content": "什么,为什么,怎么办,不是"
},
"joinSession": {
"enable": true
},
"noReplyAfter": {
"enable": false,
"secondDuration": 1
}
},
"status": 1
}
```
如果有新增的规则直接在rules对象中添加字段即可。然后去 [./rulerList.go](./rulerList.go) 中,增加规则的解析方法。
目前,在[./rulerList.go](./rulerList.go)定义了三种回复规则的解析方式:
- keywords :关键字回复
- joinSession用户打开聊天窗口后
- noReplyAfter客服指定时间没有回复后
## 注意
- 目前不支持用户多端登录,会导致用户收到重复消息

View File

@ -1,29 +0,0 @@
// Package robot -----------------------------
// @file : replyRuler.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/13 17:39
// -------------------------------------------
package robot
import (
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/common/ws"
)
// 回复规则
type Reply struct {
Title string
Response string
Rules []IRobotTask
}
func (r *Reply) Hit(event ws.ListenEventData, robotInfo *accountFiee.ChatUserData) (hit bool, rule IRobotTask) {
for _, rule = range r.Rules {
hit = rule.Hit(event, robotInfo)
if hit {
return
}
}
return
}

View File

@ -1,265 +0,0 @@
// Package robot -----------------------------
// @file : robot.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/13 17:41
// -------------------------------------------
package robot
import (
"context"
"fmt"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/common/ws"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/asChat/chatCache"
"fonchain-fiee/pkg/service/asChat/consts"
"fonchain-fiee/pkg/service/asChat/dto"
"log"
"sync"
"time"
)
func NewRobot(cache *chatCache.ChatCache) *Robot {
ctx := context.Background()
robotQuery, err := service.AccountFieeProvider.GetChatUserList(ctx, &accountFiee.GetChatUserListRequest{
Query: &accountFiee.ChatUserData{Role: 3},
Page: 1, PageSize: 1,
})
if err != nil {
panic("聊天机器人初始化失败,err:" + err.Error())
}
var robotInfo *accountFiee.ChatUserData
if robotQuery.Total > 0 {
robotInfo = robotQuery.List[0]
} else {
robotInfo = &accountFiee.ChatUserData{
NickName: "阿泰",
Role: 3,
Origin: "fontree",
}
createChatUserResp, errs := service.AccountFieeProvider.CreateChatUser(ctx, robotInfo)
if errs != nil {
panic("聊天机器人创建失败,err:" + errs.Error())
}
robotInfo = createChatUserResp.Data
}
r := &Robot{
Info: robotInfo,
EventListener: &ws.EventListener{
Name: "robot1",
ListenEvents: []ws.ListenEvent{ //只监听消息推送事件
{ws.EventUserJoin, ws.EventProgressAfter},
{ws.EventChatMessage, ws.EventProgressBefore},
},
Chan: make(ws.ListenEventChan),
},
cache: cache,
}
err = r.ReloadRules(ctx)
fmt.Println("机器人规则加载完成,结果:", err)
consts.ChatRoom.RegisterEventListener(r.EventListener)
go r.Run()
return r
}
type Robot struct {
Info *accountFiee.ChatUserData //机器人信息
joinSessionRules, keywordsRules, noReplyAfterRules []IRobotTask //自动回复规则
DelayTask []IRobotTask //延时任务
ticker *time.Ticker //定时器
stopChan chan struct{} //停止管道
isRunning bool //运行状态
mu sync.Mutex
*ws.EventListener
cache *chatCache.ChatCache
}
//func (r *Robot) Listen(record *accountFiee.ChatRecordData) {
// for _, replyRules := range r.Rules {
// for _, rule := range replyRules.Rules {
// hit, runTime, function := rule.Hit(record)
// if hit && function != nil {
// if runTime.IsZero() {
// go func() {
// err := function(r.Info.ID, replyRules.Response)
// if err != nil {
// log.Printf("聊天机器人[%d]回复消息失败:%v", r.Info.ID, err)
// }
// }()
// } else {
// r.mu.Lock()
// r.DelayTask = append(r.DelayTask, RobotTask{
// RunTime: runTime,
// Run: function,
// Response: replyRules.Response,
// })
// r.mu.Unlock()
// // 添加任务后启动定时任务(如果未运行)
// if !r.isRunning {
// go r.Run()
// }
// }
// break
// }
// }
// }
//}
func (r *Robot) Run() {
r.mu.Lock()
if r.isRunning {
r.mu.Unlock()
return
}
r.isRunning = true
r.ticker = time.NewTicker(time.Second)
r.stopChan = make(chan struct{})
r.mu.Unlock()
defer func() {
r.mu.Lock()
r.isRunning = false
if r.ticker != nil {
r.ticker.Stop()
r.ticker = nil
}
r.stopChan = nil
r.mu.Unlock()
}()
for {
select {
default:
time.Sleep(200 * time.Millisecond)
case <-r.ticker.C:
r.mu.Lock()
if len(r.DelayTask) == 0 {
r.mu.Unlock()
break
//return // 没有任务时退出
}
now := time.Now()
var remainingTasks []IRobotTask
for _, task := range r.DelayTask {
if now.After(task.RunTime()) {
// 执行任务
go func() {
err := task.Run(r.cache)
if err != nil {
log.Printf("聊天机器人[%d]延时回复消息失败:%v", r.Info.ID, err)
} else {
log.Printf("聊天机器人[%d]延时回复消息成功", r.Info.ID)
}
}()
} else {
// 保留未到期的任务
remainingTasks = append(remainingTasks, task)
}
}
r.DelayTask = remainingTasks
r.mu.Unlock()
case <-r.stopChan:
return
case event := <-r.EventListener.Chan:
fmt.Printf("robot listen event:%#v\n", event)
r.mu.Lock()
//加入聊天室规则
hasHit := false
for _, rule := range r.joinSessionRules {
hit := rule.Hit(event, r.Info)
fmt.Printf("规则【%s】校验结果:%v\n", rule.GetTitle(), hit)
if hit {
hasHit = true
if rule.RunTime().IsZero() {
err := rule.Run(r.cache)
if err != nil {
log.Printf("robot 执行任务失败:%v\n", err)
}
} else {
r.RegisterDelayTask(rule)
}
}
}
if !hasHit {
for _, rule := range r.keywordsRules {
hit := rule.Hit(event, r.Info)
fmt.Printf("规则【%s】校验结果:%v\n", rule.GetTitle(), hit)
if hit {
hasHit = true
fmt.Println("命中规则:", rule.GetTitle())
if rule.RunTime().IsZero() {
err := rule.Run(r.cache)
if err != nil {
log.Printf("robot 执行任务失败:%v\n", err)
}
} else {
r.RegisterDelayTask(rule)
}
}
}
}
if !hasHit {
for _, rule := range r.noReplyAfterRules {
hit := rule.Hit(event, r.Info)
fmt.Printf("规则【%s】校验结果:%v\n", rule.GetTitle(), hit)
if hit {
hasHit = true
fmt.Println("命中规则:", rule.GetTitle())
if rule.RunTime().IsZero() {
err := rule.Run(r.cache)
if err != nil {
log.Printf("robot 执行任务失败:%v\n", err)
}
} else {
r.RegisterDelayTask(rule)
}
}
}
}
r.mu.Unlock()
}
}
}
// Stop 主动停止机器人的定时任务
func (r *Robot) Stop() {
r.mu.Lock()
if r.stopChan != nil {
close(r.stopChan)
}
r.mu.Unlock()
}
func (r *Robot) RegisterDelayTask(task IRobotTask) {
if task.Run == nil {
return
}
r.DelayTask = append(r.DelayTask, task)
}
// 重载回复规则
func (r *Robot) ReloadRules(ctx context.Context) error {
r.mu.Lock()
defer r.mu.Unlock()
r.joinSessionRules = []IRobotTask{}
r.keywordsRules = []IRobotTask{}
r.noReplyAfterRules = []IRobotTask{}
ruleListRes, err := service.AccountFieeProvider.GetChatAutoReplyRulerList(ctx, &accountFiee.GetChatAutoReplyRulerListRequest{
Query: &accountFiee.ChatAutoReplyRulerData{Status: 1},
Page: 1,
PageSize: -1,
})
if err != nil {
log.Printf("robot 查询回复规则失败:%v\n", err)
return fmt.Errorf("robot 查询回复规则失败:%v\n", err)
} else {
var data []*dto.ChatAutoReplyData
for _, v := range ruleListRes.List {
tmp := dto.ChatAutoReplyData{}
tmp.Parse(v)
data = append(data, &tmp)
}
r.joinSessionRules, r.keywordsRules, r.noReplyAfterRules = ParseReplyRule(data)
}
return nil
}

View File

@ -1,64 +0,0 @@
// Package autoReply -----------------------------
// @file : rulerList.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/13 16:16
// -------------------------------------------
package robot
import (
"fmt"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/common/ws"
"fonchain-fiee/pkg/service/asChat/chatCache"
"fonchain-fiee/pkg/service/asChat/dto"
"strings"
"time"
)
type IRobotTask interface {
Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool)
Run(cache *chatCache.ChatCache) error
RunTime() time.Time
SetResponse(response string)
GetResponse() string
SetTitle(title string)
GetTitle() string
}
// 自动回复规则结构转换
func ParseReplyRule(data []*dto.ChatAutoReplyData) (joinSessionRules, keywordsRules, noReplyAfterRules []IRobotTask) {
for _, responseRules := range data {
responseRules := responseRules
for ruleName, v := range responseRules.Rules {
if !v.Enable {
continue
}
switch ruleName {
case "keywords": //关键字回复
var keywords []string
if v.Content == "" {
continue
} else {
keywords = strings.Split(v.Content, ",")
}
fmt.Println("ParseReplyRule 解析keywords:", keywords)
r := NewReplyWhenHitKeywords(responseRules.Title+"-keywords", keywords)
r.SetResponse(responseRules.Response)
keywordsRules = append(keywordsRules, r)
case "joinSession": //加入聊天后回复
r := NewReplyWhenUserJoinSession(responseRules.Title + "-joinSession")
r.SetResponse(responseRules.Response)
joinSessionRules = append(joinSessionRules, r)
case "noReplyAfter": //指定时间没有回复则自动回复
if v.SecondDuration == 0 {
continue
}
r := NewReplyWhenWaiterNoAction(responseRules.Title+"-noReplyAfter", v.SecondDuration)
r.SetResponse(responseRules.Response)
noReplyAfterRules = append(noReplyAfterRules, r)
}
}
}
return
}

View File

@ -1,102 +0,0 @@
// Package robot -----------------------------
// @file : ruler_ReplyWhenWaiterNoAction.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/13 18:02
// -------------------------------------------
package robot
import (
"context"
"fmt"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/common/ws"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/asChat/chatCache"
"fonchain-fiee/pkg/service/asChat/dto"
"fonchain-fiee/pkg/service/asChat/logic"
"time"
)
// 客服指定时间不回复则自动回复
func NewReplyWhenWaiterNoAction(title string, delaySecond time.Duration) IRobotTask {
return &RobotTaskReplyWhenWaiterNoAction{
delaySecond: delaySecond,
title: title,
}
}
type RobotTaskReplyWhenWaiterNoAction struct {
title string
runTime time.Time
Response string
Receiver *accountFiee.ChatUserData
Sender *accountFiee.ChatUserData
Msg string
Resp string
delaySecond time.Duration
}
func (r *RobotTaskReplyWhenWaiterNoAction) Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool) {
if event.Client == nil || event.EventType != ws.EventChatMessage {
return
}
//客服和机器人的的消息不需要处理
if event.ChatUser.Role != 1 {
return
}
hit = true // 立即保存SessionId的值
r.Sender = sender
r.Receiver = event.ChatUser
r.runTime = time.Now().Add(r.delaySecond * time.Second)
return
}
func (r *RobotTaskReplyWhenWaiterNoAction) Run(cache *chatCache.ChatCache) error {
clientSessionId := fmt.Sprintf("%d", r.Receiver.ID)
fmt.Println("延时回复 sessionID:", clientSessionId)
//如果客服已经回复则不发送消息
chatRecordListRes, err := service.AccountFieeProvider.GetChatRecordList(context.Background(), &accountFiee.GetChatRecordListRequest{
Query: &accountFiee.ChatRecordData{
SessionId: clientSessionId,
},
Page: 1,
PageSize: 1,
Order: "created_at desc",
})
if err != nil || chatRecordListRes.Total == 0 {
return err
}
checkUserId := chatRecordListRes.List[0].UserId
checkChatUser, err := service.AccountFieeProvider.GetChatUserDetail(context.Background(), &accountFiee.GetChatUserByIdRequest{Id: checkUserId})
if err != nil || checkChatUser.Role != 1 {
return err
}
err = logic.NewMessage(context.Background(), cache, r.Sender, dto.NewMessageRequest{
Waiter: true,
Robot: true,
AtUserId: r.Receiver.ID,
SessionId: clientSessionId,
Message: dto.Message{
MsgType: 1,
Text: r.Resp,
LocalStamp: time.Now().Unix(),
},
})
return err
}
func (r *RobotTaskReplyWhenWaiterNoAction) RunTime() time.Time {
return r.runTime
}
func (r *RobotTaskReplyWhenWaiterNoAction) SetResponse(response string) {
r.Resp = response
}
func (r *RobotTaskReplyWhenWaiterNoAction) GetResponse() string {
return r.Response
}
func (r *RobotTaskReplyWhenWaiterNoAction) SetTitle(title string) {
r.title = title
}
func (r *RobotTaskReplyWhenWaiterNoAction) GetTitle() string {
return r.title
}

View File

@ -1,80 +0,0 @@
package robot
import (
"context"
"fmt"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/common/ws"
"fonchain-fiee/pkg/service/asChat/chatCache"
"fonchain-fiee/pkg/service/asChat/dto"
"fonchain-fiee/pkg/service/asChat/logic"
"strings"
"time"
)
type RobotTaskWithKeyworkds struct {
title string
runTime time.Time
Response string
Receiver *accountFiee.ChatUserData
Sender *accountFiee.ChatUserData
Msg string
Resp string
keywords []string
}
func NewReplyWhenHitKeywords(title string, keywords []string) IRobotTask {
return &RobotTaskWithKeyworkds{title: title, keywords: keywords}
}
func (r *RobotTaskWithKeyworkds) Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool) {
if event.EventType != ws.EventChatMessage || event.Msg == "" || event.Client == nil || event.ChatUser == nil {
return
}
if event.ChatUser.Role != 1 {
return
}
r.Sender = sender
r.Receiver = event.ChatUser
for _, v := range r.keywords {
if strings.Contains(event.Msg, v) {
fmt.Printf("关键词比对:%s ----- %s : true", event.Msg, v)
hit = true
break
}
fmt.Printf("关键词比对:%s ----- %s: false", event.Msg, v)
}
return
}
func (r *RobotTaskWithKeyworkds) Run(cache *chatCache.ChatCache) (err error) {
err = logic.NewMessage(context.Background(), cache, r.Sender, dto.NewMessageRequest{
Waiter: true,
Robot: true,
AtUserId: r.Receiver.ID,
SessionId: fmt.Sprintf("%d", r.Receiver.ID),
Message: dto.Message{
MsgType: 1,
Text: r.Resp,
LocalStamp: time.Now().Unix(),
},
})
return
}
func (r *RobotTaskWithKeyworkds) RunTime() time.Time {
return time.Time{}
}
func (r *RobotTaskWithKeyworkds) SetResponse(response string) {
r.Resp = response
}
func (r *RobotTaskWithKeyworkds) GetResponse() string {
return r.Response
}
func (r *RobotTaskWithKeyworkds) SetTitle(title string) {
r.title = title
}
func (r *RobotTaskWithKeyworkds) GetTitle() string {
return r.title
}

View File

@ -1,95 +0,0 @@
package robot
import (
"context"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/common/ws"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/asChat/chatCache"
"fonchain-fiee/pkg/service/asChat/dto"
"fonchain-fiee/pkg/service/asChat/logic"
"strconv"
"time"
)
func NewReplyWhenUserJoinSession(title string) IRobotTask {
return &ReplyWhenUserJoinSession{title: title}
}
type ReplyWhenUserJoinSession struct {
Response string
Sender *accountFiee.ChatUserData
Msg string
Resp string
sessionId string
atUserId int
title string
}
func (r *ReplyWhenUserJoinSession) Hit(event ws.ListenEventData, sender *accountFiee.ChatUserData) (hit bool) {
if event.EventType != ws.EventUserJoin {
return
}
if event.Client == nil {
return
}
ctx := context.Background()
queryRes, err := service.AccountFieeProvider.GetChatRecordList(ctx, &accountFiee.GetChatRecordListRequest{
Query: &accountFiee.ChatRecordData{
SessionId: event.Client.SessionId,
},
Page: 1,
PageSize: 1,
Order: "created_at desc",
})
if err != nil {
return
}
//如果最近一次的消息也是机器人发送的,就不再发送了
for i, v := range queryRes.List {
if i == 0 {
if v.UserId == sender.ID {
return
} else {
break
}
}
}
hit = true
r.Sender = sender
r.sessionId = event.Client.SessionId
r.atUserId, _ = strconv.Atoi(event.Client.SessionId)
return
}
func (r *ReplyWhenUserJoinSession) Run(cache *chatCache.ChatCache) (err error) {
err = logic.NewMessage(context.Background(), cache, r.Sender, dto.NewMessageRequest{
Waiter: true,
Robot: true,
AtUserId: int64(r.atUserId),
SessionId: r.sessionId,
Message: dto.Message{
MsgType: 1,
Text: r.Resp,
LocalStamp: time.Now().Unix(),
},
})
return
}
func (r *ReplyWhenUserJoinSession) RunTime() time.Time {
return time.Time{}
}
func (r *ReplyWhenUserJoinSession) SetResponse(response string) {
r.Resp = response
}
func (r *ReplyWhenUserJoinSession) GetResponse() string {
return r.Response
}
func (r *ReplyWhenUserJoinSession) SetTitle(title string) {
r.title = title
}
func (r *ReplyWhenUserJoinSession) GetTitle() string {
return r.title
}

View File

@ -1,20 +0,0 @@
// Package robot -----------------------------
// @file : task.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2025/6/13 18:02
// -------------------------------------------
package robot
import (
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/pkg/service/asChat/chatCache"
"time"
)
type RobotTask struct {
RunTime time.Time
Run func(msg string, cache *chatCache.ChatCache, Sender *accountFiee.ChatUserData) error
Response string
ChatUser *accountFiee.ChatUserData
}

View File

@ -1,46 +0,0 @@
// Package asChat -----------------------------
// @file : service.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2024/9/10 下午7:05
// -------------------------------------------
package asChat
import (
"encoding/json"
"fonchain-fiee/pkg/common/ws"
)
func HandleMessage(sourceData []byte, cli *ws.Client) {
var msg map[string]any
err := json.Unmarshal(sourceData, &msg)
if err != nil {
cli.Send <- ws.WsErrorInvalidDataFormat(cli.ClientId)
return
}
switch msg["type"] {
default:
cli.Send <- ws.WsErrorUnknownMessageType(cli.ClientId)
case ws.TestType:
var newMsg = ws.WsInfo{
Type: ws.TestType,
Content: msg["content"],
}
byteMsg, _ := json.Marshal(newMsg)
cli.Send <- byteMsg
//case ws.ChatType:
// var chatInfo ChatInfo
// _ = json.Unmarshal(sourceData, &chatInfo)
// //解析Content
// if clients, ok := cli.Room.clients[chatInfo.Content.TargetUserId]; ok {
// for _, targetObj := range clients {
// if targetObj != nil {
// targetObj.Send <- WsChatMessage(msg.From, chatInfo.Content.TargetClientId, chatInfo.Content.Msg)
// }
// }
// } else {
// //对方不在线
// cli.Send <- WsErrorMessage(ChatType, msg.From, e.ErrTargetOutLine, nil)
// }
}
}

View File

@ -7,9 +7,8 @@ import (
"fonchain-fiee/pkg/logic"
"fonchain-fiee/pkg/serializer"
"fonchain-fiee/pkg/service/approval/model"
"net/http"
"github.com/gin-gonic/gin"
"net/http"
)
const (
@ -190,21 +189,3 @@ func translateErrorMessage(c *gin.Context, message string) string {
return common.EnMessages[message]
}
}
func ErrWithCode(c *gin.Context, code e.ErrorCodeType, newMsg ...string) {
msg := e.GetCodeMsg(code)
if newMsg != nil {
msg = newMsg[0]
}
status := 1
if code == e.NotLogin {
status = e.NotLogin
}
c.JSON(e.Success, serializer.Response{
Code: code,
Status: status,
Msg: msg,
Data: nil,
})
}

View File

@ -13,30 +13,13 @@ import (
"fonchain-fiee/pkg/service/bundle/logic"
bundleModel "fonchain-fiee/pkg/service/bundle/model"
"fonchain-fiee/pkg/service/upload"
"github.com/360EntSecGroup-Skylar/excelize"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"strconv"
"strings"
"time"
)
func DeleteBundleOrder(c *gin.Context) {
var req bundle.DeleteValueAddServiceRequest
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
userInfo := login.GetUserInfoFromC(c)
req.UserID = userInfo.ID
res, err := service.BundleProvider.DeleteValueAddService(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
return
}
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
func CreateBundleOrderAddSignature(c *gin.Context) {
var req bundle.OrderAddRecord
@ -45,13 +28,10 @@ func CreateBundleOrderAddSignature(c *gin.Context) {
service.Error(c, err)
return
}
if req.Language == "" {
req.Language = c.GetHeader("Accept-Language")
if req.Language == "" {
service.Error(c, errors.New(common.MissLanguageTypes))
return
}
}
if req.BundleUuid == "" {
service.Error(c, errors.New(common.MissOrderNo))
return
@ -86,13 +66,13 @@ func CreateBundleOrderAddSignature(c *gin.Context) {
return
}
// 获取套餐详情(待替换逻辑)
//bundleDetail, err := service.BundleProvider.BundleDetail(context.Background(), &bundle.BundleDetailRequest{
// Uuid: req.BundleUuid,
//})
//if err != nil {
// service.Error(c, err)
// return
//}
bundleDetail, err := service.BundleProvider.BundleDetail(context.Background(), &bundle.BundleDetailRequest{
Uuid: req.BundleUuid,
})
if err != nil {
service.Error(c, err)
return
}
// todo 需要判断购买的增值服务是否为可用时长 如果为可以用时长 合同截止日期为购买时长时间 否则合同截止日期为主套餐截止日期
// 处理多个增值服务
type ValueAddServiceInfo struct {
@ -101,7 +81,7 @@ func CreateBundleOrderAddSignature(c *gin.Context) {
ID int32
}
// 计算总金额和确定截止日期
//var expirationDate string
var expirationDate string
var addPriceList []*bundle.AddPriceOptionsInfo
var totalAmount float32
for _, svc := range req.AddPriceOptionsList {
@ -131,8 +111,8 @@ func CreateBundleOrderAddSignature(c *gin.Context) {
Num: svc.Num,
Unit: valueAddInfo.Unit,
})
// 如果是可用时长服务,计算新的截止日期 todo 不需要计算到期时间 在完成支付时添加
/*if valueAddInfo.ServiceType == 5 {
// 如果是可用时长服务,计算新的截止日期
if valueAddInfo.ServiceType == 5 {
endDate := orderRecordResp.OrderRecord.ExpirationTime
if endDate == "9999-12-31" {
service.Error(c, errors.New(common.ErrorPermanentPackage))
@ -146,27 +126,27 @@ func CreateBundleOrderAddSignature(c *gin.Context) {
newDeadline := calculateExpirationDate(t, svc.Num, valueAddInfo.Unit)
expirationDate = newDeadline
//}
}*/
}
}
// 如果没有可用时长服务,使用主套餐截止日期
//if expirationDate == "" {
// expirationDate = orderRecordResp.OrderRecord.ExpirationTime
//}
if expirationDate == "" {
expirationDate = orderRecordResp.OrderRecord.ExpirationTime
}
req.CustomerNum = userInfo.SubNum
req.CustomerName = userInfo.Name
req.CustomerID = strconv.FormatUint(userInfo.ID, 10)
req.Source = 2
//req.SignedTime = common.GetBeijingTime()
//req.ExpirationDate = expirationDate
req.SignedTime = common.GetBeijingTime()
req.ExpirationDate = expirationDate
req.AddPriceOptionsList = addPriceList
req.OrderUUID = orderRecordResp.OrderRecord.Uuid
// 当前 未将 签名 写入合同中 todo 购买增值服务取消签约合同
//signContract, signContractErr := logic.SignContractV2(req.CustomerNum, bundleDetail.Bundle.Contract, totalAmount, expirationDate)
//if signContractErr != nil {
// service.Error(c, signContractErr)
// return
//}
//req.SignContract = signContract
// 当前 未将 签名 写入合同中
signContract, signContractErr := logic.SignContractV2(req.CustomerNum, bundleDetail.Bundle.Contract, totalAmount, expirationDate)
if signContractErr != nil {
service.Error(c, signContractErr)
return
}
req.SignContract = signContract
// 创建增值服务订单记录
res, err := service.BundleProvider.CreateOrderAddRecord(context.Background(), &req)
if err != nil {
@ -202,13 +182,10 @@ func CreateBundleOrderSignature(c *gin.Context) {
service.Error(c, errors.New(common.MissBundleUUID))
return
}
if req.Language == "" {
req.Language = c.GetHeader("Accept-Language")
if req.Language == "" {
service.Error(c, errors.New(common.MissLanguageTypes))
return
}
}
// 不去校验 签名
/*if req.Signature == "" {
service.Error(c, errors.New(common.MissOrderSignature))
@ -242,11 +219,7 @@ func CreateBundleOrderSignature(c *gin.Context) {
//有套餐并且套餐未过期
if orderRecordsList.OrderRecords != nil {
for _, orderInfo := range orderRecordsList.OrderRecords {
if orderInfo.CustomerID == strconv.FormatUint(userInfo.ID, 10) && orderInfo.Status == 1 {
service.Error(c, errors.New(common.ThereAreOutstandingOrders))
return
}
if orderInfo.CustomerID == strconv.FormatUint(userInfo.ID, 10) && orderInfo.ExpirationTime > time.Now().Format("2006-01-02 15:04:05") {
if orderInfo.CustomerID == strconv.FormatUint(userInfo.ID, 10) && orderInfo.ExpirationTime > time.Now().Format("2006-01-02") {
service.Error(c, errors.New(common.HadOrder))
return
}
@ -272,9 +245,8 @@ func CreateBundleOrderSignature(c *gin.Context) {
// 获取 套餐信息
bundleDetailReq := &bundle.BundleDetailRequest{
Uuid: req.BundleUuid,
Language: req.Language,
}
bundleDetail, detailErr := service.BundleProvider.BundleLangDetailV2(context.Background(), bundleDetailReq)
bundleDetail, detailErr := service.BundleProvider.BundleDetail(context.Background(), bundleDetailReq)
if detailErr != nil {
service.Error(c, detailErr)
return
@ -320,7 +292,7 @@ func CreateBundleOrderSignature(c *gin.Context) {
}
}
// 当前 未将 签名 写入合同中 todo 金额和有效时间待修改
signContract, signContractErr := logic.SignContractV2(req.CustomerNum, bundleDetail.Contract, addTotalPrice, expirationDay)
signContract, signContractErr := logic.SignContractV2(req.CustomerNum, bundleDetail.Bundle.Contract, addTotalPrice, expirationDay)
if signContractErr != nil {
service.Error(c, signContractErr)
return
@ -328,17 +300,17 @@ func CreateBundleOrderSignature(c *gin.Context) {
req.CustomerNum = userInfo.SubNum
req.CustomerName = userInfo.Name
req.CustomerID = strconv.FormatUint(userInfo.ID, 10)
req.BundleName = bundleDetail.Name
req.Amount = bundleDetail.Price
req.AmountType = bundleDetail.PriceType
//req.BundleCommonUid = bundleDetail.BundleCommonUid
req.TotalAmount = bundleDetail.Price + addTotalPrice
req.BundleName = bundleDetail.Bundle.Name
req.Amount = bundleDetail.Bundle.Price
req.AmountType = bundleDetail.Bundle.PriceType
req.BundleCommonUid = bundleDetail.Bundle.BundleCommonUid
req.TotalAmount = bundleDetail.Bundle.Price + addTotalPrice
req.ContractNo = common.GenerateContractNo(lastContractNo)
req.SignContract = signContract
req.SignedTime = common.GetBeijingTime()
req.Status = bundleModel.OrderSigned
req.AddRecords = addRecords
//req.ExpirationTime = expirationDay //过期日期取消 在完成支付是更新
req.ExpirationTime = expirationDay
req.PayType = 1
res, err := service.BundleProvider.CreateOrderRecord(context.Background(), &req)
@ -508,184 +480,6 @@ func OrderRecordsListV2(c *gin.Context) {
service.Success(c, orderList)
}
func OrderRecordsListDownload(c *gin.Context) {
var req bundle.OrderRecordsRequestV2
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
res := &bundle.OrderRecordsResponseV2{}
// Step 1: 如果有姓名/电话筛选,先查用户列表
if req.CustomerName != "" {
userListResp, err := service.AccountFieeProvider.UserList(context.Background(), &accountFiee.UserListRequest{
BlurNameTel: req.CustomerName,
Domain: "app",
})
if err != nil {
service.Error(c, err)
return
}
if len(userListResp.UserList) == 0 {
// 没查到用户,直接返回空结果
res.Page = req.Page
res.PageSize = req.PageSize
res.Total = 0
service.Success(c, res)
return
}
// 提取用户ID列表
for _, u := range userListResp.UserList {
req.UserIds = append(req.UserIds, int64(u.Id))
}
}
// Step 2: 查询订单列表
orderList, err := service.BundleProvider.OrderRecordsListV2(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
// Step 3: 如果订单不为空,查一次用户信息填充(只查一次)
if len(orderList.BundleInfo) > 0 {
// 收集订单里的所有用户ID
userIdSet := make(map[int64]struct{})
for _, i := range orderList.BundleInfo {
userIdSet[i.CustomerId] = struct{}{}
}
var userIds []int64
for id := range userIdSet {
userIds = append(userIds, id)
}
userListResp, err := service.AccountFieeProvider.UserList(context.Background(), &accountFiee.UserListRequest{
Ids: userIds,
Domain: "app",
})
if err != nil {
service.Error(c, err)
return
}
// 建立用户ID -> 用户信息映射
userMap := make(map[int64]*accountFiee.UserListInfo, len(userListResp.UserList))
for _, u := range userListResp.UserList {
userMap[int64(u.Id)] = u
}
// 填充订单中的用户信息
for _, item := range orderList.BundleInfo {
if u, ok := userMap[item.CustomerId]; ok {
item.CustomerName = u.Name
item.TelNum = u.TelNum
}
}
}
excelFile, err := exportExcel(orderList.BundleInfo)
if err != nil {
service.Error(c, err)
return
}
// 返回 Excel 文件流给前端
c.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
c.Header("Content-Disposition", "attachment; filename=order_list.xlsx")
c.Header("File-Name", "order_list.xlsx")
c.Header("Access-Control-Expose-Headers", "File-Name")
_ = excelFile.Write(c.Writer)
}
func exportExcel(orderList []*bundle.OrderBundleRecordInfo) (*excelize.File, error) {
f := excelize.NewFile()
sheetName := "Sheet1"
f.SetSheetName("Sheet1", sheetName)
headers := []string{
"套餐订单号", "套餐", "套餐付款状态", "艺人手机号", "艺人", "套餐订单创建时间", "套餐金额",
"增值服务订单号", "增值税服务金额", "结算金额", "币种", "手续费", "汇率", "增值订单创建时间", "增值付款状态",
}
for i, h := range headers {
cell := fmt.Sprintf("%s%d", string(rune('A'+i)), 1)
f.SetCellValue(sheetName, cell, h)
}
rowIndex := 2
for _, bundleInfo := range orderList {
addCount := len(bundleInfo.AddBundleInfo)
mergeRows := 1
if addCount > 1 {
mergeRows = addCount
}
// 写入主订单信息并合并单元格
for i := 0; i < 7; i++ {
col := string(rune('A' + i))
startCell := fmt.Sprintf("%s%d", col, rowIndex)
endCell := fmt.Sprintf("%s%d", col, rowIndex+mergeRows-1)
if mergeRows > 1 {
f.MergeCell(sheetName, startCell, endCell)
}
}
f.SetCellValue(sheetName, fmt.Sprintf("A%d", rowIndex), bundleInfo.OrderNo)
f.SetCellValue(sheetName, fmt.Sprintf("B%d", rowIndex), bundleInfo.BundleName)
f.SetCellValue(sheetName, fmt.Sprintf("C%d", rowIndex), GetPayStatusText(bundleInfo.PayStatus))
f.SetCellValue(sheetName, fmt.Sprintf("D%d", rowIndex), bundleInfo.TelNum)
f.SetCellValue(sheetName, fmt.Sprintf("E%d", rowIndex), bundleInfo.CustomerName)
f.SetCellValue(sheetName, fmt.Sprintf("F%d", rowIndex), bundleInfo.BundleCreateAt)
f.SetCellValue(sheetName, fmt.Sprintf("G%d", rowIndex), bundleInfo.Amount)
if addCount > 0 {
for i, add := range bundleInfo.AddBundleInfo {
r := rowIndex + i
f.SetCellValue(sheetName, fmt.Sprintf("H%d", r), add.OrderAddNo)
f.SetCellValue(sheetName, fmt.Sprintf("I%d", r), add.Amount)
f.SetCellValue(sheetName, fmt.Sprintf("J%d", r), add.SettlementAmount)
f.SetCellValue(sheetName, fmt.Sprintf("K%d", r), GetCurrencyTypeText(add.CurrencyType))
f.SetCellValue(sheetName, fmt.Sprintf("L%d", r), add.HandlingFee)
f.SetCellValue(sheetName, fmt.Sprintf("M%d", r), add.ExchangeRate)
f.SetCellValue(sheetName, fmt.Sprintf("N%d", r), add.OrderAddCreateAt)
f.SetCellValue(sheetName, fmt.Sprintf("O%d", r), GetPayStatusText(add.AddPayStatus))
}
} else {
for i := 8; i <= 15; i++ {
col := string(rune('A' + i))
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", col, rowIndex), "")
}
}
rowIndex += mergeRows
}
return f, nil
}
func GetPayStatusText(status int32) string {
switch status {
case 1:
return "未支付"
case 2:
return "已支付"
default:
return strconv.Itoa(int(status))
}
}
// 辅助函数:获取货币类型文本
func GetCurrencyTypeText(currencyType int32) string {
switch currencyType {
case 1:
return "人民币"
case 2:
return "美元"
default:
return strconv.Itoa(int(currencyType))
}
}
func OrderRecordsList(c *gin.Context) {
var req bundle.OrderRecordsRequest

View File

@ -77,98 +77,3 @@ func BundleList(c *gin.Context) {
service.Success(c, res)
}
func SaveBundleV2(c *gin.Context) {
var req bundle.BundleProfile
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
res, err := service.BundleProvider.SaveBundle(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func BundleListV2(c *gin.Context) {
var req bundle.BundleListRequest
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
res, err := service.BundleProvider.BundleListV2(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func BundleDetailV2(c *gin.Context) {
var req bundle.BundleDetailRequest
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
language := c.GetHeader("Accept-Language")
req.Language = language
res, err := service.BundleProvider.BundleDetailV2(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func HandShelf(c *gin.Context) {
var req bundle.HandShelfRequest
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
res, err := service.BundleProvider.HandShelf(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func OnlyAddValueListByOrderNo(c *gin.Context) {
var req bundle.OnlyAddValueListByOrderNoRequest
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
res, err := service.BundleProvider.OnlyAddValueListByOrderNo(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func BundleListH5V2(c *gin.Context) {
var req bundle.BundleListRequest
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
res, err := service.BundleProvider.BundleListH5V2(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}

View File

@ -17,20 +17,13 @@ const (
InvalidOrderAmount = "订单金额错误"
HadPay = "订单已支付"
ThereAreOutstandingOrders = "您还有未支付的订单,无法再次购买"
HadOrder = "您已购买过套餐,无法再次购买"
InvalidValueAddBundleNum = "套餐数量无效"
ThePackageHasExpired = "当前套餐已过期"
ErrorPermanentPackage = "永久套餐无需购买"
)
const (
OrderTypePackage = 1 // 套餐
OrderTypeAddon = 2 // 增值服务
TimeUnitDay = 1
TimeUnitMonth = 2
TimeUnitYear = 3
)
const (
ErrorExportOrderInfo = "导出订单信息失败"
)

View File

@ -47,10 +47,6 @@ func SignContractV2(customerNum, contract string, price float32, expirationDate
}
func InsertSignatureV2(templatePath, outputPath string, price float32, expirationDate string) error {
fmt.Println("================================templatePath:", templatePath)
fmt.Println("================================outputPath:", outputPath)
fmt.Println("================================price:", price)
fmt.Println("================================expirationDate:", expirationDate)
pdf := gopdf.GoPdf{}
pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4})

View File

@ -2,7 +2,6 @@ package bundle
import (
"context"
"dubbo.apache.org/dubbo-go/v3/common/logger"
"encoding/json"
"errors"
"fmt"
@ -142,85 +141,16 @@ func CreateAntomPay(c *gin.Context) {
// 获取 用户信息
userInfo := login.GetUserInfoFromC(c)
// outTradeNo就是orderNo根据这个去查询子表的source,如果是2就时单独的子套餐如果是1就是主套餐
orderLimit, err := service.BundleProvider.OrderListByOrderNo(context.Background(), &bundle.OrderInfoByOrderNoRequest{
OrderNo: req.OutTradeNo,
})
if err != nil {
fmt.Println("=============== antom创建支付查询订单source报错", err)
logger.Errorf("=============== antom创建支付查询订单source报错", err)
service.Error(c, err)
return
}
currencyType := 0
if req.ProductPriceCurrency == "cny" || req.ProductPriceCurrency == "CNY" {
currencyType = 1
}
if req.ProductPriceCurrency == "usd" || req.ProductPriceCurrency == "USD" {
currencyType = 2
}
bundleName := "" // 套餐名称
if orderLimit != nil && orderLimit.Type == 1 { // 这儿的type实际就是source
// 检查 订单信息 type是1说明既有主套餐又有增值服务
// 检查 订单信息
detail, detailErr := service.BundleProvider.OrderRecordsDetail(context.Background(), &bundle.OrderRecordsDetailRequest{
OrderNo: req.OutTradeNo,
})
if detailErr != nil {
fmt.Println("=============== antom创建支付查询主订单信息报错", detailErr)
logger.Errorf("=============== antom创建支付查询主订单信息报错", detailErr)
service.Error(c, detailErr)
return
}
fmt.Println("detail.OrderRecord.Status :", detail.OrderRecord.Status)
fmt.Println("detail.OrderRecord.CheckoutSessionId :", detail.OrderRecord.CheckoutSessionId)
fmt.Println("detail.OrderRecord.PayTime :", detail.OrderRecord.PayTime)
bundleName = detail.OrderRecord.BundleName
// 主套餐
// 如果 当前订单 是 已签未支付 且 存在 checkoutSessionId 需要 查询 支付结果
if detail.OrderRecord.Status == bundleModel.OrderSigned && detail.OrderRecord.CheckoutSessionId != "" && detail.OrderRecord.PayTime == "" {
// 查询支付结果
stripeInfosRes, stripeInfosErr := service.PaymentProvider.QueryAntomPayByCheckoutSessionId(context.Background(), &payment.AntomPayQueryRequest{
CheckoutSessionIds: []string{detail.OrderRecord.CheckoutSessionId},
})
if stripeInfosErr != nil {
service.Error(c, errors.New(common.ErrorQueryStripeInfo))
return
}
if stripeInfosRes != nil && len(stripeInfosRes.Infos) > 0 {
for _, info := range stripeInfosRes.Infos {
if info.OutTradeNo == detail.OrderRecord.OrderNo && info.Status == "paid" {
// 更新主套餐和子套餐 TODO
// 更新子套餐TODO
_, updateStatusErr := service.BundleProvider.UpdateOrderRecordByOrderNo(context.Background(), &bundle.OrderRecord{
OrderNo: req.OutTradeNo,
PayTime: common.GetBeijingTime(),
Status: bundleModel.OrderPaid,
})
fmt.Println("detail.OrderRecord.Uuid :", detail.OrderRecord.Uuid)
if updateStatusErr != nil {
fmt.Println("=============== antom创建支付更新主套餐和子套餐支付状态报错", updateStatusErr)
logger.Errorf("=============== antom创建支付更新主套餐和子套餐支付状态报错", updateStatusErr)
service.Error(c, updateStatusErr)
return
}
service.Success(c, &service.Response{
Msg: common.HadPay,
Code: 0,
})
return
}
}
}
}
fmt.Println("detail.OrderRecord.CustomerID :", detail.OrderRecord.CustomerID)
// 判断 是否是 本人操作
@ -234,33 +164,23 @@ func CreateAntomPay(c *gin.Context) {
fmt.Println("detail.OrderRecord.TotalAmount*100 :", detail.OrderRecord.TotalAmount*100)
//金额校验
orderAmountInCents := int64(math.Round(float64(detail.OrderRecord.TotalAmount) * 100))
reqAmountInCents := req.ProductAllPrice
orderAmountInCents := int64(math.Round(float64(detail.OrderRecord.TotalAmount * 100)))
reqAmountInCents := int64(math.Round(float64(req.ProductAllPrice)))
if orderAmountInCents != reqAmountInCents {
fmt.Println("111111111111111111111111111111111111")
service.Error(c, errors.New(common.InvalidOrderAmount))
return
}
}
if orderLimit != nil && orderLimit.Type == 2 {
fmt.Println("detail.OrderRecord.Status :", detail.OrderRecord.Status)
fmt.Println("detail.OrderRecord.CheckoutSessionId :", detail.OrderRecord.CheckoutSessionId)
fmt.Println("detail.OrderRecord.PayTime :", detail.OrderRecord.PayTime)
res, listErr := service.BundleProvider.OnlyAddValueListByOrderNo(context.Background(), &bundle.OnlyAddValueListByOrderNoRequest{
OrderNo: req.OutTradeNo,
})
if listErr != nil {
fmt.Println("=============== antom创建支付查询单独增值服务列表报错", listErr)
logger.Errorf("=============== antom创建支付查询单独增值服务列表报错", listErr)
service.Error(c, listErr)
return
}
if res != nil && len(res.AddBundleInfos) > 0 {
firstAddBundle := res.AddBundleInfos[0]
// 如果 当前订单 是 已签未支付 且 存在 checkoutSessionId 需要 查询 支付结果
if firstAddBundle.PaymentStatus == bundleModel.OrderSigned && firstAddBundle.CheckOutSessionId != "" {
if detail.OrderRecord.Status == bundleModel.OrderSigned && detail.OrderRecord.CheckoutSessionId != "" && detail.OrderRecord.PayTime == "" {
// 查询支付结果
stripeInfosRes, stripeInfosErr := service.PaymentProvider.QueryAntomPayByCheckoutSessionId(context.Background(), &payment.AntomPayQueryRequest{
CheckoutSessionIds: []string{firstAddBundle.CheckOutSessionId},
CheckoutSessionIds: []string{detail.OrderRecord.CheckoutSessionId},
})
if stripeInfosErr != nil {
@ -270,18 +190,15 @@ func CreateAntomPay(c *gin.Context) {
if stripeInfosRes != nil && len(stripeInfosRes.Infos) > 0 {
for _, info := range stripeInfosRes.Infos {
if info.OutTradeNo == firstAddBundle.OrderNo && info.Status == "paid" {
// 更新子套餐TODO
_, updateStatusErr := service.BundleProvider.UpdateOrderRecordByOrderNo(context.Background(), &bundle.OrderRecord{
OrderNo: req.OutTradeNo,
PayTime: common.GetBeijingTime(),
if info.OutTradeNo == detail.OrderRecord.OrderNo && info.Status == "paid" {
_, updateOrderRecordErr := service.BundleProvider.UpdateOrderRecord(context.Background(), &bundle.OrderRecord{
Uuid: detail.OrderRecord.Uuid,
Status: bundleModel.OrderPaid,
PayTime: common.GetBeijingTime(),
})
fmt.Println("req.OutTradeNo :", req.OutTradeNo)
if updateStatusErr != nil {
fmt.Println("=============== antom创建支付更新子套餐支付状态报错", updateStatusErr)
logger.Errorf("=============== antom创建支付更新子套餐支付状态报错", updateStatusErr)
service.Error(c, updateStatusErr)
fmt.Println("detail.OrderRecord.Uuid :", detail.OrderRecord.Uuid)
if updateOrderRecordErr != nil {
service.Error(c, detailErr)
return
}
service.Success(c, &service.Response{
@ -294,142 +211,6 @@ func CreateAntomPay(c *gin.Context) {
}
}
fmt.Println("firstAddBundle.CustomerID :", firstAddBundle.CustomerID)
// 判断 是否是 本人操作
if strconv.FormatUint(userInfo.ID, 10) != firstAddBundle.CustomerID {
service.Error(c, errors.New(common.NotMatchOrderInfo))
return
}
orderAmountInCents := int64(0.0)
for _, info := range res.AddBundleInfos {
temp := int64(math.Round(float64(info.Amount) * 100))
orderAmountInCents += temp
}
fmt.Println("orderAmountInCents :", orderAmountInCents)
fmt.Println("req.ProductAllPrice :", req.ProductAllPrice)
//金额校验
reqAmountInCents := req.ProductAllPrice
if orderAmountInCents != reqAmountInCents {
fmt.Println("111111111111111111111111111111111111")
service.Error(c, errors.New(common.InvalidOrderAmount))
return
}
}
}
if req.ProductAllPrice == 0 {
////创建对账单 todo 待修改
_, err = service.BundleProvider.CreateReconciliation(context.Background(), &bundle.ReconciliationInfo{
BundleOrderOn: req.OutTradeNo,
BundleAddOrderOn: req.OutTradeNo,
UserName: userInfo.Name,
UserTel: userInfo.TelNum,
BundleName: bundleName,
PayAmount: float32(req.ProductAllPrice),
CurrencyType: int32(currencyType),
PayStatus: 2,
PayTime: common.GetBeijingTime(),
UserID: userInfo.ID,
SerialNumber: "zero-price-serial-number",
})
if err != nil {
fmt.Println("=============== antom创建支付创建对账单报错", err)
logger.Errorf("=============== antom创建支付创建对账单报错", err)
service.Error(c, err)
return
}
_, updateStatusErr := service.BundleProvider.UpdateOrderRecordByOrderNo(context.Background(), &bundle.OrderRecord{
OrderNo: req.OutTradeNo,
PayTime: common.GetBeijingTime(),
Status: bundleModel.OrderPaid,
})
if updateStatusErr != nil {
fmt.Println("=============== antom创建支付更新订单报错", updateStatusErr)
logger.Errorf("=============== antom创建支付更新订单报错", updateStatusErr)
service.Error(c, updateStatusErr)
return
}
switch orderLimit.Type {
case common.OrderTypePackage:
//如果是购买套餐 1:创建新的余量信息CreateBundleBalance 2 添加扩展记录BundleExtend
_, err = service.BundleProvider.CreateBundleBalance(context.Background(), &bundle.CreateBundleBalanceReq{
UserId: int32(orderLimit.UserId),
OrderUUID: orderLimit.OrderUUID,
//AccountNumber: orderLimit.AccountNumber,
//VideoNumber: orderLimit.VideoNumber,
//ImageNumber: orderLimit.ImageNumber,
//DataAnalysisNumber: orderLimit.DataNumber,
ExpansionPacksNumber: 1,
})
if err != nil {
fmt.Println("=============== antom创建支付OrderTypePackage报错", err)
logger.Errorf("=============== antom创建支付OrderTypePackage报错", err)
service.Error(c, err)
return
}
case common.OrderTypeAddon:
//如果是购买增值服务 1:修改余量信息AddBundleBalance 2 添加扩展记录BundleExtend
//_, err = service.BundleProvider.AddBundleBalance(context.Background(), &bundle.AddBundleBalanceReq{
// UserId: int32(orderLimit.UserId),
// OrderUUID: orderLimit.OrderUUID,
// AccountNumber: orderLimit.AccountNumber,
// VideoNumber: orderLimit.VideoNumber,
// ImageNumber: orderLimit.ImageNumber,
// DataAnalysisNumber: orderLimit.DataNumber,
// ExpansionPacksNumber: 1,
//})
//if err != nil {
// fmt.Println("=============== antom创建支付OrderTypePackage报错", err)
// logger.Errorf("=============== antom创建支付OrderTypePackage报错", err)
// service.Error(c, err)
// return
//}
default:
fmt.Println("=============== antom创建支付无效的订单类型", err)
logger.Errorf("=============== antom创建支付无效的订单类型", err)
service.Error(c, errors.New("无效的订单类型"))
return
}
var timeUnit uint32
switch orderLimit.Unit {
case "天":
timeUnit = common.TimeUnitDay
case "月":
timeUnit = common.TimeUnitMonth
case "年":
timeUnit = common.TimeUnitYear
default:
timeUnit = 0
}
_, err = service.BundleProvider.BundleExtend(context.Background(), &bundle.BundleExtendRequest{
UserId: int64(orderLimit.UserId),
AccountAdditional: uint32(orderLimit.AccountNumber),
VideoAdditional: uint32(orderLimit.VideoNumber),
ImagesAdditional: uint32(orderLimit.ImageNumber),
DataAdditional: uint32(orderLimit.DataNumber),
AvailableDurationAdditional: uint32(orderLimit.Duration),
TimeUnit: timeUnit,
AssociatedorderNumber: req.OutTradeNo, //增值服务订单号
Type: 2, //自行购买
OperatorName: orderLimit.UserName,
OperatorId: orderLimit.UserId,
})
if err != nil {
service.Error(c, err)
return
}
service.Success(c)
return
}
var antomReq payment.CreatePayRequest
antomReq.Payee = "Antom"
antomReq.Platform = "antom"
@ -452,9 +233,9 @@ func CreateAntomPay(c *gin.Context) {
fmt.Println("result.CheckoutSessionId :", result.CheckoutSessionId)
fmt.Println("result.Url :", result.Url)
//更新订单url和checkSessionId
_, updateStatusErr := service.BundleProvider.UpdateOrderRecordByOrderNo(context.Background(), &bundle.OrderRecord{
OrderNo: req.OutTradeNo,
//更新订单状态
_, updateOrderRecordErr := service.BundleProvider.UpdateOrderRecord(context.Background(), &bundle.OrderRecord{
Uuid: detail.OrderRecord.Uuid,
CheckoutSessionId: result.CheckoutSessionId,
CheckoutSessionUrl: result.Url,
})
@ -462,32 +243,11 @@ func CreateAntomPay(c *gin.Context) {
resp := &order.CreateStripeCheckoutSessionResponse{}
resp.CheckoutSessionUrl = result.Url
resp.CheckoutSessionId = result.CheckoutSessionId
fmt.Println("req.OutTradeNo :", req.OutTradeNo)
if updateStatusErr != nil {
fmt.Println("=============== antom创建支付更新订单的请求id报错", updateStatusErr)
logger.Errorf("=============== antom创建支付更新订单的请求id报错", updateStatusErr)
service.Error(c, updateStatusErr)
return
}
fmt.Println("resp:", resp)
////创建对账单 todo 待修改
_, err = service.BundleProvider.CreateReconciliation(context.Background(), &bundle.ReconciliationInfo{
BundleOrderOn: req.OutTradeNo,
BundleAddOrderOn: req.OutTradeNo,
UserName: userInfo.Name,
UserTel: userInfo.TelNum,
BundleName: bundleName,
PayAmount: float32(req.ProductAllPrice) / 100, // 以后别用float存钱无语
CurrencyType: int32(currencyType),
PayStatus: 1,
UserID: userInfo.ID,
SerialNumber: result.CheckoutSessionId,
})
if err != nil {
fmt.Println("=============== antom创建支付创建对账单报错", err)
logger.Errorf("=============== antom创建支付创建对账单报错", err)
service.Error(c, err)
if updateOrderRecordErr != nil {
fmt.Println("有更新报错:", updateOrderRecordErr)
service.Error(c, updateOrderRecordErr)
return
}
@ -603,91 +363,7 @@ func AntomWebhook(c *gin.Context) {
service.Error(c, err)
return
}
// 更新对账单
_, err = service.BundleProvider.UpdateReconciliationStatusBySerialNumber(context.Background(), &bundle.UpdateStatusAndPayTimeBySerialNumber{
PayTime: paymentTime,
PaymentStatus: 2,
SerialNumber: requestId,
})
if err != nil {
fmt.Println("=============== antom回调更新对账单报错", err)
logger.Errorf("=============== antom回调更新对账单报错", err)
service.Error(c, err)
return
}
//添加余额
orderLimit, err := service.BundleProvider.OrderListByOrderNo(context.Background(), &bundle.OrderInfoByOrderNoRequest{
OrderNo: resp.OutTradeNo,
})
if err != nil {
service.Error(c, err)
return
}
//购买套餐
switch orderLimit.Type {
case common.OrderTypePackage:
//如果是购买套餐 1:创建新的余量信息CreateBundleBalance 2 添加扩展记录BundleExtend
_, err = service.BundleProvider.CreateBundleBalance(context.Background(), &bundle.CreateBundleBalanceReq{
UserId: int32(orderLimit.UserId),
OrderUUID: orderLimit.OrderUUID,
//AccountNumber: orderLimit.AccountNumber,
//VideoNumber: orderLimit.VideoNumber,
//ImageNumber: orderLimit.ImageNumber,
//DataAnalysisNumber: orderLimit.DataNumber,
ExpansionPacksNumber: 1,
})
if err != nil {
service.Error(c, err)
return
}
case common.OrderTypeAddon:
//如果是购买增值服务 1:修改余量信息AddBundleBalance 2 添加扩展记录BundleExtend
//_, err = service.BundleProvider.AddBundleBalance(context.Background(), &bundle.AddBundleBalanceReq{
// UserId: int32(orderLimit.UserId),
// OrderUUID: orderLimit.OrderUUID,
// AccountNumber: orderLimit.AccountNumber,
// VideoNumber: orderLimit.VideoNumber,
// ImageNumber: orderLimit.ImageNumber,
// DataAnalysisNumber: orderLimit.DataNumber,
// ExpansionPacksNumber: 1,
//})
//if err != nil {
// service.Error(c, err)
// return
//}
default:
service.Error(c, errors.New("无效的订单类型"))
return
}
var timeUnit uint32
switch orderLimit.Unit {
case "天":
timeUnit = common.TimeUnitDay
case "月":
timeUnit = common.TimeUnitMonth
case "年":
timeUnit = common.TimeUnitYear
default:
timeUnit = 0
}
_, err = service.BundleProvider.BundleExtend(context.Background(), &bundle.BundleExtendRequest{
UserId: int64(orderLimit.UserId),
AccountAdditional: uint32(orderLimit.AccountNumber),
VideoAdditional: uint32(orderLimit.VideoNumber),
ImagesAdditional: uint32(orderLimit.ImageNumber),
DataAdditional: uint32(orderLimit.DataNumber),
AvailableDurationAdditional: uint32(orderLimit.Duration),
TimeUnit: timeUnit,
AssociatedorderNumber: resp.OutTradeNo, //增值服务订单号
Type: 2, //自行购买
OperatorName: orderLimit.UserName,
OperatorId: orderLimit.UserId,
})
if err != nil {
service.Error(c, err)
return
}
}
service.Success(c)
}
@ -730,21 +406,15 @@ func HomePageRoll(c *gin.Context) {
var roll []Roll
for _, i := range res.BundleInfo {
tel := ""
name := i.BundleName // Use bundle name as fallback
if userInfo, exists := userMap[i.CustomerId]; exists && userInfo != nil {
tel = userInfo.TelNum
if len(tel) >= 2 {
masked := ""
for j := 0; j < len(tel)-2; j++ {
masked += "*"
}
tel = masked + tel[len(tel)-2:]
}
maskedTel := userMap[i.CustomerId].TelNum
if len(userMap[i.CustomerId].TelNum) >= 11 { // 标准11位手机号
maskedTel = userMap[i.CustomerId].TelNum[:3] + "****" + userMap[i.CustomerId].TelNum[7:]
} else if len(userMap[i.CustomerId].TelNum) >= 7 { // 短号处理
maskedTel = userMap[i.CustomerId].TelNum[:3] + "****" + userMap[i.CustomerId].TelNum[7:]
}
roll = append(roll, Roll{
Tel: tel,
Name: name,
Tel: maskedTel,
Name: i.BundleName,
})
}
service.Success(c, roll)

View File

@ -1,75 +0,0 @@
package bundle
import (
"context"
"fonchain-fiee/api/bundle"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/utils"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
func GetReconciliationList(c *gin.Context) {
var req bundle.GetReconciliationListReq
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
detail, detailErr := service.BundleProvider.GetReconciliationList(context.Background(), &req)
if detailErr != nil {
service.Error(c, detailErr)
return
}
service.Success(c, detail)
return
}
func GetReconciliationListDownload(c *gin.Context) {
var req bundle.GetReconciliationListReq
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
detail, detailErr := service.BundleProvider.GetReconciliationList(context.Background(), &req)
if detailErr != nil {
service.Error(c, detailErr)
return
}
titleList := []string{
"关联套餐订单号", "关联增值服务订单号", "对账单创建时间", "艺人", "艺人手机号", "套餐", "支付金额", "币种", "支付渠道", "支付时间", "支付状态", "流水号",
}
var dataList []interface{}
for _, i := range detail.List {
payStatus := GetPayStatusText(i.PayStatus)
currencyType := GetCurrencyTypeText(i.CurrencyType)
payChannel := "未知"
if i.PayChannel == 1 {
payChannel = "支付宝"
}
data := []any{
i.BundleOrderOn,
i.BundleAddOrderOn,
i.CreationTime,
i.UserName,
i.UserTel,
i.BundleName,
i.PayAmount,
currencyType,
payChannel,
i.PayTime,
payStatus,
i.SerialNumber,
}
dataList = append(dataList, &data)
}
content, err := utils.ToExcelByType(titleList, dataList, "slice", "")
if err != nil {
service.Error(c, err)
return
}
utils.ResponseXls(c, content, "对账单")
return
}

View File

@ -67,65 +67,3 @@ func ValueAddBundleDetail(c *gin.Context) {
service.Success1(c, res.Msg, res)
}
func SaveValueAddService(c *gin.Context) {
var req bundle.ValueAddServiceLang
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error1(c, err)
return
}
res, err := service.BundleProvider.SaveValueAddService(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func ValueAddServiceList(c *gin.Context) {
var req bundle.ValueAddServiceListRequest
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error1(c, err)
return
}
res, err := service.BundleProvider.ValueAddServiceList(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func ValueAddServiceDetail(c *gin.Context) {
var req bundle.ValueAddServiceDetailRequest
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error1(c, err)
return
}
res, err := service.BundleProvider.ValueAddServiceDetail(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func ValueAddServiceLangDetail(c *gin.Context) {
var req bundle.ValueAddServiceDetailRequest
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error1(c, err)
return
}
language := c.GetHeader("Accept-Language")
req.Language = language
res, err := service.BundleProvider.ValueAddServiceLangByUuidAndLanguage(context.Background(), &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}

View File

@ -1,45 +0,0 @@
package cast
import (
"encoding/json"
"errors"
"fmt"
"fonchain-fiee/cmd/config"
"fonchain-fiee/pkg/e"
modelCast "fonchain-fiee/pkg/model/cast"
"fonchain-fiee/pkg/utils"
)
type CastService struct {
}
func (c *CastService) ApprovalDetail(approvalIds []int) (data map[int]modelCast.Item, err error) {
type ApprovalDetailRequest struct {
ID []int `json:"ID"`
}
req := ApprovalDetailRequest{
ID: approvalIds,
}
idsBytes, _ := json.Marshal(req)
var respBody string
url := fmt.Sprintf(config.AppConfig.System.FieeHost + "/approval/list/ex")
respBody, err = utils.Post(url, string(idsBytes))
if err != nil {
return
}
var respDetail modelCast.ApprovalDetailResponse
if err = json.Unmarshal([]byte(respBody), &respDetail); err != nil {
err = errors.New(e.GetMsg(e.JsonUnmarshal))
return
}
if respDetail.Status == 0 && len(respDetail.Data.Data) > 0 {
data = make(map[int]modelCast.Item, len(respDetail.Data.Data))
for _, v := range respDetail.Data.Data {
data[v.ID] = v
}
} else {
err = errors.New(e.GetMsg(e.ErrorHttp))
return
}
return
}

View File

@ -4,14 +4,11 @@ import (
"context"
"errors"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/api/bundle"
"fonchain-fiee/api/cast"
"fonchain-fiee/cmd/config"
"fonchain-fiee/pkg/e"
modelCast "fonchain-fiee/pkg/model/cast"
"fonchain-fiee/pkg/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"strconv"
)
@ -37,7 +34,6 @@ func MediaUserList(ctx *gin.Context) {
func UnbindManager(ctx *gin.Context) {
var req *cast.UnbindManagerReq
var resp *cast.UnbindManagerResp
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
@ -47,24 +43,11 @@ func UnbindManager(ctx *gin.Context) {
service.Error(ctx, err)
return
}
resp, err = service.CastProvider.UnbindManager(ctx, req)
_, err = service.CastProvider.UnbindManager(ctx, req)
if err != nil {
service.Error(ctx, err)
return
}
zap.L().Info("UnbindManager resp", zap.Any("resp", resp))
if resp.OldBindArtistUuid != "" {
userID, _ := strconv.ParseInt(resp.OldBindArtistUuid, 10, 64)
_, err = service.BundleProvider.AddBundleBalance(context.Background(), &bundle.AddBundleBalanceReq{
UserId: int32(userID),
AccountConsumptionNumber: -1,
})
if err != nil {
service.Error(ctx, err)
//FIXME 进行回滚
return
}
}
service.Success(ctx, nil)
return
}
@ -121,83 +104,15 @@ func UpdateMediaAccount(ctx *gin.Context) {
}
req.ArtistName = infoResp.Name
req.ArtistPhone = infoResp.TelNum
req.ArtistPhoneAreaCode = infoResp.TelAreaCode
if _, ok := cast.PlatformIDENUM_name[int32(req.PlatformID)]; !ok {
service.Error(ctx, errors.New(e.GetMsg(e.InvalidParams)))
return
}
userID, _ := strconv.ParseInt(req.ArtistUuid, 10, 64)
if req.MediaAccountUuid == "" {
if err = CheckUserBundleBalance(int32(userID), modelCast.BalanceTypeAccountValue); err != nil {
service.Error(ctx, err)
return
}
_, err = service.BundleProvider.AddBundleBalance(context.Background(), &bundle.AddBundleBalanceReq{
UserId: int32(userID),
AccountConsumptionNumber: 1,
})
if err != nil {
service.Error(ctx, err)
return
}
}
resp, err := service.CastProvider.UpdateMediaAccount(ctx, req)
if err != nil {
service.Error(ctx, err)
if req.MediaAccountUuid == "" {
_, err = service.BundleProvider.AddBundleBalance(context.Background(), &bundle.AddBundleBalanceReq{
UserId: int32(userID),
AccountConsumptionNumber: -1,
})
if err != nil {
service.Error(ctx, err)
return
}
}
return
}
service.Success(ctx, resp)
return
}
func OAuthUrl(ctx *gin.Context) {
var req *cast.OAuthYoutubeUrlReq
var resp *cast.OAuthYoutubeUrlResp
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
if err = req.Validate(); err != nil {
service.Error(ctx, err)
return
}
if resp, err = service.CastProvider.OAuthYoutubeUrl(ctx, req); err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
return
}
func OAuth2Callback(ctx *gin.Context) {
code := ctx.Query("code")
state := ctx.Query("state")
//scope := ctx.Query("scope")
resp, err := service.CastProvider.OAuthYoutubeToken(ctx, &cast.OAuthYoutubeTokenReq{
MediaAccountUuid: state,
Code: code,
//scope: scope,
})
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
return
}
func Test(ctx *gin.Context) {
service.Success(ctx, nil)
return
}

View File

@ -1 +0,0 @@
package cast

View File

@ -1,29 +0,0 @@
package cast
import (
"context"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"fmt"
"fonchain-fiee/cmd/config"
"fonchain-fiee/pkg/model/login"
"github.com/gin-gonic/gin"
)
func NewCtxWithUserInfo(ctx *gin.Context) (newCtx context.Context) {
var userInfo = login.Info{}
if config.AppConfig.System.AppMode != "dev" {
userInfo = login.GetUserInfoFromC(ctx)
} else {
userInfo = login.Info{
ID: 61,
Name: "小波",
TelNum: "18288888888",
}
}
var mm = make(map[string]interface{}, 3)
mm["userid"] = fmt.Sprintf("%d", userInfo.ID)
mm["name"] = userInfo.Name
mm["phone"] = userInfo.TelNum
newCtx = context.WithValue(context.Background(), constant.DubboCtxKey("attachment"), mm)
return
}

View File

@ -2,17 +2,11 @@ package cast
import (
"context"
"errors"
"fmt"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/api/bundle"
"fonchain-fiee/api/cast"
"fonchain-fiee/cmd/config"
"fonchain-fiee/pkg/e"
modelCast "fonchain-fiee/pkg/model/cast"
"fonchain-fiee/pkg/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"strconv"
)
@ -38,19 +32,10 @@ func UpdateWorkImage(ctx *gin.Context) {
infoResp = &accountFiee.UserInfoResponse{
Name: "小波",
TelNum: "18288888888",
TelAreaCode: "86",
}
}
req.ArtistName = infoResp.Name
req.ArtistPhone = infoResp.TelNum
req.ArtistPhoneAreaCode = infoResp.TelAreaCode
artistID, _ := strconv.ParseUint(req.ArtistUuid, 10, 64)
if err = CheckUserBundleBalance(int32(artistID), modelCast.BalanceTypeImageValue); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.UpdateWorkImage(newCtx, req)
resp, err := service.CastProvider.UpdateWorkImage(ctx, req)
if err != nil {
service.Error(ctx, err)
return
@ -81,19 +66,10 @@ func UpdateWorkVideo(ctx *gin.Context) {
infoResp = &accountFiee.UserInfoResponse{
Name: "小波",
TelNum: "18288888888",
TelAreaCode: "86",
}
}
artistID, _ := strconv.ParseUint(req.ArtistUuid, 10, 64)
if err = CheckUserBundleBalance(int32(artistID), modelCast.BalanceTypeVideoValue); err != nil {
service.Error(ctx, err)
return
}
req.ArtistName = infoResp.Name
req.ArtistPhone = infoResp.TelNum
req.ArtistPhoneAreaCode = infoResp.TelAreaCode
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.UpdateWorkVideo(newCtx, req)
resp, err := service.CastProvider.UpdateWorkVideo(ctx, req)
if err != nil {
service.Error(ctx, err)
return
@ -101,263 +77,3 @@ func UpdateWorkVideo(ctx *gin.Context) {
service.Success(ctx, resp)
return
}
func UpdateApproval(ctx *gin.Context) {
var req *cast.UpdateStatusReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
req.WorkAction = cast.WorkActionENUM_APPROVAL
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.UpdateStatus(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
return
}
func WorkList(ctx *gin.Context) {
var (
req *cast.WorkListReq
resp *cast.WorkListResp
)
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
resp, err = service.CastProvider.WorkList(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
if len(resp.Data) > 0 {
var workUuidApprovalIDMap = make(map[int]string)
for _, v := range resp.Data {
if v.WorkStatus == 2 && v.ApprovalID != "" {
approvalID, _ := strconv.ParseUint(v.ApprovalID, 10, 64)
workUuidApprovalIDMap[int(approvalID)] = v.WorkUuid
}
}
if len(workUuidApprovalIDMap) > 0 {
_ = RefreshWorkApprovalStatus(ctx, workUuidApprovalIDMap)
}
}
service.Success(ctx, resp)
return
}
func WorkDetail(ctx *gin.Context) {
var (
req *cast.WorkDetailReq
resp *cast.WorkDetailResp
)
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
resp, err = service.CastProvider.WorkDetail(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
return
}
func CheckUserBundleBalance(userID int32, balanceType modelCast.BalanceTypeEnum) (err error) {
resp, err := service.BundleProvider.GetBundleBalanceByUserId(context.Background(), &bundle.GetBundleBalanceByUserIdReq{UserId: userID})
if err != nil {
return
}
zap.L().Info("CheckUserBundleBalance", zap.Any("resp", resp))
fmt.Println("CheckUserBundleBalance resp", resp)
switch balanceType {
case modelCast.BalanceTypeAccountValue:
if resp.AccountNumber-resp.AccountConsumptionNumber <= 0 {
err = errors.New(e.ErrorBalanceInsufficient)
return
}
case modelCast.BalanceTypeImageValue:
if resp.ImageNumber-resp.ImageConsumptionNumber <= 0 {
err = errors.New(e.ErrorBalanceInsufficient)
return
}
case modelCast.BalanceTypeVideoValue:
if resp.VideoNumber-resp.VideoConsumptionNumber <= 0 {
err = errors.New(e.ErrorBalanceInsufficient)
return
}
}
return
}
func RePublish(ctx *gin.Context) {
var (
req *cast.RePublishReq
resp *cast.RePublishResp
)
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
resp, err = service.CastProvider.RePublish(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
artistID, _ := strconv.ParseUint(resp.ArtistUuid, 10, 64)
balanceReq := &bundle.AddBundleBalanceReq{
UserId: int32(artistID),
}
if resp.WorkCategory == 1 {
balanceReq.ImageConsumptionNumber = 1
}
if resp.WorkCategory == 2 {
balanceReq.VideoConsumptionNumber = 1
}
_, err = service.BundleProvider.AddBundleBalance(context.Background(), balanceReq)
if err != nil {
service.Error(ctx, err)
//FIXME 进行回滚
return
}
service.Success(ctx, nil)
return
}
//修改余量我还需要调用吗
func UserBundleBalanceCost() {
service.BundleProvider.AddBundleBalance(context.Background(), &bundle.AddBundleBalanceReq{})
}
func RefreshWorkApprovalStatus(ctx *gin.Context, approvalIDWorkUuidMap map[int]string) (err error) {
var castS = new(CastService)
var data = make(map[int]modelCast.Item)
var approvalIDs []int
for approvalId, _ := range approvalIDWorkUuidMap {
approvalIDs = append(approvalIDs, approvalId)
}
if len(approvalIDs) == 0 {
return
}
data, err = castS.ApprovalDetail(approvalIDs)
// status: 1待审批 2审批通过 3审批不通过 6撤销发其中 7撤销完成
var newData = make(map[int]modelCast.Item, len(approvalIDs))
for _, v := range approvalIDs {
newData[v] = data[v]
}
newCtx := NewCtxWithUserInfo(ctx)
if len(newData) > 0 {
for approvalId, v := range newData {
if v.ID == 0 {
_, _ = service.CastProvider.UpdateStatus(newCtx, &cast.UpdateStatusReq{
WorkAction: cast.WorkActionENUM_APPROVAL_DELETE,
WorkUuid: approvalIDWorkUuidMap[approvalId],
ApprovalID: fmt.Sprint(approvalId),
ApprovalReply: "",
})
continue
}
var workAction cast.WorkActionENUM
if v.Status == 2 {
workAction = cast.WorkActionENUM_APPROVAL_PASS
} else if v.Status == 3 {
workAction = cast.WorkActionENUM_APPROVAL_REJECT
} else {
continue
}
_, _ = service.CastProvider.UpdateStatus(newCtx, &cast.UpdateStatusReq{
WorkAction: workAction,
WorkUuid: approvalIDWorkUuidMap[approvalId],
ApprovalID: fmt.Sprint(approvalId),
ApprovalReply: v.Reply,
})
}
}
return
}
func DelWork(ctx *gin.Context) {
var req *cast.DelWorkReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
_, err = service.CastProvider.DelWork(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, nil)
return
}
func Remind(ctx *gin.Context) {
var req *cast.WorkInfoReq
var err error
var workInfo *cast.WorkInfoResp
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
workInfo, err = service.CastProvider.WorkInfo(context.Background(), req)
if err != nil {
service.Error(ctx, err)
return
}
if workInfo.WorkStatus != modelCast.WorkStatusArtistConfirming {
service.Error(ctx, errors.New(e.InvalidStatus))
return
}
if workInfo.ArtistPhoneAreaCode == "" {
workInfo.ArtistPhoneAreaCode = "86"
}
artistID, _ := strconv.ParseUint(workInfo.ArtistUuid, 10, 64)
infoResp, err := service.AccountFieeProvider.Info(context.Background(), &accountFiee.InfoRequest{
ID: artistID,
Domain: "app",
})
if err != nil {
service.Error(ctx, err)
return
}
if workInfo.ArtistPhoneAreaCode == "86" {
_, err = service.AccountFieeProvider.OnlySendMsg(context.Background(), &accountFiee.SendMsgRequest{
Domain: "app",
TelNum: infoResp.TelNum,
Project: "fiee",
SignNo: 0,
MId: 277385,
Scope: "",
Zone: infoResp.TelAreaCode,
NonceStr: "",
})
} else {
_, err = service.AccountFieeProvider.SendNationTemplateMsg(context.Background(), &accountFiee.SendNationMsgRequest{
Domain: "app",
TelNum: fmt.Sprintf("%s%s", infoResp.TelAreaCode, infoResp.TelNum),
Project: "fiee",
SignNo: 0,
MId: 108375,
Scope: "",
})
}
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, nil)
return
}

View File

@ -11,7 +11,6 @@ import (
"fonchain-fiee/api/order"
"fonchain-fiee/api/payment"
"fonchain-fiee/api/pressreleases"
"fonchain-fiee/api/secFilings"
pkConfig "fonchain-fiee/pkg/config"
"os"
@ -30,20 +29,17 @@ var PaymentProvider = new(payment.PaymentCentClientImpl)
var CastProvider = new(cast.CastClientImpl)
var GovernanceProvider = new(governance.GovernanceClientImpl)
var PressReleasesProvider = new(pressreleases.PressReleasesClientImpl)
var SecFilingProvider = new(secFilings.SecFilingsClientImpl)
func init() {
config.SetConsumerService(BundleProvider)
config.SetConsumerService(OrderProvider)
config.SetConsumerService(AccountProvider)
config.SetConsumerService(PaymentProvider)
//config.SetConsumerService(OrderProvider)
//config.SetConsumerService(AccountProvider)
//config.SetConsumerService(PaymentProvider)
config.SetConsumerService(AccountFieeProvider)
config.SetConsumerService(CastProvider)
config.SetConsumerService(FilesProvider)
config.SetConsumerService(GovernanceProvider)
config.SetConsumerService(PressReleasesProvider)
config.SetConsumerService(SecFilingProvider)
if err := config.Load(); err != nil {
panic(err)
}

View File

@ -1,235 +0,0 @@
package secfilings
import (
"encoding/json"
"errors"
"fmt"
"fonchain-fiee/api/secFilings"
"fonchain-fiee/pkg/model/login"
"fonchain-fiee/pkg/service"
"net/http"
"net/url"
"strconv"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
func CreateSecFiling(c *gin.Context) {
var req secFilings.CreateSecFilingReq
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
userInfo := login.GetUserInfoFromC(c)
req.Operator = userInfo.Name
req.OperatorId = int32(userInfo.ID)
res, err := service.SecFilingProvider.CreateSecFiling(c, &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func UpdateSecFiling(c *gin.Context) {
var req secFilings.UpdateSecFilingReq
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
userInfo := login.GetUserInfoFromC(c)
req.Operator = userInfo.Name
req.OperatorId = int32(userInfo.ID)
res, err := service.SecFilingProvider.UpdateSecFiling(c, &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func UpdateSecFilingStatus(c *gin.Context) {
var req secFilings.UpdateSecFilingStatusReq
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
userInfo := login.GetUserInfoFromC(c)
req.Operator = userInfo.Name
req.OperatorId = int32(userInfo.ID)
res, err := service.SecFilingProvider.UpdateSecFilingStatus(c, &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func ListSecFiling(c *gin.Context) {
var req secFilings.ListSecFilingReq
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
res, err := service.SecFilingProvider.ListSecFiling(c, &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func DetailSecFiling(c *gin.Context) {
var req secFilings.DetailSecFilingReq
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
res, err := service.SecFilingProvider.DetailSecFiling(c, &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func DeleteSecFiling(c *gin.Context) {
var req secFilings.DeleteSecFilingReq
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
userInfo := login.GetUserInfoFromC(c)
req.Operator = userInfo.Name
req.OperatorId = int32(userInfo.ID)
res, err := service.SecFilingProvider.DeleteSecFiling(c, &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
type GetSecFilingsReq struct {
FilingDate string `json:"filingDate"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
type GetSecFilingsData struct {
Symbol string `json:"symbol"`
Cik string `json:"cik"`
FilingDate string `json:"filingDate"`
AcceptedDate string `json:"acceptedDate"`
FormType string `json:"formType"`
Link string `json:"link"`
FinalLink string `json:"finalLink"`
IsSelect bool `json:"isSelect"`
}
type GetSecFilingsResp struct {
Total int `json:"total"`
Data []*GetSecFilingsResult `json:"data"`
}
type GetSecFilingsResult struct {
//Symbol string `json:"symbol"`
//Cik string `json:"cik"`
FilingDate string `json:"filingDate"`
Form string `json:"form"`
//Description string `json:"description"`
//FormDescription string `json:"formDescription"`
FileLink string `json:"fileLink"`
IsSelect bool `json:"isSelect"`
}
func GetSecFilings(c *gin.Context) {
var req GetSecFilingsReq
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
if req.FilingDate == "" {
service.Error(c, errors.New("filing_date is empty"))
return
}
fmt.Println(req.FilingDate)
symbol := "MINM"
beginDate := req.FilingDate
endDate := req.FilingDate
page := 0
pageSize := 100
if req.Page != 0 && req.PageSize != 0 {
page = req.Page - 1
pageSize = req.PageSize
}
baseURL := "https://financialmodelingprep.com/stable/sec-filings-search/symbol"
params := url.Values{}
params.Add("symbol", symbol)
params.Add("from", beginDate)
params.Add("to", endDate)
params.Add("page", strconv.Itoa(page))
params.Add("limit", strconv.Itoa(pageSize))
params.Add("apikey", "lBQWUwdjRmfHVZ7e3I1trWe4jw0ZtDct")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
resp, err := http.Get(fullURL)
if err != nil {
service.Error(c, err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
service.Error(c, fmt.Errorf("http status code is not 200"))
return
}
var result []GetSecFilingsData
err = json.NewDecoder(resp.Body).Decode(&result)
if err != nil {
service.Error(c, err)
return
}
var data = GetSecFilingsResp{
Total: 0,
Data: make([]*GetSecFilingsResult, 0),
}
for _, v := range result {
res, err := service.SecFilingProvider.IsSecFilingExist(c, &secFilings.IsSecFilingExistReq{
FilingDate: req.FilingDate,
Form: v.FormType,
FinalLink: v.FinalLink,
})
if err != nil {
service.Error(c, err)
return
}
data.Data = append(data.Data, &GetSecFilingsResult{
FilingDate: req.FilingDate,
Form: v.FormType,
FileLink: v.FinalLink,
IsSelect: res.Exist,
})
data.Total++
}
service.Success(c, data)
}
func GetFormList(c *gin.Context) {
var req secFilings.ListFormTypeReq
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
res, err := service.SecFilingProvider.ListFormType(c, &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}
func WebListSecFiling(c *gin.Context) {
var req secFilings.WebListSecFilingReq
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
service.Error(c, err)
return
}
res, err := service.SecFilingProvider.WebListSecFiling(c, &req)
if err != nil {
service.Error(c, err)
return
}
service.Success(c, res)
}

View File

@ -329,19 +329,3 @@ func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName str
snapshotName = names[len(names)-1] + "." + PngType
return
}
func UploadWithBuffer(fileBuffer *bytes.Buffer, cloudStoreSubPath string) (url string, err error) {
Client, err := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint)
if err != nil {
err = errors.New(fmt.Sprintf("云存储初始化失败:%s", err.Error()))
return
}
cloudStoreSubPath = getEnvDir(cloudStoreSubPath)
_, err = Client.PutObjectFromBytes(config.ConfigData.Oss.BucketName, cloudStoreSubPath, fileBuffer.Bytes())
url = config.ConfigData.Oss.CdnHost + "/" + cloudStoreSubPath
return
}
func getEnvDir(cloudStoreSubPath string) (ep string) {
ep, _ = url.JoinPath("fiee", cloudStoreSubPath)
return ep
}

View File

@ -1,34 +0,0 @@
package utils
import (
"bytes"
"io/ioutil"
"net/http"
)
func Post(url, data string) (string, error) {
reader := bytes.NewReader([]byte(data))
request, err := http.NewRequest("POST", url, reader)
if err != nil {
return "", err
}
defer request.Body.Close() //程序在使用完回复后必须关闭回复的主体
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
//必须设定该参数,POST参数才能正常提交意思是以json串提交数据
client := http.Client{}
resp, err := client.Do(request) //Do 方法发送请求,返回 HTTP 回复
if err != nil {
return "", err
}
respBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
//byte数组直接转成string优化内存
// str := (*string)(unsafe.Pointer(&respBytes))
return string(respBytes), nil
}

View File

@ -1,47 +0,0 @@
/*
* @FileName: if.go
* @Author: JJXu
* @CreateTime: 2022/3/31 下午10:34
* @Description:
*/
package utils
import "strings"
func If(condition bool, trueVal, falseVal interface{}) interface{} {
if condition {
return trueVal
}
return falseVal
}
func IfGec[T ~string | ~int | ~int32 | ~int64 | ~bool | ~float32 | ~float64](condition bool, trueVal, falseVal T) T {
if condition {
return trueVal
}
return falseVal
}
// IsValueInList 值是否在列表中
// value:查询的值
// list: 列表
// disableStrictCase: 禁用严格大小写检查。默认是严格大小写
func IsValueInList(value string, list []string, disableStrictCase ...bool) bool {
var disStrictCase bool
if disableStrictCase != nil {
disStrictCase = disableStrictCase[0]
}
for _, v := range list {
var listValue string
if disStrictCase {
listValue = strings.ToLower(v)
value = strings.ToLower(v)
} else {
listValue = v
}
if listValue == value {
return true
}
}
return false
}

View File

@ -1,51 +0,0 @@
// Package utils -----------------------------
// @file : requestDataToProto.go
// @author : JJXu
// @contact : wavingbear@163.com
// @time : 2023/8/28 17:57
// -------------------------------------------
package utils
import (
"reflect"
"strings"
)
// http请求转proto请求
func RequestDataConvert(from interface{}, to interface{}) {
var proxyField = "Query"
fromValue := reflect.ValueOf(from)
toValue := reflect.ValueOf(to)
toType := reflect.TypeOf(to)
// 获取From结构体的字段信息
fromType := fromValue.Type().Elem()
for i := 0; i < fromType.NumField(); i++ {
// 获取字段名和字段值
fieldName := fromType.Field(i).Name
fieldValue := fromValue.Elem().FieldByName(fieldName)
if fieldName != proxyField {
_, exists := toType.Elem().FieldByName(fieldName)
if exists {
// 设置To结构体中相应字段的值
toValue.Elem().FieldByName(fieldName).Set(fieldValue)
}
}
}
queryField, exists := toType.Elem().FieldByName(proxyField)
if exists {
var queryFieldTypeName string
// 指针类型额外处理,拿到真实的数据类型
if queryField.Type.Kind() == reflect.Ptr {
queryFieldTypeName = queryField.Type.Elem().String()
} else {
queryFieldTypeName = queryField.Type.Kind().String()
}
//处理拿到的结构体类型如 utils.xxxx的类型去掉utils.这部分
if strings.Contains(queryFieldTypeName, ".") {
queryFieldTypeName = strings.Split(queryFieldTypeName, ".")[1]
}
fromQueryValue := fromValue.Elem().FieldByName(queryFieldTypeName)
toValue.Elem().FieldByName(proxyField).Set(fromQueryValue.Addr())
}
}

Some files were not shown because too many files have changed in this diff Show More