diff --git a/api/cast/cast.pb.go b/api/cast/cast.pb.go index 0ce65ab..8910cac 100644 --- a/api/cast/cast.pb.go +++ b/api/cast/cast.pb.go @@ -973,6 +973,8 @@ type UpdateWorkImageReq struct { LineNo uint32 `protobuf:"varint,18,opt,name=lineNo,proto3" json:"lineNo"` Remark string `protobuf:"bytes,19,opt,name=remark,proto3" json:"remark"` Success bool `protobuf:"varint,20,opt,name=success,proto3" json:"success"` + ArtistSubNum string `protobuf:"bytes,21,opt,name=artistSubNum,proto3" json:"artistSubNum"` + ScriptUuid string `protobuf:"bytes,22,opt,name=scriptUuid,proto3" json:"scriptUuid"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1147,6 +1149,20 @@ func (x *UpdateWorkImageReq) GetSuccess() bool { return false } +func (x *UpdateWorkImageReq) GetArtistSubNum() string { + if x != nil { + return x.ArtistSubNum + } + return "" +} + +func (x *UpdateWorkImageReq) GetScriptUuid() string { + if x != nil { + return x.ScriptUuid + } + return "" +} + type UpdateWorkImageResp struct { state protoimpl.MessageState `protogen:"open.v1"` WorkUuid string `protobuf:"bytes,1,opt,name=workUuid,proto3" json:"workUuid"` @@ -1299,6 +1315,7 @@ type UpdateWorkVideoReq struct { CoverTimestampMs uint64 `protobuf:"varint,19,opt,name=coverTimestampMs,proto3" json:"coverTimestampMs"` AutoPublish AutoPublishENUM `protobuf:"varint,20,opt,name=autoPublish,proto3,enum=Cast.AutoPublishENUM" json:"autoPublish"` ScriptUuid string `protobuf:"bytes,21,opt,name=scriptUuid,proto3" json:"scriptUuid"` + ArtistSubNum string `protobuf:"bytes,22,opt,name=artistSubNum,proto3" json:"artistSubNum"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1480,6 +1497,13 @@ func (x *UpdateWorkVideoReq) GetScriptUuid() string { return "" } +func (x *UpdateWorkVideoReq) GetArtistSubNum() string { + if x != nil { + return x.ArtistSubNum + } + return "" +} + type UpdateWorkVideoResp struct { state protoimpl.MessageState `protogen:"open.v1"` WorkUuid string `protobuf:"bytes,1,opt,name=workUuid,proto3" json:"workUuid"` @@ -1646,6 +1670,10 @@ type WorkListReq struct { MediaAccountUuids []string `protobuf:"bytes,14,rep,name=mediaAccountUuids,proto3" json:"mediaAccountUuids"` CostType int32 `protobuf:"varint,15,opt,name=costType,proto3" json:"costType"` ScriptUuid string `protobuf:"bytes,16,opt,name=scriptUuid,proto3" json:"scriptUuid"` + ArtistSubNum string `protobuf:"bytes,17,opt,name=artistSubNum,proto3" json:"artistSubNum"` + TiktokStatus uint32 `protobuf:"varint,18,opt,name=tiktokStatus,proto3" json:"tiktokStatus"` + InsStatus uint32 `protobuf:"varint,19,opt,name=insStatus,proto3" json:"insStatus"` + DmStatus uint32 `protobuf:"varint,20,opt,name=dmStatus,proto3" json:"dmStatus"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1792,6 +1820,34 @@ func (x *WorkListReq) GetScriptUuid() string { return "" } +func (x *WorkListReq) GetArtistSubNum() string { + if x != nil { + return x.ArtistSubNum + } + return "" +} + +func (x *WorkListReq) GetTiktokStatus() uint32 { + if x != nil { + return x.TiktokStatus + } + return 0 +} + +func (x *WorkListReq) GetInsStatus() uint32 { + if x != nil { + return x.InsStatus + } + return 0 +} + +func (x *WorkListReq) GetDmStatus() uint32 { + if x != nil { + return x.DmStatus + } + return 0 +} + type WorkListResp struct { state protoimpl.MessageState `protogen:"open.v1"` Data []*WorkListResp_Info `protobuf:"bytes,1,rep,name=data,proto3" json:"data"` @@ -2011,12 +2067,13 @@ type WorkDetailResp struct { CoverTimestampMs uint64 `protobuf:"varint,19,opt,name=coverTimestampMs,proto3" json:"coverTimestampMs"` ScriptUuid string `protobuf:"bytes,20,opt,name=scriptUuid,proto3" json:"scriptUuid"` ArtistUuid string `protobuf:"bytes,21,opt,name=artistUuid,proto3" json:"artistUuid"` - TiktokStatus uint32 `protobuf:"varint,22,opt,name=tiktokStatus,proto3" json:"tiktokStatus"` - InsStatus uint32 `protobuf:"varint,23,opt,name=insStatus,proto3" json:"insStatus"` - DmStatus uint32 `protobuf:"varint,24,opt,name=dmStatus,proto3" json:"dmStatus"` - NeedPlatformIDs []int32 `protobuf:"varint,25,rep,packed,name=needPlatformIDs,proto3" json:"needPlatformIDs"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // uint32 tiktokStatus = 22; + // uint32 insStatus = 23; + // uint32 dmStatus = 24; + NeedPlatformIDs []int32 `protobuf:"varint,25,rep,packed,name=needPlatformIDs,proto3" json:"needPlatformIDs"` + ArtistSubNum string `protobuf:"bytes,26,opt,name=artistSubNum,proto3" json:"artistSubNum"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *WorkDetailResp) Reset() { @@ -2196,27 +2253,6 @@ func (x *WorkDetailResp) GetArtistUuid() string { return "" } -func (x *WorkDetailResp) GetTiktokStatus() uint32 { - if x != nil { - return x.TiktokStatus - } - return 0 -} - -func (x *WorkDetailResp) GetInsStatus() uint32 { - if x != nil { - return x.InsStatus - } - return 0 -} - -func (x *WorkDetailResp) GetDmStatus() uint32 { - if x != nil { - return x.DmStatus - } - return 0 -} - func (x *WorkDetailResp) GetNeedPlatformIDs() []int32 { if x != nil { return x.NeedPlatformIDs @@ -2224,6 +2260,13 @@ func (x *WorkDetailResp) GetNeedPlatformIDs() []int32 { return nil } +func (x *WorkDetailResp) GetArtistSubNum() string { + if x != nil { + return x.ArtistSubNum + } + return "" +} + type UpdateStatusReq struct { state protoimpl.MessageState `protogen:"open.v1"` WorkAction WorkActionENUM `protobuf:"varint,1,opt,name=workAction,proto3,enum=Cast.WorkActionENUM" json:"workAction"` @@ -11171,6 +11214,7 @@ type WorkPlatformInfo struct { Remark string `protobuf:"bytes,8,opt,name=remark,proto3" json:"remark"` // 备注 CreatedAt int32 `protobuf:"varint,9,opt,name=createdAt,proto3" json:"createdAt"` // 创建时间 UpdatedAt int32 `protobuf:"varint,10,opt,name=updatedAt,proto3" json:"updatedAt"` // 更新时间 + ArtistUuid string `protobuf:"bytes,11,opt,name=artistUuid,proto3" json:"artistUuid"` // 艺人UUID unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -11275,6 +11319,13 @@ func (x *WorkPlatformInfo) GetUpdatedAt() int32 { return 0 } +func (x *WorkPlatformInfo) GetArtistUuid() string { + if x != nil { + return x.ArtistUuid + } + return "" +} + // 获取作品平台信息列表响应 type ListWorkPlatformInfoResp struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -11347,6 +11398,11 @@ type WorkListResp_Info struct { CostType uint32 `protobuf:"varint,15,opt,name=costType,proto3" json:"costType"` ScriptUuid string `protobuf:"bytes,16,opt,name=scriptUuid,proto3" json:"scriptUuid"` ScriptTitle string `protobuf:"bytes,17,opt,name=scriptTitle,proto3" json:"scriptTitle"` + ArtistSubNum string `protobuf:"bytes,18,opt,name=artistSubNum,proto3" json:"artistSubNum"` + TiktokStatus uint32 `protobuf:"varint,19,opt,name=tiktokStatus,proto3" json:"tiktokStatus"` + InsStatus uint32 `protobuf:"varint,20,opt,name=insStatus,proto3" json:"insStatus"` + DmStatus uint32 `protobuf:"varint,21,opt,name=dmStatus,proto3" json:"dmStatus"` + ConfirmType uint32 `protobuf:"varint,22,opt,name=confirmType,proto3" json:"confirmType"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -11500,6 +11556,41 @@ func (x *WorkListResp_Info) GetScriptTitle() string { return "" } +func (x *WorkListResp_Info) GetArtistSubNum() string { + if x != nil { + return x.ArtistSubNum + } + return "" +} + +func (x *WorkListResp_Info) GetTiktokStatus() uint32 { + if x != nil { + return x.TiktokStatus + } + return 0 +} + +func (x *WorkListResp_Info) GetInsStatus() uint32 { + if x != nil { + return x.InsStatus + } + return 0 +} + +func (x *WorkListResp_Info) GetDmStatus() uint32 { + if x != nil { + return x.DmStatus + } + return 0 +} + +func (x *WorkListResp_Info) GetConfirmType() uint32 { + if x != nil { + return x.ConfirmType + } + return 0 +} + type MediaAccountsResp_Info struct { state protoimpl.MessageState `protogen:"open.v1"` PlatformID uint32 `protobuf:"varint,1,opt,name=platformID,proto3" json:"platformID"` @@ -12048,7 +12139,7 @@ const file_pb_fiee_cast_proto_rawDesc = "" + "\x0eBindManagerReq\x12*\n" + "\x10mediaAccountUuid\x18\x01 \x01(\tR\x10mediaAccountUuid\x12 \n" + "\vmanagerUuid\x18\x02 \x01(\tR\vmanagerUuid\x12(\n" + - "\x0fmanagerUserName\x18\x03 \x01(\tR\x0fmanagerUserName\"\x8e\x06\n" + + "\x0fmanagerUserName\x18\x03 \x01(\tR\x0fmanagerUserName\"\xd2\x06\n" + "\x12UpdateWorkImageReq\x12\x14\n" + "\x05title\x18\x01 \x01(\tR\x05title\x12\x18\n" + "\acontent\x18\x02 \x01(\tR\acontent\x12\x16\n" + @@ -12074,7 +12165,11 @@ const file_pb_fiee_cast_proto_rawDesc = "" + "\x06source\x18\x11 \x01(\rR\x06source\x12\x16\n" + "\x06lineNo\x18\x12 \x01(\rR\x06lineNo\x12\x16\n" + "\x06remark\x18\x13 \x01(\tR\x06remark\x12\x18\n" + - "\asuccess\x18\x14 \x01(\bR\asuccess\"1\n" + + "\asuccess\x18\x14 \x01(\bR\asuccess\x12\"\n" + + "\fartistSubNum\x18\x15 \x01(\tR\fartistSubNum\x12\x1e\n" + + "\n" + + "scriptUuid\x18\x16 \x01(\tR\n" + + "scriptUuid\"1\n" + "\x13UpdateWorkImageResp\x12\x1a\n" + "\bworkUuid\x18\x01 \x01(\tR\bworkUuid\"\xbf\x01\n" + "\rPublishConfig\x12$\n" + @@ -12087,7 +12182,7 @@ const file_pb_fiee_cast_proto_rawDesc = "" + "\n" + "canComment\x18\x05 \x01(\rR\n" + "canComment\x12\x12\n" + - "\x04isAI\x18\x06 \x01(\rR\x04isAI\"\xe9\x06\n" + + "\x04isAI\x18\x06 \x01(\rR\x04isAI\"\x8d\a\n" + "\x12UpdateWorkVideoReq\x12\x14\n" + "\x05title\x18\x01 \x01(\tR\x05title\x12\x18\n" + "\acontent\x18\x02 \x01(\tR\acontent\x12\x1a\n" + @@ -12116,7 +12211,8 @@ const file_pb_fiee_cast_proto_rawDesc = "" + "\vautoPublish\x18\x14 \x01(\x0e2\x15.Cast.AutoPublishENUMR\vautoPublish\x12\x1e\n" + "\n" + "scriptUuid\x18\x15 \x01(\tR\n" + - "scriptUuid\"1\n" + + "scriptUuid\x12\"\n" + + "\fartistSubNum\x18\x16 \x01(\tR\fartistSubNum\"1\n" + "\x13UpdateWorkVideoResp\x12\x1a\n" + "\bworkUuid\x18\x01 \x01(\tR\bworkUuid\"\x90\x01\n" + "\fMediaInfoReq\x12\x1e\n" + @@ -12128,7 +12224,7 @@ const file_pb_fiee_cast_proto_rawDesc = "" + "platformID\x12*\n" + "\x10platformUserName\x18\x03 \x01(\tR\x10platformUserName\"8\n" + "\rMediaInfoResp\x12'\n" + - "\x04info\x18\x01 \x01(\v2\x13.Cast.MediaUserInfoR\x04info\"\xcb\x04\n" + + "\x04info\x18\x01 \x01(\v2\x13.Cast.MediaUserInfoR\x04info\"\xcd\x05\n" + "\vWorkListReq\x12\x1c\n" + "\tartistVal\x18\x01 \x01(\tR\tartistVal\x12\x1e\n" + "\n" + @@ -12152,10 +12248,14 @@ const file_pb_fiee_cast_proto_rawDesc = "" + "\bcostType\x18\x0f \x01(\x05R\bcostType\x12\x1e\n" + "\n" + "scriptUuid\x18\x10 \x01(\tR\n" + - "scriptUuid\"\xaa\x05\n" + + "scriptUuid\x12\"\n" + + "\fartistSubNum\x18\x11 \x01(\tR\fartistSubNum\x12\"\n" + + "\ftiktokStatus\x18\x12 \x01(\rR\ftiktokStatus\x12\x1c\n" + + "\tinsStatus\x18\x13 \x01(\rR\tinsStatus\x12\x1a\n" + + "\bdmStatus\x18\x14 \x01(\rR\bdmStatus\"\xce\x06\n" + "\fWorkListResp\x12+\n" + "\x04data\x18\x01 \x03(\v2\x17.Cast.WorkListResp.InfoR\x04data\x12\x14\n" + - "\x05count\x18\x02 \x01(\x03R\x05count\x1a\xd6\x04\n" + + "\x05count\x18\x02 \x01(\x03R\x05count\x1a\xfa\x05\n" + "\x04Info\x12\x1a\n" + "\bworkUuid\x18\x01 \x01(\tR\bworkUuid\x12\x1e\n" + "\n" + @@ -12184,7 +12284,12 @@ const file_pb_fiee_cast_proto_rawDesc = "" + "\n" + "scriptUuid\x18\x10 \x01(\tR\n" + "scriptUuid\x12 \n" + - "\vscriptTitle\x18\x11 \x01(\tR\vscriptTitle\"+\n" + + "\vscriptTitle\x18\x11 \x01(\tR\vscriptTitle\x12\"\n" + + "\fartistSubNum\x18\x12 \x01(\tR\fartistSubNum\x12\"\n" + + "\ftiktokStatus\x18\x13 \x01(\rR\ftiktokStatus\x12\x1c\n" + + "\tinsStatus\x18\x14 \x01(\rR\tinsStatus\x12\x1a\n" + + "\bdmStatus\x18\x15 \x01(\rR\bdmStatus\x12 \n" + + "\vconfirmType\x18\x16 \x01(\rR\vconfirmType\"+\n" + "\rWorkDetailReq\x12\x1a\n" + "\bworkUuid\x18\x01 \x01(\tR\bworkUuid\"\xfb\x01\n" + "\vWorkLogInfo\x12\x1a\n" + @@ -12201,7 +12306,7 @@ const file_pb_fiee_cast_proto_rawDesc = "" + "\textraData\x18\a \x01(\tR\textraData\x12\x1e\n" + "\n" + "workStatus\x18\b \x01(\rR\n" + - "workStatus\"\xcd\b\n" + + "workStatus\"\x93\b\n" + "\x0eWorkDetailResp\x12\x1a\n" + "\bworkUuid\x18\x01 \x01(\tR\bworkUuid\x12\x14\n" + "\x05title\x18\x02 \x01(\tR\x05title\x12\x18\n" + @@ -12232,11 +12337,9 @@ const file_pb_fiee_cast_proto_rawDesc = "" + "scriptUuid\x12\x1e\n" + "\n" + "artistUuid\x18\x15 \x01(\tR\n" + - "artistUuid\x12\"\n" + - "\ftiktokStatus\x18\x16 \x01(\rR\ftiktokStatus\x12\x1c\n" + - "\tinsStatus\x18\x17 \x01(\rR\tinsStatus\x12\x1a\n" + - "\bdmStatus\x18\x18 \x01(\rR\bdmStatus\x12(\n" + - "\x0fneedPlatformIDs\x18\x19 \x03(\x05R\x0fneedPlatformIDs\x1aT\n" + + "artistUuid\x12(\n" + + "\x0fneedPlatformIDs\x18\x19 \x03(\x05R\x0fneedPlatformIDs\x12\"\n" + + "\fartistSubNum\x18\x1a \x01(\tR\fartistSubNum\x1aT\n" + "\x11MediaAccDataEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12)\n" + "\x05value\x18\x02 \x01(\v2\x13.Cast.MediaUserInfoR\x05value:\x028\x01\"\xca\x02\n" + @@ -13291,7 +13394,7 @@ const file_pb_fiee_cast_proto_rawDesc = "" + "\vplatformIDs\x18\x01 \x03(\rR\vplatformIDs\x12.\n" + "\x12publishMediaStatus\x18\x02 \x01(\x05R\x12publishMediaStatus\x12\x12\n" + "\x04page\x18\x03 \x01(\x05R\x04page\x12\x1a\n" + - "\bpageSize\x18\x04 \x01(\x05R\bpageSize\"\xd2\x02\n" + + "\bpageSize\x18\x04 \x01(\x05R\bpageSize\"\xf2\x02\n" + "\x10WorkPlatformInfo\x12\x12\n" + "\x04uuid\x18\x01 \x01(\tR\x04uuid\x12\x1a\n" + "\bworkUuid\x18\x02 \x01(\tR\bworkUuid\x12 \n" + @@ -13305,7 +13408,10 @@ const file_pb_fiee_cast_proto_rawDesc = "" + "\x06remark\x18\b \x01(\tR\x06remark\x12\x1c\n" + "\tcreatedAt\x18\t \x01(\x05R\tcreatedAt\x12\x1c\n" + "\tupdatedAt\x18\n" + - " \x01(\x05R\tupdatedAt\"\\\n" + + " \x01(\x05R\tupdatedAt\x12\x1e\n" + + "\n" + + "artistUuid\x18\v \x01(\tR\n" + + "artistUuid\"\\\n" + "\x18ListWorkPlatformInfoResp\x12*\n" + "\x04data\x18\x01 \x03(\v2\x16.Cast.WorkPlatformInfoR\x04data\x12\x14\n" + "\x05count\x18\x02 \x01(\x03R\x05count*G\n" + diff --git a/api/cast/cast.pb.validate.go b/api/cast/cast.pb.validate.go index ae9cf00..f8db610 100644 --- a/api/cast/cast.pb.validate.go +++ b/api/cast/cast.pb.validate.go @@ -1115,6 +1115,10 @@ func (m *UpdateWorkImageReq) validate(all bool) error { // no validation rules for Success + // no validation rules for ArtistSubNum + + // no validation rules for ScriptUuid + if len(errors) > 0 { return UpdateWorkImageReqMultiError(errors) } @@ -1577,6 +1581,8 @@ func (m *UpdateWorkVideoReq) validate(all bool) error { // no validation rules for ScriptUuid + // no validation rules for ArtistSubNum + if len(errors) > 0 { return UpdateWorkVideoReqMultiError(errors) } @@ -2047,6 +2053,14 @@ func (m *WorkListReq) validate(all bool) error { // no validation rules for ScriptUuid + // no validation rules for ArtistSubNum + + // no validation rules for TiktokStatus + + // no validation rules for InsStatus + + // no validation rules for DmStatus + if len(errors) > 0 { return WorkListReqMultiError(errors) } @@ -2716,11 +2730,7 @@ func (m *WorkDetailResp) validate(all bool) error { // no validation rules for ArtistUuid - // no validation rules for TiktokStatus - - // no validation rules for InsStatus - - // no validation rules for DmStatus + // no validation rules for ArtistSubNum if len(errors) > 0 { return WorkDetailRespMultiError(errors) @@ -17198,6 +17208,8 @@ func (m *WorkPlatformInfo) validate(all bool) error { // no validation rules for UpdatedAt + // no validation rules for ArtistUuid + if len(errors) > 0 { return WorkPlatformInfoMultiError(errors) } @@ -17460,6 +17472,16 @@ func (m *WorkListResp_Info) validate(all bool) error { // no validation rules for ScriptTitle + // no validation rules for ArtistSubNum + + // no validation rules for TiktokStatus + + // no validation rules for InsStatus + + // no validation rules for DmStatus + + // no validation rules for ConfirmType + if len(errors) > 0 { return WorkListResp_InfoMultiError(errors) } diff --git a/data/alibabacloud.env b/data/alibabacloud.env new file mode 100644 index 0000000..570c8e1 --- /dev/null +++ b/data/alibabacloud.env @@ -0,0 +1,16 @@ +#=========== 阿里云内容安全配置 =========== +# STS登录模式配置 +# RAM用户AccessKey ID(用于获取STS临时凭证) +RAM_ACCESS_KEY_ID=LTAI5tNBzbeEbG1yCitvHsMb + +# RAM用户AccessKey Secret +RAM_ACCESS_KEY_SECRET=G1xAUB8G6WDVo0SLr6DJaJjNWIlpmO + +# 要扮演的RAM角色ARN +RAM_ROLE_ARN=acs:ram::5828544250383902:role/content-secret + +# 阿里云区域(可选,默认为cn-shanghai) +ALIBABA_CLOUD_REGION=ap-southeast-1 + +# 阿里云端点(可选,默认为green.cn-shanghai.aliyuncs.com) +ALIBABA_CLOUD_ENDPOINT=green-cip.ap-southeast-1.aliyuncs.com \ No newline at end of file diff --git a/pkg/model/security/file.go b/pkg/model/security/file.go new file mode 100644 index 0000000..56756fe --- /dev/null +++ b/pkg/model/security/file.go @@ -0,0 +1,13 @@ +package security + +import "time" + +type FileInfo struct { + SubmitTime time.Time + FileName string + FileUrl string + FileType string + SecurityStatus string + Describe string + ProblemTimeFrame string +} diff --git a/pkg/security/init.go b/pkg/security/init.go index 2084603..17a2890 100644 --- a/pkg/security/init.go +++ b/pkg/security/init.go @@ -1,11 +1,18 @@ package security import ( + "sync" + "time" + "github.com/fonchain/utils/security" "go.uber.org/zap" ) -var ImageScanner *security.ImageScanner +var ( + ImageScanner *security.ImageScanner + globalConfig *security.Config + configMutex sync.RWMutex +) func Init() { config, err := security.LoadConfigFromFile("../conf/alibabacloud.env") @@ -25,3 +32,37 @@ func Init() { panic(err) } } + +// GetGlobalConfig 获取全局配置实例(单例模式) +func GetGlobalConfig(configFile string) (*security.Config, error) { + configMutex.RLock() + if globalConfig != nil { + // 检查 token 是否还有效 + if !globalConfig.TokenExpiration.IsZero() && + time.Now().Before(globalConfig.TokenExpiration.Add(-5*time.Minute)) { + configMutex.RUnlock() + return globalConfig, nil + } + } + configMutex.RUnlock() + + // 需要重新加载或刷新 + configMutex.Lock() + defer configMutex.Unlock() + + // 双重检查 + if globalConfig != nil && + !globalConfig.TokenExpiration.IsZero() && + time.Now().Before(globalConfig.TokenExpiration.Add(-5*time.Minute)) { + return globalConfig, nil + } + + // 加载配置 + config, err := security.LoadConfigFromFile(configFile) + if err != nil { + return nil, err + } + + globalConfig = config + return globalConfig, nil +} diff --git a/pkg/service/cast/work.go b/pkg/service/cast/work.go index 417f88f..60aa350 100644 --- a/pkg/service/cast/work.go +++ b/pkg/service/cast/work.go @@ -38,6 +38,18 @@ func UpdateWorkImage(ctx *gin.Context) { service.Error(ctx, err) return } + // 图片鉴定 + for _, v := range req.Images { + ok, _err := check.SecurityFile(v) + if _err != nil { + service.Error(ctx, _err) + return + } + if !ok { + service.Error(ctx, errors.New("图片鉴定未通过")) + return + } + } artistId, _ := strconv.ParseUint(req.ArtistUuid, 10, 64) infoResp, err = service.AccountFieeProvider.Info(context.Background(), &accountFiee.InfoRequest{ ID: artistId, @@ -48,6 +60,7 @@ func UpdateWorkImage(ctx *gin.Context) { service.Error(ctx, err) return } + req.ArtistName = infoResp.Name req.ArtistPhone = infoResp.TelNum req.ArtistPhoneAreaCode = infoResp.TelAreaCode @@ -98,6 +111,15 @@ func UpdateWorkVideo(ctx *gin.Context) { service.Error(ctx, err) return } + ok, _err := check.SecurityFile(req.CoverUrl) + if _err != nil { + service.Error(ctx, _err) + return + } + if !ok { + service.Error(ctx, errors.New("图片鉴定未通过")) + return + } if config.AppConfig.System.AppMode != "dev" { artistId, _ := strconv.ParseUint(req.ArtistUuid, 10, 64) infoResp, err = service.AccountFieeProvider.Info(context.Background(), &accountFiee.InfoRequest{ diff --git a/pkg/service/check/image.go b/pkg/service/check/image.go deleted file mode 100644 index 19fd8fa..0000000 --- a/pkg/service/check/image.go +++ /dev/null @@ -1,52 +0,0 @@ -package check - -import ( - "errors" - "fmt" - "mime/multipart" - "time" - - pkgSecurity "fonchain-fiee/pkg/security" - - "github.com/fonchain/utils/security" -) - -// ImageCheckUrlValid 图片黄疸检测 true 是通过 -func ImageCheckUrlValid(imgUrl string) (bool, error) { - resp, err := pkgSecurity.ImageScanner.ScanImageByURL(imgUrl, fmt.Sprint(time.Now().UnixMicro()), security.BaselineCheckGlobal) - if err != nil { - err = errors.New("图片检测请求失败") - return false, err - } - if resp.Code != 200 { - err = errors.New("图片检测失败,错误码") - return false, err - } - if len(resp.Data) == 0 || len(resp.Data[0].Results) == 0 { - return false, errors.New("图片检测结果异常") - } - riskLevel := resp.Data[0].Results[0].RiskLevel - if *riskLevel == "none" { - return true, nil - } - return false, nil -} - -func ImageCheckByte(file *multipart.FileHeader) (bool, error) { - //imageScanner, err := security.NewImageScanner(&security.Config{ - // RAMAccessKeyID: "LTAI5tNBzbeEbG1yCitvHsMb", - // RAMAccessKeySecret: "G1xAUB8G6WDVo0SLr6DJaJjNWIlpmO", - // RAMRoleArn: "acs:ram::5828544250383902:role/content-secret", - // Region: "ap-southeast-1", - // Endpoint: "green-cip.ap-southeast-1.aliyuncs.com", - // TempAccessKeyID: "", - // TempAccessKeySecret: "", - // SecurityToken: "", - //}) - //if err != nil { - // return false, err - //} - //resp, err := imageScanner.ScanImageByFileByte(file, fmt.Sprint(time.Now().UnixMicro()), security.BaselineCheckGlobal) - //fmt.Println(resp) - return false, nil -} diff --git a/pkg/service/check/security.go b/pkg/service/check/security.go new file mode 100644 index 0000000..8c5b371 --- /dev/null +++ b/pkg/service/check/security.go @@ -0,0 +1,191 @@ +package check + +import ( + "errors" + "fmt" + "mime/multipart" + "path/filepath" + "strconv" + "time" + + modelSecurity "fonchain-fiee/pkg/model/security" + pkgSecurity "fonchain-fiee/pkg/security" + + "github.com/fonchain/utils/security" +) + +// ImageCheckUrlValid 图片黄疸检测 true 是通过 +func ImageCheckUrlValid(imgUrl string) (bool, error) { + resp, err := pkgSecurity.ImageScanner.ScanImageByURL(imgUrl, fmt.Sprint(time.Now().UnixMicro()), security.BaselineCheckGlobal) + if err != nil { + err = errors.New("图片检测请求失败") + return false, err + } + if resp.Code != 200 { + err = errors.New("图片检测失败,错误码") + return false, err + } + if len(resp.Data) == 0 || len(resp.Data[0].Results) == 0 { + return false, errors.New("图片检测结果异常") + } + riskLevel := resp.Data[0].Results[0].RiskLevel + if *riskLevel == "none" { + return true, nil + } + return false, nil +} + +func ImageCheckByte(file *multipart.FileHeader) (bool, error) { + //imageScanner, err := security.NewImageScanner(&security.Config{ + // RAMAccessKeyID: "LTAI5tNBzbeEbG1yCitvHsMb", + // RAMAccessKeySecret: "G1xAUB8G6WDVo0SLr6DJaJjNWIlpmO", + // RAMRoleArn: "acs:ram::5828544250383902:role/content-secret", + // Region: "ap-southeast-1", + // Endpoint: "green-cip.ap-southeast-1.aliyuncs.com", + // TempAccessKeyID: "", + // TempAccessKeySecret: "", + // SecurityToken: "", + //}) + //if err != nil { + // return false, err + //} + //resp, err := imageScanner.ScanImageByFileByte(file, fmt.Sprint(time.Now().UnixMicro()), security.BaselineCheckGlobal) + //fmt.Println(resp) + return false, nil +} + +func SecurityFile(fileUrl string) (bool, error) { + if fileUrl == "" { + return true, nil + } + var fileInfo modelSecurity.FileInfo + fileInfo.FileName = fileUrl + fileInfo.FileUrl = fileUrl + //获取文件名称后缀 + extension := filepath.Ext(fileUrl) + switch extension { + case ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp": + fileInfo.FileType = "image" + case ".mp4", ".avi", ".mov", ".wmv", ".flv", ".mkv": + fileInfo.FileType = "video" + default: + return false, errors.New("该类型无需安全检测") + } + err := securityScan(&fileInfo) + if err != nil { + return false, err + } + return true, nil +} + +func securityScan(fileInfo *modelSecurity.FileInfo) (err error) { + //加载阿里云配置获取临时token + aliConfig, err := pkgSecurity.GetGlobalConfig("./data/alibabacloud.env") + if err != nil { + return err + } + fmt.Println("开始获取STS Token") + err = aliConfig.GetSTSToken() + if err != nil { + return errors.New("获取STS Token失败") + } + fmt.Println("获取STS Token成功") + switch fileInfo.FileType { + case "image": + return handleImageScan(aliConfig, fileInfo) + case "video": + return handleVideoScan(aliConfig, fileInfo) + default: + return errors.New("不支持的审核类型") + } +} + +func handleVideoScan(config *security.Config, fileInfo *modelSecurity.FileInfo) (err error) { + fmt.Println("\n=== 视频内容安全审核 ===") + + scanner, err := security.NewVideoScanner(config) + if err != nil { + fmt.Printf("创建视频扫描器失败: %v\n", err) + return errors.New("创建视频扫描器失败") + } + + if fileInfo.FileUrl == "" { + fmt.Println("视频不能为空") + return errors.New("视频不能为空") + } + serviceType := security.VideoBaselineCheckGlobal + dataID := "video_" + time.Now().Format("20060102150405") + + fmt.Println("正在扫描视频(这可能需要几分钟)...") + result, err := scanner.ScanVideoAndWait(fileInfo.FileUrl, dataID, serviceType, 10*time.Minute) + if err != nil { + fmt.Printf("扫描失败: %v\n", err) + return errors.New("扫描失败") + } + scanner.PrintResult(result) + for _, v := range result.Data { + fileInfo.SecurityStatus = *v.Results.RiskLevel + if v.Results.FrameResult != nil { + frameResult := *v.Results.FrameResult + if len(frameResult.FrameSummarys) > 0 { + for _, summary := range frameResult.FrameSummarys { + fileInfo.Describe = fileInfo.Describe + *summary.Description + ";" + } + } + if len(frameResult.Frames) > 0 { + for _, frame := range frameResult.Frames { + fileInfo.ProblemTimeFrame = fileInfo.ProblemTimeFrame + strconv.FormatFloat(float64(*frame.Offset), 'f', 2, 64) + "秒;" + } + } + } + if v.Results.RiskLevel != nil { + lv := v.Results.RiskLevel + if *lv == "none" { + return nil + } + return errors.New("图片违规") + } + + return errors.New("风险等级检测未成功") + } + return nil +} + +func handleImageScan(config *security.Config, fileInfo *modelSecurity.FileInfo) (err error) { + fmt.Println("\n=== 图片内容安全审核 ===") + + scanner, err := security.NewImageScanner(config) + if err != nil { + fmt.Printf("创建图片扫描器失败:%v", err) + return errors.New("创建图片扫描器失败") + } + + if fileInfo.FileUrl == "" { + fmt.Println("文件不能为空") + return errors.New("文件不能为空") + } + + serviceType := security.BaselineCheckGlobal + + fmt.Println("正在扫描图片...") + result, err := scanner.ScanImageByURL(fileInfo.FileUrl, "image_"+time.Now().Format("20060102150405"), serviceType) + if err != nil { + fmt.Printf("扫描失败: %v\n", err) + return errors.New("扫描失败") + } + scanner.PrintResult(result) + for _, v := range result.Data { + for _, v2 := range v.Results { + fileInfo.SecurityStatus = *v2.RiskLevel + if v2.RiskLevel != nil { + lv := v2.RiskLevel + if *lv == "none" { + return nil + } + return errors.New("图片违规") + } + return errors.New("风险等级检测未成功") + } + } + return nil +}