Merge branch 'main' into feature-userinfo-daiyb

This commit is contained in:
戴育兵 2026-01-09 11:35:03 +08:00
commit b2050626b7
8 changed files with 2662 additions and 2570 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -24,7 +24,7 @@ func (w *Work) ExportExcelWorkList(data []*cast.WorkListResp_Info) (*excelize.Fi
// 表头
headers := []interface{}{
"艺人", "手机号", "用户编号", "作品标题", "脚本", "作品类型", "类型", "Ins", "Tiktok", "DM", "作品状态", "验收确认类型",
"艺人", "手机号", "用户编号", "作品标题", "脚本", "作品类型", "类型", "Ins", "Tiktok", "DM", "Youtube", "Bulesky", "作品状态", "验收确认类型",
"说明", "发布账号", "管理人", "上传时间", "待艺人确认时间", "验收确认通过时间", "发布成功时间",
}
if err := sw.SetRow("A1", headers); err != nil {
@ -72,6 +72,8 @@ func (w *Work) ExportExcelWorkList(data []*cast.WorkListResp_Info) (*excelize.Fi
modelCast.PlatformPublishStatusMM[cast.PublishStatusENUM(info.InsStatus)],
modelCast.PlatformPublishStatusMM[cast.PublishStatusENUM(info.TiktokStatus)],
modelCast.PlatformPublishStatusMM[cast.PublishStatusENUM(info.DmStatus)],
modelCast.PlatformPublishStatusMM[cast.PublishStatusENUM(info.YoutubeStatus)],
modelCast.PlatformPublishStatusMM[cast.PublishStatusENUM(info.BlueskyStatus)],
modelCast.WorkStatusMM[int(info.WorkStatus)],
modelCast.ConfirmTypeMM[int(info.ConfirmType)],
info.Remark,

View File

@ -16,17 +16,16 @@ const (
var PlatformNameKv = map[uint32]string{
1: "tiktok",
2: "youtube",
3: "instagram",
4: "DM",
5: "bluesky",
}
var NamePlatformIDKv = map[string]uint32{
"tiktok": 1,
"youtube": 2,
"instagram": 3,
"DM": 4,
}
var PlatformIDStrKv = map[string]uint8{
"TIKTOK": 1,
"INS": 2,
"DM": 4,
"bluesky": 5,
}

View File

@ -612,7 +612,7 @@ func ImportMediaAccount(ctx *gin.Context) {
excelSetRemark(excelData, line, "艺人不存在")
continue
}
var tiktokName, insName, dmName string
var tiktokName, insName, dmName, youtubeName, blueskyName string
if len(row) >= 3 {
tiktokName = strings.TrimSpace(row[2])
}
@ -622,7 +622,13 @@ func ImportMediaAccount(ctx *gin.Context) {
if len(row) >= 5 {
dmName = strings.TrimSpace(row[4])
}
if tiktokName == "" && insName == "" && dmName == "" {
if len(row) >= 6 {
youtubeName = strings.TrimSpace(row[5])
}
if len(row) >= 7 {
blueskyName = strings.TrimSpace(row[6])
}
if tiktokName == "" && insName == "" && dmName == "" && youtubeName == "" && blueskyName == "" {
excelSetRemark(excelData, line, "请填写账号")
continue
}
@ -641,6 +647,16 @@ func ImportMediaAccount(ctx *gin.Context) {
excelSetRemark(excelData, line, fmt.Sprintf("%s:%s", dmName, err.Error()))
}
}
if youtubeName != "" {
if err = updateMediaAccount(youtubeName, cast.PlatformIDENUM_YOUTUBE, subInfoResp, loginInfo); err != nil {
excelSetRemark(excelData, line, fmt.Sprintf("%s:%s", youtubeName, err.Error()))
}
}
if blueskyName != "" {
if err = updateMediaAccount(blueskyName, cast.PlatformIDENUM_BULESKY, subInfoResp, loginInfo); err != nil {
excelSetRemark(excelData, line, fmt.Sprintf("%s:%s", blueskyName, err.Error()))
}
}
_ = CheckAsProfile(subInfoResp)
}
// 保存Excel文件到磁盘
@ -665,14 +681,14 @@ func ImportMediaAccount(ctx *gin.Context) {
// 记录需要删除的行(从后往前删除,避免行号变化)
rowsToDelete := make([]int, 0)
for line := 1; line < len(rows); line++ { // 从第2行开始跳过表头
remarkCell := fmt.Sprintf("F%d", line+1)
remarkCell := fmt.Sprintf("H%d", line+1) // 备注列已移动到H列
remark, _ := excelData.GetCellValue("Sheet1", remarkCell)
if remark == "" {
// F列没有数据,表示成功
// H列没有数据,表示成功
successCount++
rowsToDelete = append(rowsToDelete, line+1)
} else {
// F列有值,表示失败
// H列有值,表示失败
failCount++
}
}
@ -705,11 +721,11 @@ func ImportMediaAccount(ctx *gin.Context) {
func excelSetRemark(excelData *excelize.File, line int, remark string) {
zap.L().Info("设置备注", zap.Int("line", line), zap.String("remark", remark))
oldRemark, _ := excelData.GetCellValue("Sheet1", fmt.Sprintf("%s%d", "F", line+1))
oldRemark, _ := excelData.GetCellValue("Sheet1", fmt.Sprintf("%s%d", "H", line+1))
if oldRemark != "" {
remark = fmt.Sprintf("%s\n%s", oldRemark, remark)
}
excelData.SetCellValue("Sheet1", fmt.Sprintf("%s%d", "F", line+1), remark)
excelData.SetCellValue("Sheet1", fmt.Sprintf("%s%d", "H", line+1), remark)
}
func updateMediaAccount(platformName string, platformId cast.PlatformIDENUM, subInfoResp *accountFiee.UserInfoResponse, loginInfo login.Info) error {

View File

@ -48,21 +48,16 @@ import (
"go.uber.org/zap"
)
func UpdateWorkImage(ctx *gin.Context) {
var req *cast.UpdateWorkImageReq
// UpdateWorkImageCore 更新作品图片的核心逻辑,可以被其他函数复用
func UpdateWorkImageCore(ctx *gin.Context, req *cast.UpdateWorkImageReq) (*cast.UpdateWorkImageResp, error) {
var infoResp *accountFiee.UserInfoResponse
var err error
var ok bool
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
loginInfo := login.GetUserInfoFromC(ctx)
lockKey := fmt.Sprintf("lock_update_work_image_%d", loginInfo.ID)
reply := cache.RedisClient.SetNX(lockKey, time.Now().Format("2006-01-02 15:04:05"), time.Second*5)
if !reply.Val() {
service.Error(ctx, errors.New("请勿重复提交"))
return
return nil, errors.New("请勿重复提交")
}
defer func() {
cache.RedisClient.Del(lockKey)
@ -72,37 +67,30 @@ func UpdateWorkImage(ctx *gin.Context) {
/*for _, v := range req.Images {
ok, err = check.SecurityFile(v)
if err != nil {
service.Error(ctx, err)
return
return nil, err
}
if !ok {
service.Error(ctx, errors.New("图片鉴定未通过"))
return
return nil, errors.New("图片鉴定未通过")
}
}
ok, err = check.SecurityText(req.Title)
if err != nil {
service.Error(ctx, err)
return
return nil, err
}
if !ok {
service.Error(ctx, errors.New("标题鉴定未通过"))
return
return nil, errors.New("标题鉴定未通过")
}
ok, err = check.SecurityText(req.Content)
if err != nil {
service.Error(ctx, err)
return
return nil, err
}
if !ok {
service.Error(ctx, errors.New("内容鉴定未通过"))
return
return nil, errors.New("内容鉴定未通过")
}*/
if req.From != "ai" {
for _, v := range req.Images {
if filepath.Ext(v) != ".jpg" && filepath.Ext(v) != ".jpeg" {
service.Error(ctx, errors.New("图片格式只支持jpg"))
return
return nil, errors.New("图片格式只支持jpg")
}
}
}
@ -112,8 +100,7 @@ func UpdateWorkImage(ctx *gin.Context) {
for _, v := range images {
imageUrl, err = checkAndReuploadImage(v, "image")
if err != nil {
service.Error(ctx, errors.New("图片转换错误"))
return
return nil, errors.New("图片转换错误")
}
req.Images = append(req.Images, imageUrl)
}
@ -124,8 +111,7 @@ func UpdateWorkImage(ctx *gin.Context) {
})
zap.L().Info("UpdateWorkImage infoResp", zap.Any("infoResp", infoResp))
if err != nil {
service.Error(ctx, err)
return
return nil, err
}
req.ArtistName = infoResp.Name
@ -134,13 +120,26 @@ func UpdateWorkImage(ctx *gin.Context) {
req.ArtistSubNum = infoResp.SubNum
//artistID, _ := strconv.ParseUint(req.ArtistUuid, 10, 64)
//if _, err = CheckUserBundleBalance(int32(artistID), modelCast.BalanceTypeImageValue); err != nil {
// service.Error(ctx, err)
// return
// return nil, err
//}
newCtx := NewCtxWithUserInfo(ctx)
req.Source = 1
resp, err := service.CastProvider.UpdateWorkImage(newCtx, req)
zap.L().Info("UpdateWorkImage resp", zap.Any("resp", resp))
if err != nil {
return nil, err
}
return resp, nil
}
func UpdateWorkImage(ctx *gin.Context) {
var req *cast.UpdateWorkImageReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
resp, err := UpdateWorkImageCore(ctx, req)
if err != nil {
service.Error(ctx, err)
return
@ -171,27 +170,21 @@ func UpdateWorkImage(ctx *gin.Context) {
return
}
func UpdateWorkVideo(ctx *gin.Context) {
var req *cast.UpdateWorkVideoReq
// UpdateWorkVideoCore 更新作品视频的核心逻辑,可以被其他函数复用
func UpdateWorkVideoCore(ctx *gin.Context, req *cast.UpdateWorkVideoReq) (*cast.UpdateWorkVideoResp, error) {
var infoResp *accountFiee.UserInfoResponse
var err error
var ok bool
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
if req.CoverUrl != "" {
if filepath.Ext(req.CoverUrl) != ".jpg" && filepath.Ext(req.CoverUrl) != ".jpeg" {
service.Error(ctx, errors.New("图片格式只支持jpg"))
return
return nil, errors.New("图片格式只支持jpg")
}
}
loginInfo := login.GetUserInfoFromC(ctx)
lockKey := fmt.Sprintf("lock_update_work_video_%d", loginInfo.ID)
reply := cache.RedisClient.SetNX(lockKey, time.Now().Format("2006-01-02 15:04:05"), time.Second*5)
if !reply.Val() {
service.Error(ctx, errors.New("请勿重复提交"))
return
return nil, errors.New("请勿重复提交")
}
defer func() {
cache.RedisClient.Del(lockKey)
@ -199,30 +192,24 @@ func UpdateWorkVideo(ctx *gin.Context) {
fmt.Println(ok)
/* ok, err = check.SecurityText(req.Title)
if err != nil {
service.Error(ctx, err)
return
return nil, err
}
if !ok {
service.Error(ctx, errors.New("标题鉴定未通过"))
return
return nil, errors.New("标题鉴定未通过")
}
ok, err = check.SecurityText(req.Content)
if err != nil {
service.Error(ctx, err)
return
return nil, err
}
if !ok {
service.Error(ctx, errors.New("内容鉴定未通过"))
return
return nil, errors.New("内容鉴定未通过")
}
ok, err = check.SecurityFile(req.CoverUrl)
if err != nil {
service.Error(ctx, err)
return
return nil, err
}
if !ok {
service.Error(ctx, errors.New("图片鉴定未通过"))
return
return nil, errors.New("图片鉴定未通过")
}*/
if req.VideoUrl != "" && false {
//请求接口判断
@ -231,12 +218,10 @@ func UpdateWorkVideo(ctx *gin.Context) {
FileName: "",
})
if errs != nil {
service.Error(ctx, errs)
return
return nil, errs
}
if fileResp.SecurityStatus == "high" {
service.Error(ctx, errors.New("视频鉴定未通过"))
return
return nil, errors.New("视频鉴定未通过")
}
}
if config.AppConfig.System.AppMode != "dev" {
@ -247,8 +232,7 @@ func UpdateWorkVideo(ctx *gin.Context) {
})
zap.L().Info("UpdateWorkVideo", zap.Any("infoResp", infoResp))
if err != nil {
service.Error(ctx, err)
return
return nil, err
}
} else {
infoResp = &accountFiee.UserInfoResponse{
@ -259,8 +243,7 @@ func UpdateWorkVideo(ctx *gin.Context) {
}
//artistID, _ := strconv.ParseUint(req.ArtistUuid, 10, 64)
//if _, err = CheckUserBundleBalance(int32(artistID), modelCast.BalanceTypeVideoValue); err != nil {
// service.Error(ctx, err)
// return
// return nil, err
//}
req.ArtistName = infoResp.Name
req.ArtistPhone = infoResp.TelNum
@ -270,6 +253,20 @@ func UpdateWorkVideo(ctx *gin.Context) {
req.Source = 1
resp, err := service.CastProvider.UpdateWorkVideo(newCtx, req)
zap.L().Info("UpdateWorkVideo", zap.Any("resp", resp))
if err != nil {
return nil, err
}
return resp, nil
}
func UpdateWorkVideo(ctx *gin.Context) {
var req *cast.UpdateWorkVideoReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
resp, err := UpdateWorkVideoCore(ctx, req)
if err != nil {
service.Error(ctx, err)
return
@ -623,6 +620,29 @@ func PostAS(workUuid string) error {
ThumbNail: "",
Visibility: "",
}
case cast.PlatformIDENUM_YOUTUBE:
// YouTube 发布选项配置
postReq.YouTubeOptions = &aryshare.YouTubeOptions{
Title: workDetail.Title,
Visibility: "public", // 可见性设置public/unlisted/private
Tags: nil,
// CategoryId: 0, // YouTube 分类 ID例如24 = Entertainment
MadeForKids: false,
ThumbNail: coverUrl,
PlaylistId: "",
NotifySubscribers: true,
Shorts: false,
ContainsSyntheticMedia: false,
PublishAt: "",
SubTitleUrl: "",
SubTitleLanguage: "",
SubTitleName: "",
}
case cast.PlatformIDENUM_BULESKY: // BLUESKY
// Bluesky 发布选项配置
postReq.BlueskyOptions = &aryshare.BlueskyOptions{
AltText: nil, // 图片或视频的替代文本数组(用于屏幕阅读器的无障碍功能)
}
}
zap.L().Info("post 6", zap.Any("workUuid", workUuid), zap.Any("platformID", platformID))
zap.L().Info("Publish Ayrshare PostReq", zap.Any("workUuid", workDetail.WorkUuid), zap.Any("postReq", postReq), zap.Any("workDetail", workDetail))
@ -704,6 +724,10 @@ func PostAS(workUuid string) error {
pid = 1
case "instagram":
pid = 3
case "youtube":
pid = 2
case "bluesky":
pid = 5
}
publishStatus := cast.PublishStatusENUM_PublishMediaStatus_NO
if postInfo.Status == "success" {
@ -1284,8 +1308,8 @@ func ImportWorkBatch(ctx *gin.Context) {
temp.ArtistPhone = subInfoResp.TelNum
temp.ArtistPhoneAreaCode = subInfoResp.TelAreaCode
}
if len(row) > 5 {
temp.Title = utils.CleanString(row[5])
if len(row) > 7 {
temp.Title = utils.CleanString(row[7])
ok, _err := check.SecurityText(temp.Title)
if _err != nil {
temp.Remark = _err.Error()
@ -1298,8 +1322,8 @@ func ImportWorkBatch(ctx *gin.Context) {
break
}
}
if len(row) > 6 {
temp.Content = utils.CleanString(row[6])
if len(row) > 8 {
temp.Content = utils.CleanString(row[8])
if temp.Content != "" {
ok, _err := check.SecurityText(temp.Content)
if _err != nil {
@ -1314,8 +1338,7 @@ func ImportWorkBatch(ctx *gin.Context) {
}
}
}
// 图片
for i := 8; i <= 18; i++ {
for i := 10; i <= 20; i++ {
if len(row) > i {
if utils.CleanString(row[i]) != "" {
ok, _err := check.SecurityFile(row[i])
@ -1325,7 +1348,7 @@ func ImportWorkBatch(ctx *gin.Context) {
break
}
if !ok {
temp.Remark = fmt.Sprintf("图片%d黄反审核未通过", i-7)
temp.Remark = fmt.Sprintf("图片%d黄反审核未通过", i-9)
req.ImageWorks = append(req.ImageWorks, temp)
break
}
@ -1416,6 +1439,60 @@ func ImportWorkBatch(ctx *gin.Context) {
temp.MediaAccountNames = append(temp.MediaAccountNames, utils.CleanString(row[4]))
temp.MediaAccountUuids = append(temp.MediaAccountUuids, mediaInfoResp.Info.MediaAccountUuid)*/
}
// YouTube账号第F列row[5]
if len(row) > 5 && utils.CleanString(row[5]) != "" {
temp.Remark = fmt.Sprintf("Youtube不能发图文")
zap.L().Error("CastProvider.MediaInfo", zap.Error(err))
req.ImageWorks = append(req.ImageWorks, temp)
continue
// mediaInfoResp, err = service.CastProvider.MediaInfo(context.Background(), &cast.MediaInfoReq{
// ArtistUuid: temp.ArtistUuid,
// PlatformID: cast.PlatformIDENUM_YOUTUBE,
// PlatformUserName: utils.CleanString(row[5]),
// })
// if err != nil || mediaInfoResp.Info.MediaAccountUuid == "" {
// temp.Remark = fmt.Sprintf("YouTube账号名不存在")
// zap.L().Error("CastProvider.MediaInfo", zap.Error(err))
// req.ImageWorks = append(req.ImageWorks, temp)
// continue
// }
// temp.PublishConfig1 = &cast.PublishConfig{
// ForbidComment: 1,
// PublicType: 1,
// CanJoin: 1,
// CanQuote: 1,
// CanComment: 1,
// IsAI: 1,
// }
// temp.PlatformIDs = append(temp.PlatformIDs, cast.PlatformIDENUM_YOUTUBE)
// temp.MediaAccountNames = append(temp.MediaAccountNames, utils.CleanString(row[5]))
// temp.MediaAccountUuids = append(temp.MediaAccountUuids, mediaInfoResp.Info.MediaAccountUuid)
}
// Bluesky账号第G列row[6]
if len(row) > 6 && utils.CleanString(row[6]) != "" {
mediaInfoResp, err = service.CastProvider.MediaInfo(context.Background(), &cast.MediaInfoReq{
ArtistUuid: temp.ArtistUuid,
PlatformID: cast.PlatformIDENUM_BULESKY,
PlatformUserName: utils.CleanString(row[6]),
})
if err != nil || mediaInfoResp.Info.MediaAccountUuid == "" {
temp.Remark = fmt.Sprintf("Bluesky账号名不存在")
zap.L().Error("CastProvider.MediaInfo", zap.Error(err))
req.ImageWorks = append(req.ImageWorks, temp)
continue
}
temp.PublishConfig1 = &cast.PublishConfig{
ForbidComment: 1,
PublicType: 1,
CanJoin: 1,
CanQuote: 1,
CanComment: 1,
IsAI: 1,
}
temp.PlatformIDs = append(temp.PlatformIDs, cast.PlatformIDENUM_BULESKY)
temp.MediaAccountNames = append(temp.MediaAccountNames, utils.CleanString(row[6]))
temp.MediaAccountUuids = append(temp.MediaAccountUuids, mediaInfoResp.Info.MediaAccountUuid)
}
if artistNum == "" {
temp.Remark = "艺人编号不能为空"
req.ImageWorks = append(req.ImageWorks, temp)
@ -1446,6 +1523,12 @@ func ImportWorkBatch(ctx *gin.Context) {
req.ImageWorks = append(req.ImageWorks, temp)
continue
}
// 判断图片数量是否超过4
if len(temp.Images) > 4 {
temp.Remark = "Bluesky 图片数量不能超过4"
req.ImageWorks = append(req.ImageWorks, temp)
continue
}
req.ImageWorks = append(req.ImageWorks, temp)
}
if len(req.ImageWorks) == 0 {
@ -1464,7 +1547,7 @@ func ImportWorkBatch(ctx *gin.Context) {
for _, v := range resp.ImageWorks {
if !v.Success {
rowNum := int(v.LineNo) + 1
excelData.SetCellValue("Sheet1", fmt.Sprintf("H%d", rowNum), v.Remark)
excelData.SetCellValue("Sheet1", fmt.Sprintf("J%d", rowNum), v.Remark)
hasValueRows[rowNum] = true
}
}

View File

@ -376,6 +376,11 @@ func UpdateWorkImageWithTaskUUID(ctx *gin.Context) {
service.Error(ctx, errors.New("任务已中止,不能上传图文"))
return
}
resp, err := castService.UpdateWorkImageCore(ctx, req.UpdateWorkImageReq)
if err != nil {
service.Error(ctx, err)
return
}
if config.AppConfig.System.AppMode != "dev" {
artistId, _ := strconv.ParseUint(req.ArtistUuid, 10, 64)
infoResp, err = service.AccountFieeProvider.Info(context.Background(), &accountFiee.InfoRequest{
@ -393,21 +398,6 @@ func UpdateWorkImageWithTaskUUID(ctx *gin.Context) {
TelAreaCode: "86",
}
}
req.ArtistName = infoResp.Name
req.ArtistPhone = infoResp.TelNum
req.ArtistPhoneAreaCode = infoResp.TelAreaCode
// artistID, _ := strconv.ParseUint(req.ArtistUuid, 10, 64)
// if _, err = castService.CheckUserBundleBalance(int32(artistID), modelCast.BalanceTypeImageValue); err != nil {
// service.Error(ctx, err)
// return
// }
newCtx := castService.NewCtxWithUserInfo(ctx)
req.Source = 1
resp, err := service.CastProvider.UpdateWorkImage(newCtx, req.UpdateWorkImageReq)
if err != nil {
service.Error(ctx, err)
return
}
// EmployeeName 和 EmployeeNum 从 toekn 里面拿
userInfo := login.GetUserInfoFromC(ctx)
// 调用员工实际任务状态更新
@ -474,6 +464,11 @@ func UpdateWorkVideoWithUUID(ctx *gin.Context) {
service.Error(ctx, errors.New("任务已中止,不能上传视频"))
return
}
resp, err := castService.UpdateWorkVideoCore(ctx, req.UpdateWorkVideoReq)
if err != nil {
service.Error(ctx, err)
return
}
if config.AppConfig.System.AppMode != "dev" {
artistId, _ := strconv.ParseUint(req.ArtistUuid, 10, 64)
infoResp, err = service.AccountFieeProvider.Info(context.Background(), &accountFiee.InfoRequest{
@ -491,21 +486,6 @@ func UpdateWorkVideoWithUUID(ctx *gin.Context) {
TelAreaCode: "86",
}
}
// artistID, _ := strconv.ParseUint(req.ArtistUuid, 10, 64)
// if _, err = castService.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 := castService.NewCtxWithUserInfo(ctx)
req.Source = 1
resp, err := service.CastProvider.UpdateWorkVideo(newCtx, req.UpdateWorkVideoReq)
if err != nil {
service.Error(ctx, err)
return
}
// EmployeeName 和 EmployeeNum 从 toekn 里面拿
userInfo := login.GetUserInfoFromC(ctx)
// 调用员工实际任务状态更新