This commit is contained in:
戴育兵 2025-12-19 20:08:11 +08:00
parent 6b2c201bc1
commit 0e5cb8a5ff

View File

@ -12,6 +12,7 @@ import (
"fonchain-fiee/cmd/config"
"fonchain-fiee/pkg/e"
modelCast "fonchain-fiee/pkg/model/cast"
"fonchain-fiee/pkg/model/login"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/utils"
"net/http"
@ -522,330 +523,128 @@ func SyncAsProfile(ctx *gin.Context) {
// ImportMediaAccount 导入自媒体账号
func ImportMediaAccount(ctx *gin.Context) {
var failedRecords []FailedRecord
var successRecords []SuccessRecord
// 1. 接收上传的Excel文件
excelFile, err := ctx.FormFile("file")
if err != nil {
service.Error(ctx, errors.New("缺少Excel文件"))
service.Error(ctx, err)
return
}
// 2. 保存临时文件
tempDir := "./runtime/media"
_, err = utils.CheckDirPath(tempDir, true)
if err != nil {
service.Error(ctx, err)
return
}
fileName := fmt.Sprintf("%d_media_account.xlsx", time.Now().UnixMicro())
excelPath := filepath.Join(tempDir, fileName)
if err = ctx.SaveUploadedFile(excelFile, excelPath); err != nil {
service.Error(ctx, err)
return
}
// 3. 读取Excel数据
mediaAccounts, err := readMediaAccountExcel(excelPath)
excelData, err := excelize.OpenFile(excelPath)
if err != nil {
service.Error(ctx, fmt.Errorf("读取Excel失败: %w", err))
service.Error(ctx, err)
return
}
if len(mediaAccounts) == 0 {
service.Error(ctx, errors.New("Excel中没有有效数据"))
defer excelData.Close()
rows, err := excelData.GetRows("Sheet1")
if err != nil {
service.Error(ctx, err)
return
}
// 4. 处理每个账号
for _, account := range mediaAccounts {
for platformID, accountInfo := range account.Account {
// 跳过空账号信息
if accountInfo.AccountId == "" && accountInfo.NickName == "" {
continue
loginInfo := login.GetUserInfoFromC(ctx)
for line, row := range rows {
if line == 0 {
continue
}
if len(row) < 3 {
continue
}
subNum := strings.TrimSpace(row[1])
if subNum == "" {
continue
}
var subInfoResp *accountFiee.UserInfoResponse
//查询艺人信息
if config.AppConfig.System.AppMode == "dev" {
subInfoResp = &accountFiee.UserInfoResponse{
Id: 0,
SubNum: "",
}
// 查询用户信息
res, err := service.AccountFieeProvider.UserList(context.Background(), &accountFiee.UserListRequest{
Name: account.Name,
SubNum: account.SubNum,
})
if err != nil {
failedRecords = append(failedRecords, FailedRecord{
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
Msg: fmt.Sprintf("获取用户信息失败: %s", err.Error()),
})
continue
}
if res.Count == 0 {
failedRecords = append(failedRecords, FailedRecord{
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
Msg: "未找到用户信息",
})
continue
}
// 获取用户详细信息
var infoResp *accountFiee.UserInfoResponse
infoResp, err = GetArtistAccountInfo(res.UserList[0].Id)
if err != nil {
failedRecords = append(failedRecords, FailedRecord{
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
Msg: fmt.Sprintf("查询用户详细信息失败: %s", err.Error()),
})
continue
}
if infoResp.SubNum == "" {
failedRecords = append(failedRecords, FailedRecord{
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
Msg: "用户不存在",
})
continue
}
// 检查并创建AS Profile
if err = CheckAsProfile(infoResp); err != nil {
failedRecords = append(failedRecords, FailedRecord{
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
Msg: fmt.Sprintf("创建AS Profile失败: %s", err.Error()),
})
continue
}
// 验证平台ID
if _, ok := cast.PlatformIDENUM_name[int32(platformID)]; !ok {
failedRecords = append(failedRecords, FailedRecord{
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
Msg: "无效的平台ID",
})
continue
}
artistUuid := strconv.FormatUint(res.UserList[0].Id, 10)
userID := int32(res.UserList[0].Id)
// 查询该艺人是否已存在该平台账号
userResp, err := service.CastProvider.MediaUserList(context.Background(), &cast.MediaUserListReq{
ArtistUuid: artistUuid,
Page: 1,
PageSize: 100,
})
if err != nil {
failedRecords = append(failedRecords, FailedRecord{
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
Msg: fmt.Sprintf("查询已有账号失败: %s", err.Error()),
})
continue
}
// 检查是否已经存在该平台的账号
accountExists := false
if userResp != nil && len(userResp.Data) > 0 {
for _, v := range userResp.Data {
if v.PlatformID == uint32(platformID) {
accountExists = true
break
}
}
}
if accountExists {
failedRecords = append(failedRecords, FailedRecord{
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
Msg: "该平台账号已存在",
})
continue
}
// 检查并消耗账户余额
if _, err = CheckUserBundleBalance(userID, modelCast.BalanceTypeAccountValue); err != nil {
failedRecords = append(failedRecords, FailedRecord{
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
Msg: fmt.Sprintf("账户余额不足: %s", err.Error()),
})
continue
}
// 增加账户消耗数量
_, err = service.BundleProvider.AddBundleBalance(context.Background(), &bundle.AddBundleBalanceReq{
UserId: userID,
AccountConsumptionNumber: 1,
})
if err != nil {
failedRecords = append(failedRecords, FailedRecord{
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
Msg: fmt.Sprintf("扣除账户余额失败: %s", err.Error()),
})
continue
}
// 创建自媒体账号
mediaAccountResp, err := service.CastProvider.UpdateMediaAccount(ctx, &cast.UpdateMediaAccountReq{
ArtistUuid: artistUuid,
PlatformID: platformID,
PlatformUserName: accountInfo.NickName,
PlatformUserID: accountInfo.AccountId,
ArtistName: infoResp.Name,
ArtistPhone: infoResp.TelNum,
ArtistPhoneAreaCode: infoResp.TelAreaCode,
ArtistSubNum: infoResp.SubNum,
})
if err != nil {
// 创建失败,回退余额
_, _ = service.BundleProvider.AddBundleBalance(context.Background(), &bundle.AddBundleBalanceReq{
UserId: userID,
AccountConsumptionNumber: -1,
})
failedRecords = append(failedRecords, FailedRecord{
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
Msg: fmt.Sprintf("创建账号失败: %s", err.Error()),
})
continue
}
// 记录成功
successRecords = append(successRecords, SuccessRecord{
MediaAccountUuid: mediaAccountResp.MediaAccountUuid,
Name: account.Name,
SubNum: account.SubNum,
Platform: modelCast.PlatformNameKv[uint32(platformID)],
PlatformUserName: accountInfo.NickName,
PlatformUserID: accountInfo.AccountId,
} else {
subInfoResp, err = service.AccountFieeProvider.SubNumGetInfo(context.Background(), &accountFiee.SubNumGetInfoRequest{
SubNum: subNum,
Domain: "app",
})
}
}
// 5. 返回结果
if err != nil {
excelSetRemark(excelData, line, "查询艺人出错")
continue
}
if subInfoResp.Id == 0 {
excelSetRemark(excelData, line, "艺人不存在")
continue
}
var tiktokName, insName, dmName string
if len(row) >= 3 {
tiktokName = strings.TrimSpace(row[2])
}
if len(row) >= 4 {
insName = strings.TrimSpace(row[3])
}
if len(row) >= 5 {
dmName = strings.TrimSpace(row[4])
}
if tiktokName == "" && insName == "" && dmName == "" {
excelSetRemark(excelData, line, "请填写账号")
continue
}
if tiktokName != "" {
if err = updateMediaAccount(tiktokName, cast.PlatformIDENUM_TIKTOK, subInfoResp, loginInfo); err != nil {
excelSetRemark(excelData, line, err.Error())
}
}
if insName != "" {
if err = updateMediaAccount(tiktokName, cast.PlatformIDENUM_INS, subInfoResp, loginInfo); err != nil {
excelSetRemark(excelData, line, err.Error())
}
}
if dmName != "" {
if err = updateMediaAccount(tiktokName, cast.PlatformIDENUM_DM, subInfoResp, loginInfo); err != nil {
excelSetRemark(excelData, line, err.Error())
}
}
}
urlHost := config.AppConfig.System.FieeHost
urlResult := fmt.Sprintf("%s/api/fiee/static/media/%s", urlHost, fileName)
service.Success(ctx, map[string]interface{}{
"successCount": len(successRecords),
"failedCount": len(failedRecords),
"successRecords": successRecords,
"failedRecords": failedRecords,
"successCount": 0,
"failCount": 0,
"url": urlResult,
})
return
}
// readMediaAccountExcel 读取自媒体账号Excel文件
func readMediaAccountExcel(excelPath string) ([]MediaAccountImport, error) {
f, err := excelize.OpenFile(excelPath)
if err != nil {
return nil, err
func excelSetRemark(excelData *excelize.File, line int, remark string) {
oldRemark, _ := excelData.GetCellValue("Sheet1", fmt.Sprintf("%s%d", "F", line+1))
if oldRemark != "" {
remark = fmt.Sprintf("%s\n%s", oldRemark, remark)
}
defer f.Close()
sheetName := f.GetSheetName(0)
rows, err := f.GetRows(sheetName)
if err != nil {
return nil, err
}
var accounts []MediaAccountImport
for i, row := range rows {
// 跳过表头
if i == 0 || len(row) < 3 {
continue
}
// 获取基本信息
index := strings.TrimSpace(row[0])
name := strings.TrimSpace(row[1])
subNum := strings.TrimSpace(row[2])
if name == "" && subNum == "" {
continue
}
tmp := MediaAccountImport{
Index: index,
Name: name,
SubNum: subNum,
Account: make(map[cast.PlatformIDENUM]AccountInfo),
}
// 读取TikTok账号信息 (列D, E)
tiktokId, _ := f.GetCellValue(sheetName, fmt.Sprintf("D%d", i+1))
tiktokNickName, _ := f.GetCellValue(sheetName, fmt.Sprintf("E%d", i+1))
tmp.Account[cast.PlatformIDENUM_TIKTOK] = AccountInfo{
AccountId: strings.TrimSpace(tiktokId),
NickName: strings.TrimSpace(tiktokNickName),
}
// 读取YouTube账号信息 (列F, G)
youtubeId, _ := f.GetCellValue(sheetName, fmt.Sprintf("F%d", i+1))
youtubeNickName, _ := f.GetCellValue(sheetName, fmt.Sprintf("G%d", i+1))
tmp.Account[cast.PlatformIDENUM_YOUTUBE] = AccountInfo{
AccountId: strings.TrimSpace(youtubeId),
NickName: strings.TrimSpace(youtubeNickName),
}
// 读取Instagram账号信息 (列H, I)
insId, _ := f.GetCellValue(sheetName, fmt.Sprintf("H%d", i+1))
insNickName, _ := f.GetCellValue(sheetName, fmt.Sprintf("I%d", i+1))
tmp.Account[cast.PlatformIDENUM_INS] = AccountInfo{
AccountId: strings.TrimSpace(insId),
NickName: strings.TrimSpace(insNickName),
}
accounts = append(accounts, tmp)
}
return accounts, nil
excelData.SetCellValue("Sheet1", fmt.Sprintf("%s%d", "F", line+1), remark)
}
// MediaAccountImport 自媒体账号导入结构
type MediaAccountImport struct {
Index string `json:"index"`
Name string `json:"name"`
SubNum string `json:"subNum"`
Account map[cast.PlatformIDENUM]AccountInfo `json:"account"`
}
// AccountInfo 账号信息
type AccountInfo struct {
NickName string `json:"nickName"`
AccountId string `json:"accountId"`
}
// FailedRecord 失败记录
type FailedRecord struct {
Name string `json:"name"`
SubNum string `json:"subNum"`
Platform string `json:"platform"`
Msg string `json:"msg"`
}
// SuccessRecord 成功记录
type SuccessRecord struct {
MediaAccountUuid string `json:"mediaAccountUuid"`
Name string `json:"name"`
SubNum string `json:"subNum"`
Platform string `json:"platform"`
PlatformUserName string `json:"platformUserName"`
PlatformUserID string `json:"platformUserID"`
func updateMediaAccount(platformName string, platformId cast.PlatformIDENUM, subInfoResp *accountFiee.UserInfoResponse, loginInfo login.Info) error {
_, err := service.CastProvider.UpdateMediaAccount(context.Background(), &cast.UpdateMediaAccountReq{
PlatformID: platformId,
PlatformUserName: platformName,
PlatformUserID: "",
ArtistUuid: fmt.Sprint(subInfoResp.Id),
ArtistName: subInfoResp.Name,
ArtistPhone: subInfoResp.TelNum,
MediaAccountUuid: "",
ManagerUuid: fmt.Sprint(loginInfo.ID),
ManagerUserName: loginInfo.Name,
ArtistSubNum: subInfoResp.SubNum,
})
return err
}