fonchain-fiee/pkg/service/cast/report.go

794 lines
22 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"
"errors"
"fmt"
"fonchain-fiee/api/accountFiee"
"fonchain-fiee/api/bundle"
"fonchain-fiee/api/cast"
"fonchain-fiee/cmd/config"
"fonchain-fiee/pkg/cache"
"fonchain-fiee/pkg/e"
modelCast "fonchain-fiee/pkg/model/cast"
"fonchain-fiee/pkg/model/login"
"fonchain-fiee/pkg/service"
"fonchain-fiee/pkg/service/upload"
"fonchain-fiee/pkg/utils"
"path/filepath"
"strconv"
"time"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"github.com/gin-gonic/gin"
"github.com/xuri/excelize/v2"
"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)
artistID, _ := strconv.ParseUint(req.ArtistID, 10, 64)
// 通过接口查询艺人信息,自动填充艺人名字、手机号等信息
var infoResp *accountFiee.UserInfoResponse
if config.AppConfig.System.AppMode != "dev" {
infoResp, err = service.AccountFieeProvider.Info(context.Background(), &accountFiee.InfoRequest{
ID: artistID,
Domain: "app",
})
zap.L().Info("CreateCompetitiveReport", zap.Any("infoResp", infoResp))
if err != nil {
service.Error(ctx, err)
return
}
} else {
infoResp = &accountFiee.UserInfoResponse{
Name: "小波",
TelNum: "18288888888",
SubNum: "FE00000",
}
}
// 填充艺人信息到请求中
req.ArtistName = infoResp.Name
req.ArtistPhone = infoResp.TelNum
req.SubNum = infoResp.SubNum
req.Source = 1
if _, err = CheckUserBundleBalance(int32(artistID), modelCast.BalanceTypeCompetitiveValue); err != nil {
if err != nil && err.Error() == e.ErrorBalanceInsufficient {
service.Error(ctx, errors.New("该艺人竞品报告可用次数为0"))
return
}
service.Error(ctx, err)
return
}
if req.ReportContent != "" && req.ImageUrl != "" {
err = errors.New("报告内容和图片不能同时为空")
service.Error(ctx, err)
return
}
// 如果提供了报告内容和图片URL则生成PDF并上传
if req.ReportContent != "" {
// 生成临时PDF文件路径
pdfFileName := fmt.Sprintf("competitive_report_%s_%d.pdf", req.ArtistID, time.Now().UnixMicro())
pdfFilePath := "./runtime/report_pdf/" + pdfFileName
// 确保目录存在
_, err = utils.CheckDirPath("./runtime/report_pdf/", true)
if err != nil {
service.Error(ctx, fmt.Errorf("创建PDF目录失败: %v", err))
return
}
// 生成PDF文件
fontPath := "./data/simfang.ttf"
err = utils.GeneratePDF(req.ReportContent, req.ImageUrl, pdfFilePath, fontPath)
if err != nil {
fmt.Println("生成PDF失败", err)
zap.L().Error("生成PDF失败", zap.Error(err))
service.Error(ctx, errors.New("生成PDF失败"))
return
}
fmt.Println("生成PDF成功", pdfFilePath)
// 上传PDF到OSS
pdfUrl, uploadErr := upload.PutBos(pdfFilePath, upload.PdfType, true)
if uploadErr != nil {
zap.L().Error("上传PDF失败: %v", zap.Error(uploadErr))
service.Error(ctx, errors.New("上传PDF失败"))
return
}
// 将上传后的PDF链接设置到请求中
req.PdfUrl = pdfUrl
} else {
req.PdfUrl = req.ImageUrl
}
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) {
// 获取上传的Excel文件
excelFile, err := ctx.FormFile("file")
if err != nil {
service.Error(ctx, err)
return
}
loginInfo := login.GetUserInfoFromC(ctx)
lockKey := fmt.Sprintf("import_competitive_report_batch:%d", loginInfo.ID)
replay := cache.RedisClient.SetNX(lockKey, time.Now().Format("20060102150405"), 5*time.Minute)
if !replay.Val() {
service.Error(ctx, errors.New("有导入任务正在进行,请稍后再试"))
return
}
defer cache.RedisClient.Del(lockKey)
tempDir := "./runtime/report"
_, err = utils.CheckDirPath(tempDir, true)
if err != nil {
service.Error(ctx, err)
return
}
// 生成文件名并保存文件
fileName := fmt.Sprintf("%d_competitive_report.xlsx", time.Now().UnixMicro())
excelPath := filepath.Join(tempDir, fileName)
if err = ctx.SaveUploadedFile(excelFile, excelPath); err != nil {
service.Error(ctx, err)
return
}
// 打开Excel文件
excelData, err := excelize.OpenFile(excelPath)
if err != nil {
service.Error(ctx, err)
return
}
defer excelData.Close()
// 解析Excel中的数据
rows, err := excelData.GetRows("Sheet1")
if err != nil {
service.Error(ctx, err)
return
}
// 初始化请求结构
req := cast.ImportCompetitiveReportBatchReq{
Reports: make([]*cast.CreateCompetitiveReportReq, 0),
}
// 生成结果文件URL
urlHost := config.AppConfig.System.FieeHost
urlResult := fmt.Sprintf("%s/api/fiee/static/report/%s", urlHost, fileName)
// 记录每行数据对应的Excel行号用于后续匹配失败记录
reportRowMap := make(map[*cast.CreateCompetitiveReportReq]int)
for line, row := range rows {
// 跳过表头
if line == 0 {
continue
}
// 跳过空行
if len(row) == 0 {
continue
}
// 创建报告请求对象
temp := &cast.CreateCompetitiveReportReq{
Source: 2, // 来源2 导入
}
// 记录Excel行号line+1是因为Excel行号从1开始且跳过表头
excelRowNum := line + 1
reportRowMap[temp] = excelRowNum
// 解析艺人编号B列row[1]
var artistNum string
if len(row) > 1 && utils.CleanString(row[1]) != "" {
artistNum = utils.CleanString(row[1])
artistSubNum := utils.CleanString(row[1])
if artistSubNum == "" {
temp.Remark = "艺人编号不能为空"
req.Reports = append(req.Reports, temp)
continue
}
var subInfoResp *accountFiee.UserInfoResponse
subInfoResp, err := service.AccountFieeProvider.SubNumGetInfo(context.Background(), &accountFiee.SubNumGetInfoRequest{
SubNum: artistSubNum,
Domain: "app",
})
if err != nil {
temp.Remark = fmt.Sprintf("自媒体用户查询失败:%s", err.Error())
zap.L().Error("AccountFieeProvider.SubNumGetInfo", zap.Error(err))
req.Reports = append(req.Reports, temp)
continue
}
if subInfoResp == nil || subInfoResp.Id == 0 {
temp.Remark = "自媒体用户不存在"
zap.L().Error("AccountFieeProvider.SubNumGetInfo user not found", zap.String("subNum", artistSubNum))
req.Reports = append(req.Reports, temp)
continue
}
// 设置艺人信息
temp.SubNum = artistSubNum
temp.ArtistID = fmt.Sprint(subInfoResp.Id)
temp.ArtistName = subInfoResp.Name
temp.ArtistPhone = subInfoResp.TelNum
// 这里根据 ArtistID 查询竞品报告余额
artistID, _ := strconv.ParseUint(temp.ArtistID, 10, 64)
if _, err = CheckUserBundleBalance(int32(artistID), modelCast.BalanceTypeCompetitiveValue); err != nil {
if err != nil && err.Error() == e.ErrorBalanceInsufficient {
temp.Remark = "该艺人竞品报告可用次数为0"
req.Reports = append(req.Reports, temp)
continue
}
if err != nil {
temp.Remark = errors.New("查询竞品报告余额失败").Error()
req.Reports = append(req.Reports, temp)
continue
}
}
}
// 解析标题C列row[2]
if len(row) > 2 {
temp.Title = utils.CleanString(row[2])
}
// 解析报告内容D列row[3]
if len(row) > 3 {
temp.ReportContent = row[3]
}
// 解析图片URLE列row[4]
if len(row) > 4 && utils.CleanString(row[4]) != "" {
temp.ImageUrl = utils.CleanString(row[4])
}
// 解析PDF URLF列row[5]),可选
if len(row) > 5 && utils.CleanString(row[5]) != "" {
temp.PdfUrl = utils.CleanString(row[5])
}
// 验证必填字段
if artistNum == "" {
temp.Remark = "艺人编号不能为空"
req.Reports = append(req.Reports, temp)
continue
}
if temp.PdfUrl == "" {
temp.Remark = "PDF URL不能为空"
req.Reports = append(req.Reports, temp)
continue
}
req.Reports = append(req.Reports, temp)
}
// 检查是否有数据
if len(req.Reports) == 0 {
service.Error(ctx, errors.New(e.ErrNoData))
return
}
// 调用批量导入接口
newCtx := NewCtxWithUserInfo(ctx)
resp, err := service.CastProvider.ImportCompetitiveReportBatch(newCtx, &req)
if err != nil {
service.Error(ctx, err)
return
}
// 如果有失败的数据,生成结果文件
if resp.FailCount > 0 {
hasValueRows := make(map[int]bool, resp.FailCount)
// 遍历响应结果,标记失败的行
// resp.Reports的顺序应该与req.Reports的顺序一致
for i, v := range resp.Reports {
if !v.Success {
// 根据索引找到对应的请求对象
if i < len(req.Reports) {
reqReport := req.Reports[i]
// 通过请求对象找到对应的Excel行号
if excelRowNum, ok := reportRowMap[reqReport]; ok {
// 将错误信息写入最后一列G列可根据实际模板调整
excelData.SetCellValue("Sheet1", fmt.Sprintf("G%d", excelRowNum), v.Remark)
hasValueRows[excelRowNum] = true
}
}
}
}
// 删除成功的行(从后往前删除,避免行号变化)
for i := len(rows) - 1; i >= 1; i-- {
if !hasValueRows[i+1] {
if err = excelData.RemoveRow("Sheet1", i+1); err != nil {
continue
}
}
}
// 保存结果文件
resultPath := fmt.Sprintf("./runtime/report/%s", fileName)
if err = excelData.SaveAs(resultPath); err != nil {
service.Error(ctx, err)
return
}
}
// 返回结果
service.Success(ctx, map[string]interface{}{
"successCount": resp.SuccessCount,
"failCount": resp.FailCount,
"resultUrl": urlResult,
})
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
}
// ListCompetitiveReportByArtistUuid 根据艺人UUID获取竞品报告列表必须传ArtistUuid
func ListCompetitiveReportByArtistUuid(ctx *gin.Context) {
var req *cast.ListCompetitiveReportReq
var err error
if err = ctx.ShouldBind(&req); err != nil {
service.Error(ctx, err)
return
}
// 验证ArtistUuid必须存在
if req.ArtistUuid == "" {
service.Error(ctx, errors.New("ArtistUuid不能为空"))
return
}
// 复用ListCompetitiveReport的逻辑
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.CompetitiveExtendConsumptionNumber >= balanceInfoRes.CompetitiveExtendNumber {
confirmRemark = "数据分析余量不足"
isFailed = true
}
addBalanceReq.CompetitiveConsumptionNumber = 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
}