package db import ( "context" "fmt" "reflect" "strings" "time" "youngee_b_api/consts" "youngee_b_api/model/common_model" "youngee_b_api/model/gorm_model" "youngee_b_api/model/http_model" "youngee_b_api/pack" "youngee_b_api/util" "github.com/issue9/conv" "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) func CreateProject(ctx context.Context, projectInfo gorm_model.ProjectInfo) (*string, error) { db := GetWriteDB(ctx) err := db.Create(&projectInfo).Error if err != nil { return nil, err } return &projectInfo.ProjectID, nil } func UpdateProject(ctx context.Context, project gorm_model.ProjectInfo) (*string, error) { db := GetReadDB(ctx) err := db.Model(&project).Updates(project).Error if err != nil { return nil, err } return &project.ProjectID, nil } func DeleteProject(ctx context.Context, projectID string) (*string, error) { db := GetReadDB(ctx) err := db.Where("project_id = ?", projectID).Delete(&gorm_model.ProjectInfo{}).Error if err != nil { return nil, err } return &projectID, nil } func GetFullProjectList(ctx context.Context, enterpriseID string, pageSize, pageNum int32, condition *common_model.ProjectCondition) ([]*gorm_model.ProjectInfo, int64, error) { db := GetReadDB(ctx) // 根据企业id过滤 db = db.Debug().Model(gorm_model.ProjectInfo{}).Where("enterprise_id = ? and project_status <> 1", enterpriseID) // 根据Project条件过滤 conditionType := reflect.TypeOf(condition).Elem() conditionValue := reflect.ValueOf(condition).Elem() for i := 0; i < conditionType.NumField(); i++ { field := conditionType.Field(i) tag := field.Tag.Get("condition") value := conditionValue.FieldByName(field.Name) if (tag == "project_id" || tag == "project_name") && !util.IsBlank(value) { db = db.Where(fmt.Sprintf("project_id like '%%%v%%' or project_name like '%%%v%%'", value.Interface(), value.Interface())) } else if tag == "updated_at" && value.Interface() != "0" { //db = db.Where(fmt.Sprintf("%s > ?", tag), value.Interface()) db = db.Where(fmt.Sprintf("updated_at like '%s%%'", value.Interface())) } else if !util.IsBlank(value) && tag != "updated_at" { db = db.Where(fmt.Sprintf("%s = ?", tag), value.Interface()) } } // 查询总数 var total int64 var fullProjects []*gorm_model.ProjectInfo if err := db.Count(&total).Error; err != nil { logrus.WithContext(ctx).Errorf("[GetFullProjectList] error query mysql total, err:%+v", err) return nil, 0, err } // 查询该页数据 limit := pageSize offset := pageSize * pageNum // assert pageNum start with 0 err := db.Order("updated_at desc").Limit(int(limit)).Offset(int(offset)).Find(&fullProjects).Error if err != nil { logrus.WithContext(ctx).Errorf("[GetFullProjectList] error query mysql total, err:%+v", err) return nil, 0, err } return fullProjects, total, nil } func GetProjectDraftList(ctx context.Context, enterpriseID string, pageSize, pageNum int32, condition *common_model.ProjectCondition) ([]*gorm_model.ProjectInfo, int64, error) { db := GetReadDB(ctx) // 根据企业id过滤 db = db.Debug().Model(gorm_model.ProjectInfo{}).Where("enterprise_id = ?", enterpriseID) // 根据Project条件过滤 conditionType := reflect.TypeOf(condition).Elem() conditionValue := reflect.ValueOf(condition).Elem() for i := 0; i < conditionType.NumField(); i++ { field := conditionType.Field(i) tag := field.Tag.Get("condition") value := conditionValue.FieldByName(field.Name) if (tag == "project_id" || tag == "project_name") && !util.IsBlank(value) { db = db.Where(fmt.Sprintf("project_id like '%%%v%%' or project_name like '%%%v%%'", value.Interface(), value.Interface())) } else if tag == "updated_at" && value.Interface() != "0" { //db = db.Where(fmt.Sprintf("%s > ?", tag), value.Interface()) db = db.Where(fmt.Sprintf("updated_at like '%s%%'", value.Interface())) } else if !util.IsBlank(value) && tag != "updated_at" { db = db.Where(fmt.Sprintf("%s = ?", tag), value.Interface()) } } // 查询总数 var total int64 var projectDrafts []*gorm_model.ProjectInfo if err := db.Count(&total).Error; err != nil { logrus.WithContext(ctx).Errorf("[GetProjectDraftList] error query mysql total, err:%+v", err) return nil, 0, err } // 查询该页数据 limit := pageSize offset := pageSize * pageNum // assert pageNum start with 0 err := db.Order("updated_at desc").Limit(int(limit)).Offset(int(offset)).Find(&projectDrafts).Error if err != nil { logrus.WithContext(ctx).Errorf("[GetProjectDraftList] error query mysql total, err:%+v", err) return nil, 0, err } return projectDrafts, total, nil } func GetProjectTaskList(ctx context.Context, pageSize, pageNum int64, conditions *common_model.TaskConditions) ([]*http_model.ProjectTaskInfo, int64, error) { db := GetReadDB(ctx) // 查询task表信息 db = db.Debug().Model(gorm_model.YoungeeTaskInfo{}) // 根据Project条件过滤 conditionType := reflect.TypeOf(conditions).Elem() conditionValue := reflect.ValueOf(conditions).Elem() var platform_nickname string = "" for i := 0; i < conditionType.NumField(); i++ { field := conditionType.Field(i) tag := field.Tag.Get("condition") value := conditionValue.FieldByName(field.Name) if !util.IsBlank(value) && tag != "platform_nickname" { db = db.Where(fmt.Sprintf("%s = ?", tag), value.Interface()) } else if tag == "platform_nickname" { platform_nickname = fmt.Sprintf("%v", value.Interface()) continue } } var taskInfos []gorm_model.YoungeeTaskInfo db = db.Model(gorm_model.YoungeeTaskInfo{}) // 查询总数 var totalTask int64 if err := db.Count(&totalTask).Error; err != nil { logrus.WithContext(ctx).Errorf("[GetProjectTaskList] error query mysql total, err:%+v", err) return nil, 0, err } db.Order("task_id").Find(&taskInfos) // 查询该页数据 limit := pageSize offset := pageSize * pageNum // assert pageNum start with 0 err := db.Order("task_id").Limit(int(limit)).Offset(int(offset)).Error if err != nil { logrus.WithContext(ctx).Errorf("[GetProjectTaskList] error query mysql total, err:%+v", err) return nil, 0, err } var taskDatas []*http_model.ProjectTaskInfo var newTaskDatas []*http_model.ProjectTaskInfo taskDatas = pack.TaskAccountToTaskInfo(taskInfos) for _, v := range taskDatas { if platform_nickname == "" { newTaskDatas = append(newTaskDatas, v) } else if strings.Contains(v.PlatformNickname, platform_nickname) { newTaskDatas = append(newTaskDatas, v) } else if strings.Contains(v.TaskID, platform_nickname) { newTaskDatas = append(newTaskDatas, v) } else { totalTask-- } } return newTaskDatas, totalTask, nil } func GetProjectDetail(ctx context.Context, projectID string) (*gorm_model.ProjectInfo, error) { db := GetReadDB(ctx) var ProjectDetail *gorm_model.ProjectInfo //fmt.Printf("项目ID:%+v", projectID) err := db.Where("project_id = ?", projectID).First(&ProjectDetail).Error if err != nil { if err == gorm.ErrRecordNotFound { return nil, nil } else { return nil, err } } //fmt.Printf("项目详情:%+v", ProjectDetail) return ProjectDetail, nil } func GetProjectPhoto(ctx context.Context, ProjectID string) ([]gorm_model.ProjectPhoto, error) { db := GetReadDB(ctx) ProjectPhoto := []gorm_model.ProjectPhoto{} err := db.Where("project_id=?", ProjectID).Find(&ProjectPhoto).Error if err != nil { return nil, err } return ProjectPhoto, nil } func GetRecruitStrategys(ctx context.Context, ProjectID string) ([]gorm_model.RecruitStrategy, error) { db := GetReadDB(ctx) RecruitStrategys := []gorm_model.RecruitStrategy{} err := db.Where("project_id=?", ProjectID).Find(&RecruitStrategys).Error if err != nil { return nil, err } return RecruitStrategys, nil } func UpdateProjectStatus(ctx context.Context, projectId string, status int64) error { db := GetReadDB(ctx) t := time.Now() err := db.Model(gorm_model.ProjectInfo{}). Where("project_id = ?", projectId).Updates(gorm_model.ProjectInfo{ProjectStatus: status, PayAt: &t}).Error if err != nil { log.Println("DB UpdateProjectStatus error :", err) return err } return nil } func GetFeeDetail(ctx context.Context, enterpriseID string, EndTime string) (*http_model.FeeDetailPreview, error) { db := GetReadDB(ctx) // 根据企业id过滤 db = db.Debug().Model(gorm_model.ProjectInfo{}).Where("enterprise_id = ? AND project_status = 10", enterpriseID) if EndTime != "" { db = db.Where("updated_at like ?", EndTime+"%") } var projectInfos []gorm_model.ProjectInfo db = db.Order("updated_at desc").Find(&projectInfos) FeeDetailPreview := http_model.FeeDetailPreview{} for _, projectInfo := range projectInfos { FeeDetailData := new(http_model.FeeDetailData) FeeDetailData.ProjectID = projectInfo.ProjectID FeeDetailData.ProjectName = projectInfo.ProjectName FeeDetailData.ProjectType = consts.GetProjectType(projectInfo.ProjectType) FeeDetailData.Payment = conv.MustString(projectInfo.PaymentAmount, "") FeeDetailData.UpdatedAt = conv.MustString(projectInfo.UpdatedAt)[0:19] FeeDetailPreview.FeeDetailData = append(FeeDetailPreview.FeeDetailData, FeeDetailData) } return &FeeDetailPreview, nil } func SetProjectFinish(ctx context.Context, projectId string) error { db := GetReadDB(ctx) var finishedNum int64 var unfinishedNum int64 db.Model(gorm_model.YoungeeTaskInfo{}).Where("project_id = ? AND task_status = 2 AND task_stage < 15", projectId).Count(&unfinishedNum) db.Model(gorm_model.YoungeeTaskInfo{}).Where("project_id = ? and task_status = 2 and task_stage >= 15", projectId).Count(&finishedNum) if unfinishedNum == 0 && finishedNum != 0 { // 2. 释放企业账户因项目冻结的资金 // 1) 计算剩余资金 db1 := GetReadDB(ctx) var allPayment float64 var realPayment float64 err := db1.Model(gorm_model.YoungeeTaskInfo{}). Where("project_id = ? and task_status = 2 and task_stage >= 15", projectId).Pluck("COALESCE(SUM(all_payment), 0) as allPayment", &allPayment).Error if err != nil { log.Println("DB GetAutoCaseCloseTask error in data:", err) return err } err = db1.Model(gorm_model.YoungeeTaskInfo{}).Select("sum(real_payment) as realPayment"). Where("project_id = ? and task_status = 2 and task_stage >= 15", projectId).Pluck("COALESCE(SUM(real_payment), 0) as realPayment", &realPayment).Error if err != nil { log.Println("DB GetAutoCaseCloseTask error in data:", err) return err } fmt.Println("企业应支付金额总计:", allPayment, "实际支付总计:", realPayment) db2 := GetReadDB(ctx) var enterpriseID int64 db2.Model(gorm_model.ProjectInfo{}).Select("enterprise_id").Where("project_id = ?", projectId).Find(&enterpriseID) // 2). 释放剩余资金 err = db1.Model(gorm_model.Enterprise{}).Where("enterprise_id = ?", enterpriseID).Updates( map[string]interface{}{ "frozen_balance": gorm.Expr("frozen_balance - ?", allPayment), "balance": gorm.Expr("balance - ?", realPayment), "available_balance": gorm.Expr("available_balance + ?", allPayment-realPayment)}).Error if err != nil { log.Println("DB GetAutoCaseCloseTask error in data:", err) return err } // 1. 更新项目状态为已结束 t := time.Now() err = db.Model(gorm_model.ProjectInfo{}).Where("project_id = ?", projectId).Updates(gorm_model.ProjectInfo{ProjectStatus: 10, PaymentAmount: realPayment, FinishAt: &t}).Error if err != nil { logrus.WithContext(ctx).Errorf("[Project db] Update ProjectInfo error,err:%+v", err) return err } } return nil } func SetSpecialProjectFinish(ctx context.Context, projectId string) error { db := GetReadDB(ctx) var finishedNum int64 var unfinishedNum int64 db.Model(gorm_model.YoungeeTaskInfo{}).Where("project_id = ? AND task_status = 2 AND task_stage < 15", projectId).Count(&unfinishedNum) db.Model(gorm_model.YoungeeTaskInfo{}).Where("project_id = ? and task_status = 2 and task_stage >= 15", projectId).Count(&finishedNum) if unfinishedNum == 0 && finishedNum != 0 { // 1. 更新项目状态为已结束 t := time.Now() err := db.Model(gorm_model.ProjectInfo{}).Where("project_id = ?", projectId).Updates(gorm_model.ProjectInfo{ProjectStatus: 10, FinishAt: &t}).Error if err != nil { logrus.WithContext(ctx).Errorf("[Project db] Update ProjectInfo error,err:%+v", err) return err } } return nil } func GetCreatingNumber(ctx context.Context, enterpriseID string) (*int64, error) { db := GetReadDB(ctx) var creatingNumber int64 err := db.Model(gorm_model.ProjectInfo{}).Where("enterprise_id = ? and project_status = 1", enterpriseID).Count(&creatingNumber).Error if err != nil { logrus.WithContext(ctx).Errorf("[Project db] Update ProjectInfo error,err:%+v", err) return nil, err } return &creatingNumber, nil } func GetProjectData(ctx context.Context, projectid string) (http_model.ProjectDataResponse, error) { db := GetReadDB(ctx) var projectInfo gorm_model.ProjectInfo // 查询项目基本信息 if err := db.Where("project_id = ?", projectid).First(&projectInfo).Error; err != nil { logrus.WithContext(ctx).Errorf("[Project db] GetProjectData error, err: %+v", err) return http_model.ProjectDataResponse{}, err } fmt.Println("projectInfo---", projectInfo.ProjectID) var projectTasks []gorm_model.YoungeeTaskInfo if err := db.Where("project_id = ? AND task_status = ?", projectid, 2).Find(&projectTasks).Error; err != nil { return http_model.ProjectDataResponse{}, err } var totalTasks int64 if err := db.Model(&gorm_model.YoungeeTaskInfo{}).Where("project_id = ? AND task_status = ?", projectid, 2).Count(&totalTasks).Error; err != nil { return http_model.ProjectDataResponse{}, err } // 初始化统计数据 dateStats := make(map[string]int) fansCounts := map[int64]int{0: 0, 1: 0, 2: 0, 3: 0} feeCounts := map[int]int{1: 0, 2: 0, 3: 0} startDate := *projectInfo.CreatedAt endDate := time.Now() // 填充日期统计 for d := startDate; d.Before(endDate) || d.Equal(endDate); d = d.Add(24 * time.Hour) { dateStats[d.Format("2006-01-02")] = 0 } var totalCost float64 var totalFans int var serverTaskCount float64 var maleCount int64 // 处理每个任务 for _, task := range projectTasks { totalCost += task.DraftFee var talentInfo gorm_model.YoungeeTalentInfo // 查询达人信息 if err := db.Where("id = ?", task.TalentID).First(&talentInfo).Error; err != nil { logrus.WithContext(ctx).Errorf("[Project db] GetProjectData error, err: %+v", err) return http_model.ProjectDataResponse{}, err } // 统计性别 if talentInfo.Sex == 1 { maleCount++ } totalFans += task.FansNum // 统计来自服务商的任务 if task.SupplierId != 0 && task.SupplierStatus == 2 { serverTaskCount++ } // 稿费形式统计 feeCounts[task.FeeForm]++ // 统计粉丝数 switch { case task.FansNum < 10000: fansCounts[0]++ case task.FansNum < 100000: fansCounts[1]++ case task.FansNum < 1000000: fansCounts[2]++ default: fansCounts[3]++ } SelectDate := task.SelectDate.Format("2006-01-02") if _, exists := dateStats[SelectDate]; exists { dateStats[SelectDate]++ } } // 计算平均值 var avgFansNum int if totalTasks > 0 { avgFansNum = totalFans / int(totalTasks) } else { avgFansNum = 0 } var fromType float64 if totalTasks > 0 { fromType = serverTaskCount / float64(totalTasks) } else { fromType = 0 } var manRatio float64 if totalTasks > 0 { manRatio = float64(maleCount) / float64(totalTasks) } else { manRatio = 0 } // 构建响应 res := http_model.ProjectDataResponse{ Recruittime: *projectInfo.PassAt, RecruitDDl: *projectInfo.RecruitDdl, AgreeNum: projectInfo.RecruitNum, ApplyNum: projectInfo.ApplyNum, DraftFee: totalCost, AvgFansNum: avgFansNum, FromType: fromType, ManRatio: manRatio, DateStats: dateStats, FeeMap: feeCounts, FansMap: fansCounts, } return res, nil } func GetProjectExecuteData(ctx context.Context, projectid string) (http_model.ExecuteDataResponse, error) { db := GetReadDB(ctx) var projectData gorm_model.ProjectInfo // 查询项目基本信息 err := db.Model(gorm_model.ProjectInfo{}).Where("project_id = ?", projectid).First(&projectData).Error if err != nil { logrus.WithContext(ctx).Errorf("[Project db] GetProjectData error, err: %+v", err) return http_model.ExecuteDataResponse{}, err } // 查询项目任务信息 var projectTaskInfo []gorm_model.YoungeeTaskInfo query := db.Model(&gorm_model.YoungeeTaskInfo{}).Where("project_id = ? AND task_status = ?", projectid, 2).Find(&projectTaskInfo) var total int64 if err = query.Count(&total).Error; err != nil { return http_model.ExecuteDataResponse{}, err } // 初始化统计数据 skedateStats := make(map[string]int) linkdateStatics := make(map[string]int) startDate := *projectData.CreatedAt endDate := time.Now() // 填充日期统计 for d := startDate; d.Before(endDate) || d.Equal(endDate); d = d.Add(24 * time.Hour) { skedateStats[d.Format("2006-01-02")] = 0 linkdateStatics[d.Format("2006-01-02")] = 0 } var presketchnum int64 //代传初稿数 var sketchnum int64 //待审 var sketchaccnum int64 //通过 var prelinknum, linknum, linkaccnum, predatanum, datanum int64 //待传连接数,待审,通过 var duration time.Duration var accskecnt int var avgduration time.Duration var avgccreateduraion time.Duration var createduraion time.Duration var crecnt, submint, firacccnt int var firaccratio, firacclinkratio float64 var linkaccduartion, avglinkduration, backduration, avgbackdurtion time.Duration var acclinkcnt, backcnt, submintcnt, firlinkacccnt int var defaultnum int64 var defaultratio float64 var sktchinfo gorm_model.YounggeeSketchInfo var draftee, settle_amount float64 for _, task := range projectTaskInfo { draftee += task.DraftFee switch task.TaskStage { case 9: presketchnum += 1 case 10: sketchnum += 1 case 11: prelinknum += 1 case 12: linknum += 1 case 13: predatanum += 1 } if task.SketchStatus == 5 { sketchaccnum += 1 } if task.LinkStatus == 5 { linkaccnum += 1 } if task.CurDefaultType != 0 { defaultnum += 1 } if task.TaskStage == 15 { settle_amount += task.SettleAmount } if task.TaskStage > 9 { //初稿 //err = db.Model(gorm_model.YounggeeSketchInfo{}).Where("task_id = ? ", task.TaskID).First(&sktchinfo).Error err = db.Model(gorm_model.YounggeeSketchInfo{}).Where("task_id = ?", task.TaskID).Order("create_at ASC").First(&sktchinfo).Error if err != nil { return http_model.ExecuteDataResponse{}, err } else { if projectData.ProjectForm == 1 { if !task.SignedTime.IsZero() { createduraion += sktchinfo.CreateAt.Sub(task.SignedTime) crecnt += 1 } } else { if sktchinfo.IsSubmit == 1 { createduraion += sktchinfo.CreateAt.Sub(task.SelectDate) crecnt += 1 } } //平均创作耗时 var sktchaccinfo gorm_model.YounggeeSketchInfo err = db.Model(gorm_model.YounggeeSketchInfo{}).Where("task_id = ?", task.TaskID).Order("create_at ASC").Last(&sktchaccinfo).Error if err != nil { return http_model.ExecuteDataResponse{}, err } if sktchaccinfo.IsOk == 1 { duration += sktchaccinfo.AgreeAt.Sub(sktchinfo.CreateAt) accskecnt += 1 //审稿耗时 submint += 1 if sktchaccinfo.SketchID == sktchinfo.SketchID { firacccnt += 1 } //首次通过 AgreeDate := sktchaccinfo.AgreeAt.Format("2006-01-02") if _, exists := skedateStats[AgreeDate]; exists { skedateStats[AgreeDate]++ } } } } if task.TaskStage > 11 { var linkinfo gorm_model.YounggeeLinkInfo //最后一次上传link err = db.Model(gorm_model.YounggeeLinkInfo{}).Where("task_id = ? ", task.TaskID).Order("create_at ASC").Last(&linkinfo).Error if err != nil { continue } else { if linkinfo.IsOk == 1 { linkaccduartion += linkinfo.AgreeAt.Sub(linkinfo.CreateAt) acclinkcnt += 1 } //平均质检时间 var linkfirinfo gorm_model.YounggeeLinkInfo //最后一次上传link err = db.Model(gorm_model.YounggeeLinkInfo{}).Where("task_id = ? ", task.TaskID).Order("create_at ASC").First(&linkfirinfo).Error if err != nil { return http_model.ExecuteDataResponse{}, err } else { backduration += linkinfo.CreateAt.Sub(sktchinfo.AgreeAt) backcnt += 1 var linklasinfo gorm_model.YounggeeLinkInfo //最后一次上传link err = db.Model(gorm_model.YounggeeLinkInfo{}).Where("task_id = ? ", task.TaskID).Order("create_at ASC").Last(&linklasinfo).Error if err != nil { return http_model.ExecuteDataResponse{}, err } if linklasinfo.IsOk == 1 { submintcnt += 1 if linklasinfo.LinkID == linkfirinfo.LinkID { firlinkacccnt += 1 } //首次通过 AgreeDate := linklasinfo.AgreeAt.Format("2006-01-02") if _, exists := linkdateStatics[AgreeDate]; exists { linkdateStatics[AgreeDate]++ } } } } } } if submint > 0 && firacccnt > 0 { firaccratio = float64(firacccnt) / float64(submint) } else { firaccratio = 0 } if submintcnt > 0 && firlinkacccnt > 0 { firacclinkratio = float64(firlinkacccnt) / float64(submintcnt) } else { firacclinkratio = 0 } if accskecnt > 0 { avgduration = duration / time.Duration(accskecnt) } else { avgduration = 0 } if crecnt > 0 { avgccreateduraion = createduraion / time.Duration(crecnt) } else { avgccreateduraion = 0 } if acclinkcnt > 0 { avglinkduration = linkaccduartion / time.Duration(acclinkcnt) } else { avglinkduration = 0 } if backcnt > 0 { avgbackdurtion = backduration / time.Duration(backcnt) } else { avgbackdurtion = 0 } if defaultnum > 0 { defaultratio = float64(defaultnum) / float64(total) } else { defaultratio = 0 } res := http_model.ExecuteDataResponse{ Excutetime: *projectData.PayAt, PreSketchNum: presketchnum, SketchNum: sketchnum, SketchAccNum: sketchaccnum, AvgAccTime: avgduration, AvgCreTime: avgccreateduraion, FirAccRatio: firaccratio, PreLinkNum: prelinknum, LinkNum: linknum, LinkAccNum: linkaccnum, AvgLinkAccTime: avglinkduration, AvgBackTime: avgbackdurtion, FirAccLinkRatio: firacclinkratio, PreDataNum: predatanum, DataNum: datanum, DefaultNum: defaultnum, DefaultRatio: defaultratio, DraftFee: draftee, Settle_Amount: settle_amount, } return res, nil } func GetProjecdata(ctx context.Context, projectid string) (http_model.ProjectdataResponse, error) { db := GetReadDB(ctx) var projectInfo gorm_model.ProjectInfo // 查询项目基本信息 if err := db.Where("project_id = ?", projectid).First(&projectInfo).Error; err != nil { logrus.WithContext(ctx).Errorf("[Project db] GetProjectData error, err: %+v", err) return http_model.ProjectdataResponse{}, err } res := http_model.ProjectdataResponse{} return res, nil }