fonchain-fiee/pkg/service/cast/report.go
2026-01-12 18:34:56 +08:00

473 lines
13 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package cast
import (
"context"
"fmt"
"fonchain-fiee/api/bundle"
"fonchain-fiee/api/cast"
"fonchain-fiee/pkg/cache"
modelCast "fonchain-fiee/pkg/model/cast"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/utils"
"strconv"
"time"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// CreateCompetitiveReport 创建竞品报告
func CreateCompetitiveReport(ctx *gin.Context) {
var req *cast.CreateCompetitiveReportReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.CreateCompetitiveReport(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
return
}
// ImportCompetitiveReportBatch 批量导入竞品报告
func ImportCompetitiveReportBatch(ctx *gin.Context) {
var req *cast.ImportCompetitiveReportBatchReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.ImportCompetitiveReportBatch(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
return
}
// UpdateCompetitiveReportStatus 更新竞品报告状态
func UpdateCompetitiveReportStatus(ctx *gin.Context) {
var req *cast.UpdateCompetitiveReportStatusReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
_, err = service.CastProvider.UpdateCompetitiveReportStatus(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, nil)
return
}
// GetCompetitiveReport 获取竞品报告详情
func GetCompetitiveReport(ctx *gin.Context) {
var req *cast.GetCompetitiveReportDetailReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.GetCompetitiveReport(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
return
}
// GetCompetitiveReportForApp 获取竞品报告详情App端
func GetCompetitiveReportForApp(ctx *gin.Context) {
var req *cast.GetCompetitiveReportForAppReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.GetCompetitiveReportForApp(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
return
}
// ListCompetitiveReport 获取竞品报告列表
func ListCompetitiveReport(ctx *gin.Context) {
var req *cast.ListCompetitiveReportReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.ListCompetitiveReport(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
RefreshCompetitiveReportApproval(ctx, resp.Data)
service.Success(ctx, resp)
return
}
// DeleteCompetitiveReport 删除竞品报告
func DeleteCompetitiveReport(ctx *gin.Context) {
var req *cast.DeleteCompetitiveReportReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
_, err = service.CastProvider.DeleteCompetitiveReport(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, nil)
return
}
// UpdateCompetitiveReportApprovalID 更新竞品报告审批ID
func UpdateCompetitiveReportApprovalID(ctx *gin.Context) {
var req *cast.UpdateCompetitiveReportApprovalIDReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
_, err = service.CastProvider.UpdateCompetitiveReportApprovalID(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, nil)
return
}
// CountCompetitiveReportByWorkUuids 根据作品UUID统计竞品报告数量
func CountCompetitiveReportByWorkUuids(ctx *gin.Context) {
var req *cast.CountCompetitiveReportByWorkUuidsReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.CountCompetitiveReportByWorkUuids(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
service.Success(ctx, resp)
return
}
// getCompetitiveReportStatusText 获取竞品报告状态文本
func getCompetitiveReportStatusText(status uint32) string {
switch status {
case 1:
return "待提交"
case 2:
return "审批中"
case 3:
return "审批驳回"
case 4:
return "待艺人验收"
case 5:
return "验收失败"
case 6:
return "待阅读"
case 7:
return "已阅读"
default:
return ""
}
}
// ListCompetitiveReportExport 获取竞品报告列表并导出Excel
func ListCompetitiveReportExport(ctx *gin.Context) {
var req *cast.ListCompetitiveReportReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
req.Page = 1
req.PageSize = 999999999
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.ListCompetitiveReport(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
titleList := []string{
"标题", "艺人", "用户编号", "手机号", "状态", "验收确认类型", "原因", "状态变更时间", "提交时间", "操作人", "pdf链接",
}
var dataList []interface{}
for _, i := range resp.Data {
data := []any{
i.Title,
i.ArtistName,
i.SubNum,
i.ArtistPhone,
getCompetitiveReportStatusText(i.WorkReportStatus),
getComfirmTypeText(i.ComfirmType),
i.Reason,
i.StatusUpdateTime,
i.SubmitTime,
i.OperatorName,
i.PdfUrl,
}
dataList = append(dataList, &data)
}
content, err := utils.ToExcelByType(titleList, dataList, "slice", "")
if err != nil {
service.Error(ctx, err)
return
}
utils.ResponseXls(ctx, content, "竞品报告列表")
return
}
// ListCompetitiveReportSingleExport 获取竞品报告列表并导出Excel单个列表
func ListCompetitiveReportSingleExport(ctx *gin.Context) {
var req *cast.ListCompetitiveReportReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
req.Page = 1
req.PageSize = 999999999
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.ListCompetitiveReport(newCtx, req)
if err != nil {
service.Error(ctx, err)
return
}
titleList := []string{
"标题", "状态", "验收确认类型", "原因", "状态变更时间", "操作人", "提交时间", "pdf链接",
}
var dataList []interface{}
for _, i := range resp.Data {
data := []any{
i.Title,
getCompetitiveReportStatusText(i.WorkReportStatus),
getComfirmTypeText(i.ComfirmType),
i.Reason,
i.StatusUpdateTime,
i.OperatorName,
i.SubmitTime,
i.PdfUrl,
}
dataList = append(dataList, &data)
}
content, err := utils.ToExcelByType(titleList, dataList, "slice", "")
if err != nil {
service.Error(ctx, err)
return
}
utils.ResponseXls(ctx, content, "竞品报告列表")
return
}
// RefreshCompetitiveReportApproval 刷新竞品报告审批状态
func RefreshCompetitiveReportApproval(ctx *gin.Context, data []*cast.CompetitiveReportInfo) {
if len(data) > 0 {
var reportUuidApprovalIDMap = make(map[int]string)
for _, v := range data {
// 状态为2表示待审批需要获取详情来获取ApprovalID
if v.WorkReportStatus == 2 && v.ApprovalID != "" {
zap.L().Info("RefreshCompetitiveReportApproval", zap.Any("approvalID", v.ApprovalID))
approvalID, _ := strconv.ParseUint(v.ApprovalID, 10, 64)
reportUuidApprovalIDMap[int(approvalID)] = v.Uuid
}
}
if len(reportUuidApprovalIDMap) > 0 {
_ = RefreshCompetitiveReportApprovalStatus(ctx, reportUuidApprovalIDMap)
}
}
}
// RefreshCompetitiveReportApprovalStatus 刷新竞品报告审批状态详情
func RefreshCompetitiveReportApprovalStatus(ctx *gin.Context, approvalIDReportUuidMap map[int]string) (err error) {
var castS = new(CastService)
var data = make(map[int]modelCast.Item)
var approvalIDs []int
for approvalId := range approvalIDReportUuidMap {
approvalIDs = append(approvalIDs, approvalId)
}
if len(approvalIDs) == 0 {
return
}
data, err = castS.ApprovalDetail(approvalIDs)
if err != nil {
return
}
// 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.UpdateCompetitiveReportStatus(newCtx, &cast.UpdateCompetitiveReportStatusReq{
WorkAction: cast.WorkActionENUM_APPROVAL_DELETE,
Uuid: approvalIDReportUuidMap[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.UpdateCompetitiveReportStatus(newCtx, &cast.UpdateCompetitiveReportStatusReq{
WorkAction: workAction,
Uuid: approvalIDReportUuidMap[approvalId],
ApprovalID: fmt.Sprint(approvalId),
ApprovalReply: v.Reply,
})
}
}
return
}
// ProcessReportTask 处理竞品报告自动确认任务
func ProcessReportTask(ctx context.Context, reportUuid string) {
lockKey := fmt.Sprintf(modelCast.AutoConfirmReportLockKey, reportUuid)
reply := cache.RedisClient.SetNX(lockKey, "1", 5*time.Minute)
if !reply.Val() {
zap.L().Warn("竞品报告任务正在被其他实例处理", zap.String("reportUuid", reportUuid))
return
}
defer func() {
cache.RedisClient.Del(lockKey)
}()
err := autoConfirmReport(ctx, reportUuid)
if err != nil {
zap.L().Error("竞品报告自动确认失败",
zap.String("reportUuid", reportUuid),
zap.Error(err))
return
}
// 从队列中移除
err = cache.RedisClient.ZRem(modelCast.AutoConfirmReportQueueKey, reportUuid).Err()
if err != nil {
zap.L().Error("从队列移除竞品报告任务失败",
zap.String("reportUuid", reportUuid),
zap.Error(err))
}
zap.L().Info("竞品报告自动确认成功", zap.String("reportUuid", reportUuid))
}
// autoConfirmReport 自动确认竞品报告
func autoConfirmReport(ctx context.Context, reportUuid string) (err error) {
var confirmRemark string
var isFailed bool
var usedType uint32
infoResp, err := service.CastProvider.GetCompetitiveReport(context.Background(), &cast.GetCompetitiveReportDetailReq{
Uuid: reportUuid,
})
if err != nil {
zap.L().Error("autoConfirmReport GetCompetitiveReport", zap.Any("err", err))
confirmRemark = "获取竞品报告详情失败:" + err.Error()
isFailed = true
return
}
if infoResp == nil {
zap.L().Error("autoConfirmReport GetCompetitiveReport返回nil")
return
}
if infoResp.WorkReportStatus != 4 { // 4是待确认状态
return
}
userID, _ := strconv.ParseInt(infoResp.ArtistID, 10, 64)
balanceInfoRes, err := service.BundleProvider.GetBundleBalanceByUserId(context.Background(), &bundle.GetBundleBalanceByUserIdReq{
UserId: int32(userID),
})
if err != nil {
zap.L().Error("autoConfirmReport GetBundleBalanceByUserId", zap.Any("err", err))
confirmRemark = "获取余额失败:" + err.Error()
isFailed = true
}
var addBalanceReq bundle.AddBundleBalanceReq
addBalanceReq.UserId = int32(userID)
// 检查数据分析余量
if balanceInfoRes.DataAnalysisExtendConsumptionNumber >= balanceInfoRes.DataAnalysisExtendNumber {
confirmRemark = "数据分析余量不足"
isFailed = true
}
addBalanceReq.DataAnalysisConsumptionNumber = 1
zap.L().Info("autoConfirmReport AddBundleBalanceReq", zap.Any("addBalanceReq", &addBalanceReq))
resp, err := service.BundleProvider.AddBundleBalance(context.Background(), &addBalanceReq)
if err != nil {
zap.L().Error("autoConfirmReport AddBundleBalance", zap.Any("err", err))
confirmRemark = "扣除失败:" + err.Error()
isFailed = true
}
zap.L().Info("autoConfirmReport AddBundleBalanceResp", zap.Any("resp", resp))
var confirmStatus uint32 = 1
if isFailed {
usedType = 0
confirmStatus = 3
} else {
usedType = resp.UsedType
confirmRemark = "系统自动确认"
confirmStatus = 1
}
var mm = make(map[string]interface{}, 3)
mm["userid"] = 0
mm["name"] = "系统自动确定"
mm["phone"] = ""
newCtx := context.WithValue(context.Background(), constant.DubboCtxKey("attachment"), mm)
_, err = service.CastProvider.UpdateCompetitiveReportStatus(newCtx, &cast.UpdateCompetitiveReportStatusReq{
WorkAction: cast.WorkActionENUM_CONFIRM,
Uuid: reportUuid,
ConfirmRemark: confirmRemark,
CostType: usedType,
ConfirmStatus: confirmStatus,
ConfirmType: 2,
})
if err != nil {
return
}
return
}