Browse Source

草稿箱&定时任务部分

Ethan 8 months ago
parent
commit
f2b69ac473

+ 38 - 0
app/controller/task_controller.go

@@ -330,3 +330,41 @@ func (t TaskController) ProjectDel(c *gin.Context) {
 	resultMap["projectId"] = *projectId
 	returnSuccess(c, 20000, resultMap)
 }
+
+// 草稿箱——电商带货
+func (t TaskController) GetSelectionDraftList(c *gin.Context) {
+	param := &vo.SelectionDraftParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	res, err := service.SelectionInfoService{}.GetSelectionDraftList(param)
+	if err != nil {
+		logrus.Errorf("[SelectionTaskList] call Show err:%+v\n", err)
+		returnError(c, 40000, "error")
+		return
+	}
+
+	returnSuccess(c, 20000, res)
+}
+
+// 草稿箱——电商带货
+func (t TaskController) GetProjectDraftList(c *gin.Context) {
+	param := &vo.ProjectDraftParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	res, err := service.ProjectService{}.GetProjectDraftList(param)
+	if err != nil {
+		logrus.Errorf("[SelectionTaskList] call Show err:%+v\n", err)
+		returnError(c, 40000, "error")
+		return
+	}
+
+	returnSuccess(c, 20000, res)
+}

+ 21 - 0
app/dao/info_auto_default.go

@@ -0,0 +1,21 @@
+package dao
+
+import (
+	"youngee_b_api/app/entity"
+)
+
+type InfoAutoDefaultDao struct{}
+
+// 获取指定 enterpriseId 下的最新一条自动任务配置
+func (d InfoAutoDefaultDao) GetAutoDefaultLast(enterpriseId string) entity.InfoAutoDefault {
+	autoDefaultInfo := entity.InfoAutoDefault{}
+	Db.Model(&entity.InfoAutoDefault{}).Where("enterprise_id = ?", enterpriseId).Last(&autoDefaultInfo)
+	return autoDefaultInfo
+}
+
+// 获取指定 auto_default_id 的指定字段值
+func (d InfoAutoDefaultDao) GetValueByIdFieldName(autoDefaultId int64, fieldName string) entity.InfoAutoDefault {
+	autoDefaultInfo := entity.InfoAutoDefault{}
+	Db.Model(&entity.InfoAutoDefault{}).Select(fieldName).Where("auto_default_id = ?", autoDefaultId).First(&autoDefaultInfo)
+	return autoDefaultInfo
+}

+ 21 - 0
app/dao/info_auto_task.go

@@ -0,0 +1,21 @@
+package dao
+
+import (
+	"youngee_b_api/app/entity"
+)
+
+type InfoAutoTaskDao struct{}
+
+// 获取指定 enterpriseId 下的最新一条自动任务配置
+func (d InfoAutoTaskDao) GetAutoTaskLast(enterpriseId string) entity.InfoAutoTask {
+	autoTaskInfo := entity.InfoAutoTask{}
+	Db.Model(&entity.InfoAutoTask{}).Where("enterprise_id = ?", enterpriseId).Last(&autoTaskInfo)
+	return autoTaskInfo
+}
+
+// 获取指定 autoTaskId 的指定字段值
+func (d InfoAutoTaskDao) GetValueByIdFieldName(autoTaskId int64, fieldName string) entity.InfoAutoTask {
+	autoTaskInfo := entity.InfoAutoTask{}
+	Db.Model(&entity.InfoAutoTask{}).Select(fieldName).Where("auto_task_id = ?", autoTaskId).First(&autoTaskInfo)
+	return autoTaskInfo
+}

+ 57 - 2
app/dao/project_dao.go

@@ -2,6 +2,7 @@ package dao
 
 import (
 	"errors"
+	"fmt"
 	"gorm.io/gorm"
 	"time"
 	"youngee_b_api/app/entity"
@@ -10,9 +11,10 @@ import (
 
 type ProjectDAO struct{}
 
-func (d ProjectDAO) GetProjectById(ProjectId string) (*entity.Project, error) {
+// 根据projectId获取project信息
+func (d ProjectDAO) GetProjectById(projectId string) (*entity.Project, error) {
 	var Project entity.Project
-	err := Db.Where("project_id = ?", ProjectId).First(&Project).Error
+	err := Db.Where("project_id = ?", projectId).First(&Project).Error
 	if err != nil {
 		if errors.Is(err, gorm.ErrRecordNotFound) {
 			return nil, nil
@@ -123,3 +125,56 @@ func (d ProjectDAO) DeleteProject(projectId string) (*string, error) {
 	}
 	return &projectId, nil
 }
+
+// 获取草稿箱——电商带货任务列表
+func (d ProjectDAO) GetProjectDraftList(param *vo.ProjectDraftParam) ([]vo.ReProjectTaskPreview, int64, error) {
+	var reProjectTaskPreviews []vo.ReProjectTaskPreview
+	var projects []entity.Project
+	var total int64
+	query := Db.Model(&entity.Project{}).Where("project_status = ?", 1)
+	// 动态添加查询条件
+	if param.SubAccountId == 0 {
+		if param.EnterpriseId == "" {
+			return reProjectTaskPreviews, 0, errors.New("enterpriseId is empty")
+		}
+		query = query.Where("enterprise_id = ?", param.EnterpriseId)
+	} else {
+		query = query.Where("sub_account_id = ?", param.SubAccountId)
+	}
+	if param.ProjectType != 0 {
+		query = query.Where("project_type = ?", param.ProjectType)
+	}
+	if param.ProjectPlatform != 0 {
+		query = query.Where("project_platform = ?", param.ProjectPlatform)
+	}
+	query.Count(&total)
+	query = query.Select("enterprise_id, sub_account_id, project_id, project_platform, project_type, created_at, product_id")
+	offset := (param.Page - 1) * param.PageSize
+	if err := query.Order("created_at asc").Offset(offset).Limit(param.PageSize).Find(&projects).Error; err != nil {
+		return nil, 0, err
+	}
+	for _, project := range projects {
+		reProjectTaskPreview := vo.ReProjectTaskPreview{
+			EnterpriseId:    project.EnterpriseID,
+			SubAccountId:    project.SubAccountId,
+			ProjectId:       project.ProjectId,
+			ProjectPlatform: project.ProjectPlatform,
+			ProjectType:     project.ProjectType,
+			CreatedAt:       project.CreatedAt,
+			ProductId:       project.ProductID,
+		}
+		reProjectTaskPreviews = append(reProjectTaskPreviews, reProjectTaskPreview)
+	}
+
+	return reProjectTaskPreviews, total, nil
+}
+
+// 获取公开种草中全部指定状态值的项目
+func (d ProjectDAO) GetProjectList(value int64, fieldName string) ([]*entity.Project, error) {
+	var projectInfos []*entity.Project
+	err := Db.Model(entity.Project{}).Where(fmt.Sprintf("project_type = ? AND %s = ? ", fieldName), 1, value).Find(&projectInfos).Error
+	if err != nil {
+		return nil, err
+	}
+	return projectInfos, nil
+}

+ 51 - 1
app/dao/selection_info_dao.go

@@ -2,6 +2,7 @@ package dao
 
 import (
 	"errors"
+	"fmt"
 	"gorm.io/gorm"
 	"time"
 	"youngee_b_api/app/entity"
@@ -56,7 +57,7 @@ func (d SelectionInfoDAO) UpdateSelectionInfo(selectionInfo entity.SelectionInfo
 }
 
 // 获取带货任务列表
-func (d ProjectDAO) GetSelectionPreviews(param *vo.SelectionSearchParam) ([]vo.ReSelectionTaskPreview, int64, error) {
+func (d SelectionInfoDAO) GetSelectionPreviews(param *vo.SelectionSearchParam) ([]vo.ReSelectionTaskPreview, int64, error) {
 	var reSelectionTaskPreviews []vo.ReSelectionTaskPreview
 	var selectionInfos []entity.SelectionInfo
 	var total int64
@@ -125,3 +126,52 @@ func (d SelectionInfoDAO) DeleteSelection(selectionId string) (*string, error) {
 	}
 	return &selectionId, nil
 }
+
+// 获取草稿箱——电商带货任务列表
+func (d SelectionInfoDAO) GetSelectionDraftList(param *vo.SelectionDraftParam) ([]vo.ReSelectionTaskPreview, int64, error) {
+	var reSelectionTaskPreviews []vo.ReSelectionTaskPreview
+	var selectionInfos []entity.SelectionInfo
+	var total int64
+	query := Db.Model(&entity.SelectionInfo{}).Where("selection_status = ?", 1)
+	// 动态添加查询条件
+	if param.SubAccountId == 0 {
+		if param.EnterpriseId == "" {
+			return reSelectionTaskPreviews, 0, errors.New("enterpriseId is empty")
+		}
+		query = query.Where("enterprise_id = ?", param.EnterpriseId)
+	} else {
+		query = query.Where("sub_account_id = ?", param.SubAccountId)
+	}
+	if param.SelectionPlatform != 0 {
+		query = query.Where("platform = ?", param.SelectionPlatform)
+	}
+	query.Count(&total)
+	query = query.Select("enterprise_id, sub_account_id, selection_id, platform, created_at, product_id")
+	offset := (param.Page - 1) * param.PageSize
+	if err := query.Order("created_at asc").Offset(offset).Limit(param.PageSize).Find(&selectionInfos).Error; err != nil {
+		return nil, 0, err
+	}
+	for _, selectionInfo := range selectionInfos {
+		reSelectionTaskPreview := vo.ReSelectionTaskPreview{
+			EnterpriseId:      selectionInfo.EnterpriseID,
+			SubAccountId:      selectionInfo.SubAccountId,
+			SelectionId:       selectionInfo.SelectionID,
+			SelectionPlatform: selectionInfo.Platform,
+			CreatedAt:         selectionInfo.CreatedAt,
+			ProductId:         selectionInfo.ProductID,
+		}
+		reSelectionTaskPreviews = append(reSelectionTaskPreviews, reSelectionTaskPreview)
+	}
+
+	return reSelectionTaskPreviews, total, nil
+}
+
+// 获取电商带货悬赏任务中全部指定状态值的项目
+func (d SelectionInfoDAO) GetSelectionInfoList(value int64, fieldName string) ([]*entity.SelectionInfo, error) {
+	var selectionInfos []*entity.SelectionInfo
+	err := Db.Model(entity.SelectionInfo{}).Where(fmt.Sprintf("task_mode = ? AND %s = ? ", fieldName), 1, value).Find(&selectionInfos).Error
+	if err != nil {
+		return nil, err
+	}
+	return selectionInfos, nil
+}

+ 28 - 0
app/entity/info_auto_default.go

@@ -0,0 +1,28 @@
+package entity
+
+// Code generated by sql2gorm. DO NOT EDIT.
+
+type InfoAutoDefault struct {
+	AutoDefaultID          int64 `gorm:"column:auto_default_id;primary_key;AUTO_INCREMENT"` // 自动处理规则id
+	EnterpriseId           int64 `gorm:"column:enterprise_id"`                              // 企业id
+	SketchReplaceNotUpload int64 `gorm:"column:sketch_replace_not_upload"`                  // 初稿违约 产品置换 未上传初稿
+	SketchReplaceTimeOut   int64 `gorm:"column:sketch_replace_time_out"`                    // 初稿违约 产品置换 超时未上传初稿
+	SketchOtherNotUpload   int64 `gorm:"column:sketch_other_not_upload"`                    // 初稿违约 自报价、固定稿费 未上传初稿
+	SketchOtherTimeOut     int64 `gorm:"column:sketch_other_time_out"`                      // 初稿违约 自报价、固定稿费 超时未上传初稿
+	ScriptReplaceNotUpload int64 `gorm:"column:script_replace_not_upload"`                  // 脚本违约 产品置换 未上传脚本
+	ScriptReplaceTimeOut   int64 `gorm:"column:script_replace_time_out"`                    // 脚本违约 产品置换 超时未上传脚本
+	ScriptOtherNotUpload   int64 `gorm:"column:script_other_not_upload"`                    // 脚本违约 自报价、固定稿费 未上传脚本
+	ScriptOtherTimeOut     int64 `gorm:"column:script_other_time_out"`                      // 脚本违约 自报价、固定稿费 超时未上传脚本
+	LinkReplaceNotUpload   int64 `gorm:"column:link_replace_not_upload"`                    // 链接违约 产品置换 未上传链接
+	LinkReplaceTimeOut     int64 `gorm:"column:link_replace_time_out"`                      // 链接违约 产品置换 超时未上传链接
+	LinkOtherNotUpload     int64 `gorm:"column:link_other_not_upload"`                      // 链接违约 自报价、固定稿费 未上传链接
+	LinkOtherTimeOut       int64 `gorm:"column:link_other_time_out"`                        // 链接违约 自报价、固定稿费 超时未上传链接
+	DataReplaceNotUpload   int64 `gorm:"column:data_replace_not_upload"`                    // 数据违约 产品置换 未上传数据
+	DataReplaceTimeOut     int64 `gorm:"column:data_replace_time_out"`                      // 数据违约 产品置换 超时未上传数据
+	DataOtherNotUpload     int64 `gorm:"column:data_other_not_upload"`                      // 数据违约 自报价、固定稿费 未上传数据
+	DataOtherTimeOut       int64 `gorm:"column:data_other_time_out"`                        // 数据违约 自报价、固定稿费 超时未上传数据
+}
+
+func (m *InfoAutoDefault) TableName() string {
+	return "info_auto_default_handle"
+}

+ 23 - 0
app/entity/info_auto_task.go

@@ -0,0 +1,23 @@
+package entity
+
+type InfoAutoTask struct {
+	AutoTaskID        int64 `gorm:"column:auto_task_id;primary_key;AUTO_INCREMENT"` // 自动处理规则id
+	EnterpriseId      int64 `gorm:"column:enterprise_id"`                           // 企业id
+	SignInOffline     int64 `gorm:"column:sign_in_offline"`                         // 线下探店自动签收时间
+	SignInVirtual     int64 `gorm:"column:sign_in_virtual"`                         // 虚拟产品测评自动签收时间
+	ReviewInMv        int64 `gorm:"column:review_in_mv"`                            // 视频形式的审稿处理
+	ReviewUnlimited   int64 `gorm:"column:review_unlimited"`                        // 不限形式的审稿处理
+	PostReview        int64 `gorm:"column:post_review"`                             // 发布审核自动处理
+	CaseClose         int64 `gorm:"column:case_close"`                              // 结案自动处理
+	Invalid           int64 `gorm:"column:invalid"`                                 // 全流程项目失效自动处理
+	DraftDefaultInPic int64 `gorm:"column:draft_default_in_pic"`                    // 图片初稿违约自动处理
+	DraftDefaultInMv  int64 `gorm:"column:draft_default_in_mv"`                     // 视频初稿违约自动处理
+	ScriptDefault     int64 `gorm:"column:script_default"`                          // 脚本违约自动处理
+	LinkBreach        int64 `gorm:"column:link_breach"`                             // 链接违约自动处理
+	CaseCloseDefault  int64 `gorm:"column:case_close_default"`                      // 结案违约自动处理
+	SelectionInvalid  int64 `gorm:"column:selection_invalid"`                       // 选品项目失效自动处理
+}
+
+func (m *InfoAutoTask) TableName() string {
+	return "info_auto_task"
+}

+ 48 - 0
app/entity/project_task_info.go

@@ -0,0 +1,48 @@
+package entity
+
+import (
+	"time"
+)
+
+type ProjectTaskInfo struct {
+	TaskID                 string    `gorm:"column:task_id;primary_key;AUTO_INCREMENT"`   // 任务id
+	ProjectID              string    `gorm:"column:project_id;NOT NULL"`                  // 项目id
+	TalentID               string    `gorm:"column:talent_id;NOT NULL"`                   // 达人id
+	AccountID              int       `gorm:"column:account_id;NOT NULL"`                  // 账号id
+	TalentPlatformInfoSnap string    `gorm:"column:talent_platform_info_snap;NOT NULL"`   // 达人平台信息快照
+	TalentPersonalInfoSnap string    `gorm:"column:talent_personal_info_snap;NOT NULL"`   // 达人个人信息快照
+	TalentPostAddrSnap     string    `gorm:"column:talent_post_addr_snap;NOT NULL"`       // 收货地址快照
+	StrategyID             int       `gorm:"column:strategy_id"`                          // 报名选择的招募策略id
+	TaskReward             float64   `gorm:"column:task_reward;NOT NULL"`                 // 达人报酬
+	SettleAmount           float64   `gorm:"column:settle_amount;NOT NULL"`               // 达人实际所得(扣除违约扣款)
+	AllPayment             float64   `gorm:"column:all_payment;NOT NULL"`                 // 企业支付
+	RealPayment            float64   `gorm:"column:real_payment;NOT NULL"`                // 企业实际支付(扣除违约扣款)
+	ErrBreakRate           int       `gorm:"column:err_break_rate;default:0;NOT NULL"`    // 未上传类型违约扣款比例,百分之
+	ScriptBreakRate        int       `gorm:"column:script_break_rate;default:0;NOT NULL"` // 脚本上传超时违约扣款比例,百分之
+	SketchBreakRate        int       `gorm:"column:sketch_break_rate;default:0;NOT NULL"` // 初稿上传超时违约扣款比例,百分之
+	LinkBreakRate          int       `gorm:"column:link_break_rate;default:0;NOT NULL"`   // 链接上传超时违约扣款比例,百分之
+	DataBreakRate          int       `gorm:"column:data_break_rate;default:0;NOT NULL"`   // 数据上传超时违约扣款比例,百分之
+	FeeForm                int       `gorm:"column:fee_form;NOT NULL"`                    // 稿费形式,1,2,3分别代表产品置换、固定稿费、自报价
+	ServiceCharge          float64   `gorm:"column:service_charge"`                       // 服务费
+	ServiceRate            int       `gorm:"column:service_rate"`                         // 服务费率,千分之
+	TaskStatus             int       `gorm:"column:task_status;default:1;NOT NULL"`       // 任务状态 1待选 2已选 3落选
+	TaskStage              int       `gorm:"column:task_stage;NOT NULL"`                  // 任务阶段,详情见info_task_stage表
+	CreateDate             time.Time `gorm:"column:create_date;NOT NULL"`                 // 创建时间
+	SelectDate             time.Time `gorm:"column:select_date"`                          // 反选时间
+	DeliveryDate           time.Time `gorm:"column:delivery_date"`                        // 发货时间
+	CompleteStatus         int       `gorm:"column:complete_status;default:1;NOT NULL"`   // 结束方式 1未结束 2正常结束 3反选失败 4被解约
+	CompleteDate           time.Time `gorm:"column:complete_date"`                        // 结束时间
+	LogisticsStatus        int       `gorm:"column:logistics_status;default:1"`           // 发货状态 1 待发货 2已发货 3 已签收
+	ScriptStatus           uint      `gorm:"column:script_status;default:1"`              // 脚本上传状态 1-5分别代表待添加、已添加、待修改、已修改、已通过
+	SketchStatus           uint      `gorm:"column:sketch_status;default:1"`              // 初稿上传状态 1-5分别代表待添加、已添加、待修改、已修改、已通过
+	UpdateAt               time.Time `gorm:"column:update_at"`                            // 更新时间
+	LinkStatus             uint      `gorm:"column:link_status;default:1"`                // 链接上传状态 1-5分别代表待添加、已添加、待修改、已修改、已通过
+	DataStatus             uint      `gorm:"column:data_status;default:1"`                // 数据上传状态 1-5分别代表待添加、已添加、待修改、已修改、已通过
+	CurDefaultType         int       `gorm:"column:cur_default_type"`                     // 任务当前处于的违约类型 0-8分别表示未违约、脚本超时违约、脚本未上传违约、初稿超时违约、初稿未上传违约、链接超时违约、链接未上传违约、数据超时违约、数据未上传违约
+	WithdrawStatus         int       `gorm:"column:withdraw_status;default:1"`            // 提现状态,1-4分别代表不可提现、可提现、提现中、已提现
+	SettleStatus           int       `gorm:"column:settle_status;default:1"`              // 结算状态,1、2分别表示待结算、已结算
+}
+
+func (m *ProjectTaskInfo) TableName() string {
+	return "youngee_task_info"
+}

+ 44 - 0
app/entity/selection_task_info.go

@@ -0,0 +1,44 @@
+package entity
+
+// Code generated by sql2gorm. DO NOT EDIT.
+
+import (
+	"time"
+)
+
+type SelectionTaskInfo struct {
+	ID                     int       `gorm:"column:id;primary_key"`              // 递增id
+	TaskID                 string    `gorm:"column:task_id"`                     // 选品任务id
+	SelectionID            string    `gorm:"column:selection_id"`                // 选品id
+	TalentID               string    `gorm:"column:talent_id"`                   // 达人id
+	AccountID              int       `gorm:"column:account_id"`                  // 账号id
+	TalentPlatformInfoSnap string    `gorm:"column:talent_platform_info_snap"`   // 达人平台信息快照
+	TalentPersonalInfoSnap string    `gorm:"column:talent_personal_info_snap"`   // 达人个人信息快照
+	TalentPostAddrSnap     string    `gorm:"column:talent_post_addr_snap"`       // 收货地址快照
+	TaskReward             string    `gorm:"column:task_reward"`                 //  达人赏金
+	TalentPayment          string    `gorm:"column:talent_payment"`              // 达人垫付金额
+	IsPayPayment           int       `gorm:"column:is_pay_payment"`              // 企业是否返样品钱
+	IsPayReward            int       `gorm:"column:is_pay_reward"`               // 企业是否结算悬赏
+	TaskMode               int       `gorm:"column:task_mode"`                   // 任务形式,1、2分别表示纯佣带货、悬赏任务
+	SampleMode             int       `gorm:"column:sample_mode"`                 // 领样形式,1-3分别表示免费领样、垫付买样、不提供样品
+	TaskStatus             int       `gorm:"column:task_status;default:1"`       // 任务状态 1待选 2已选 3落选
+	TaskStage              int       `gorm:"column:task_stage"`                  // 任务阶段,详情见info_sec_task_stage表
+	CreateDate             time.Time `gorm:"column:create_date"`                 // 创建时间
+	SelectDate             time.Time `gorm:"column:select_date"`                 // 反选时间
+	DeliveryDate           time.Time `gorm:"column:delivery_date"`               // 发货时间
+	CompleteDate           time.Time `gorm:"column:complete_date"`               // 结束时间
+	WithdrawDate           time.Time `gorm:"column:withdraw_date"`               // 提现时间
+	CompleteStatus         int       `gorm:"column:complete_status;default:1"`   // 结束方式 1未结束 2正常结束 3反选失败
+	LogisticsStatus        int       `gorm:"column:logistics_status;default:1"`  // 发货状态 1 待发货 2已发货 3 已签收
+	AssignmentStatus       uint      `gorm:"column:assignment_status;default:1"` // 作业上传状态 1-5分别代表待添加、已添加、待修改、已修改、已通过
+	UpdateAt               time.Time `gorm:"column:update_at"`                   // 更新时间
+	WithdrawStatus         int       `gorm:"column:withdraw_status;default:1"`   // 提现状态,1-4分别代表不可提现、可提现、提现中、已提现
+	LeadTeamID             string    `gorm:"column:lead_team_id"`                // 作为团长的young之团id,对应younggee_talent_team中的team_id字段
+	TeamID                 string    `gorm:"column:team_id"`                     // 作为团员的young之团id,对应younggee_talent_team中的team_id字段
+	TeamIncome             int       `gorm:"column:team_income"`                 // young之团团长现金收益
+	TeamPoint              int       `gorm:"column:team_point"`                  // young之团团长积分收益
+}
+
+func (m *SelectionTaskInfo) TableName() string {
+	return "younggee_sec_task_info"
+}

+ 102 - 0
app/schedule/auto_task.go

@@ -0,0 +1,102 @@
+package schedule
+
+import (
+	"fmt"
+	"github.com/caixw/lib.go/conv"
+	"github.com/robfig/cron/v3"
+	"log"
+	"time"
+	"youngee_b_api/app/dao"
+	"youngee_b_api/app/entity"
+)
+
+func AutoTask() error {
+	// 新建一个定时任务对象
+	crontab := cron.New(cron.WithSeconds()) // 精确到秒
+	spec := "0 */1 * * * ?"                 //cron表达式,每10h一次
+	// "0 0 12 * * ?" 每天中午12点执行
+
+	// 添加定时任务
+	// 定时任务1  品牌种草失效自动处理
+	_, err1 := crontab.AddFunc(spec, AutoInvalidTask)
+	if err1 != nil {
+		return err1
+	}
+	// 定时任务2  电商带货失效自动处理
+	_, err2 := crontab.AddFunc(spec, AutoSelectionInvalidTask)
+	if err2 != nil {
+		return err2
+	}
+
+	// 启动定时器
+	crontab.Start()
+	// 定时任务是另起协程执行的,这里使用 select 简单阻塞.需要根据实际情况进行控制
+	//select {} //阻塞主线程停止
+	return nil
+}
+
+// 定时任务1  品牌种草失效自动处理
+func AutoInvalidTask() {
+	log.Println("AutoInvalidTask running Start, Time :", time.Now())
+	var projectInfos []*entity.Project
+	projectInfos, _ = dao.ProjectDAO{}.GetProjectList(6, "project_status")
+	// 对于所有未支付的品牌种草项目进行处理
+	for _, projectInfo := range projectInfos {
+		projectId := projectInfo.ProjectId
+		autoTaskId := projectInfo.AutoTaskID
+		autoTaskInfo := dao.InfoAutoTaskDao{}.GetValueByIdFieldName(autoTaskId, "invalid")
+		dd, _ := time.ParseDuration(conv.MustString(autoTaskInfo.Invalid, "") + "h")
+		// 失效时间计算:任务截止时间 + 设置的失效自动执行时间
+		timeInvalid := projectInfo.RecruitDdl.Add(dd)
+		if projectInfo.AutoFailAt.IsZero() {
+			dao.Db.Model(&entity.Project{}).Where("project_id = ?", projectId).Updates(&entity.Project{AutoFailAt: timeInvalid})
+		}
+		projectNeedMod := entity.Project{}
+		dao.Db.Where("project_id = ?", projectId).First(&projectNeedMod)
+		fmt.Println("品牌种草项目失效自动处理时间为:", projectNeedMod.AutoFailAt)
+		// 如果失效自动处理的时间不为空
+		if !projectNeedMod.AutoFailAt.IsZero() {
+			timeNow := time.Now()
+			// 如果 未失效 && 已经过了失效自动处理的时间
+			if projectNeedMod.ProjectStatus < 8 && projectNeedMod.AutoFailAt.Sub(time.Now()) <= 0 {
+				dao.Db.Model(entity.Project{}).Where("project_id = ?", projectId).Updates(&entity.Project{ProjectStatus: 8, FinishAt: timeInvalid, FailReason: 1})
+				fmt.Println("已更新品牌种草项目状态为超时未支付的失效状态")
+				dao.Db.Model(entity.ProjectTaskInfo{}).Where("project_id = ?", projectId).Updates(entity.ProjectTaskInfo{TaskStage: 3, CompleteStatus: 3, CompleteDate: timeNow})
+			}
+		}
+	}
+	log.Println("AutoInvalidTask running End, Time :", time.Now())
+}
+
+// 定时任务2  电商带货失效自动处理
+func AutoSelectionInvalidTask() {
+	log.Println("AutoSelectionInvalidTask running Start, Time :", time.Now())
+	var selectionInfos []*entity.SelectionInfo
+	selectionInfos, _ = dao.SelectionInfoDAO{}.GetSelectionInfoList(4, "selection_status")
+	// 对于所有未支付的电商带货项目进行处理
+	for _, selectionInfo := range selectionInfos {
+		selectionId := selectionInfo.SelectionID
+		autoTaskId := selectionInfo.AutoTaskID
+		autoTaskInfo := dao.InfoAutoTaskDao{}.GetValueByIdFieldName(autoTaskId, "selection_invalid")
+		dd, _ := time.ParseDuration(conv.MustString(autoTaskInfo.SelectionInvalid, "") + "h")
+		// 失效时间计算:任务截止时间 + 设置的失效自动执行时间
+		timeInvalid := selectionInfo.PassAt.Add(dd)
+		if selectionInfo.AutoFailAt.IsZero() {
+			dao.Db.Model(&entity.SelectionInfo{}).Where("selection_id = ?", selectionId).Updates(&entity.SelectionInfo{AutoFailAt: timeInvalid})
+		}
+		selectionInfoNeedMod := entity.SelectionInfo{}
+		dao.Db.Where("selection_id = ?", selectionId).First(&selectionInfoNeedMod)
+		fmt.Println("电商带货项目失效自动处理时间为:", selectionInfoNeedMod.AutoFailAt)
+		// 如果失效自动处理的时间不为空
+		if !selectionInfoNeedMod.AutoFailAt.IsZero() {
+			timeNow := time.Now()
+			// 如果 未失效 && 已经过了失效自动处理的时间
+			if selectionInfoNeedMod.SelectionStatus < 5 && selectionInfoNeedMod.AutoFailAt.Sub(time.Now()) <= 0 {
+				dao.Db.Model(entity.SelectionInfo{}).Where("selection_id = ?", selectionId).Updates(&entity.SelectionInfo{SelectionStatus: 7, FinishAt: timeInvalid, FailReason: 1})
+				fmt.Println("已更新电商带货项目状态为超时未支付的失效状态")
+				dao.Db.Model(entity.SelectionInfo{}).Where("selection_id = ?", selectionId).Updates(entity.SelectionTaskInfo{TaskStage: 3, CompleteStatus: 3, CompleteDate: timeNow})
+			}
+		}
+	}
+	log.Println("AutoSelectionInvalidTask running End, Time :", time.Now())
+}

+ 56 - 0
app/service/project_service.go

@@ -37,6 +37,11 @@ func (s ProjectService) CreateProject(param *vo.ProjectCreateParam) (*string, er
 	} else {
 		operatorType = 2
 	}
+	// 获取定时任务配置id
+	infoAutoTask := entity.InfoAutoTask{}
+	infoAutoTask = dao.InfoAutoTaskDao{}.GetAutoTaskLast(param.EnterpriseId)
+	infoAutoDefault := entity.InfoAutoDefault{}
+	infoAutoDefault = dao.InfoAutoDefaultDao{}.GetAutoDefaultLast(param.EnterpriseId)
 	t := time.Now()
 	newProject := entity.Project{
 		ProjectStatus:    1,
@@ -50,6 +55,8 @@ func (s ProjectService) CreateProject(param *vo.ProjectCreateParam) (*string, er
 		ProductSnap:      string(productInfoToJson),
 		ProductPhotoSnap: string(productPhotosToJson),
 		CreatedAt:        t,
+		AutoTaskID:       infoAutoTask.AutoTaskID,
+		AutoDefaultID:    infoAutoDefault.AutoDefaultID,
 	}
 	if param.ProjectType == 1 {
 		newProject.ServiceChargeRate = param.ServiceChargeRate
@@ -522,3 +529,52 @@ func (s ProjectService) DeleteProject(projectId string) (*string, error) {
 	}
 	return res, nil
 }
+
+// 草稿箱——品牌种草
+func (s ProjectService) GetProjectDraftList(param *vo.ProjectDraftParam) (vo.ResultVO, error) {
+	if param.Page == 0 {
+		param.Page = 1
+	}
+	if param.PageSize == 0 {
+		param.PageSize = 10
+	}
+	var result vo.ResultVO
+	reSelectionTaskPreviews, total, err := (&dao.ProjectDAO{}).GetProjectDraftList(param)
+	if err != nil {
+		return result, err
+	}
+	for i := range reSelectionTaskPreviews {
+		var creatorName string
+		var productName string
+		var productPrice float64
+		var mainImage string
+		if reSelectionTaskPreviews[i].SubAccountId == 0 {
+			enterprise, err := dao.EnterpriseDao{}.GetEnterprise(reSelectionTaskPreviews[i].EnterpriseId)
+			if err == nil && enterprise != nil {
+				creatorName = enterprise.BusinessName
+			}
+		} else {
+			subAccount, err := dao.SubAccountDao{}.GetSubAccount(reSelectionTaskPreviews[i].SubAccountId)
+			if err == nil && subAccount != nil {
+				creatorName = subAccount.SubAccountName
+			}
+		}
+		product, err := dao.ProductDAO{}.GetProductByID(reSelectionTaskPreviews[i].ProductId)
+		if err == nil && product != nil {
+			productName = product.ProductName
+			productPrice = product.ProductPrice
+		}
+		mainImage, err = dao.ProductPhotoDAO{}.GetMainPhotoByProductID(reSelectionTaskPreviews[i].ProductId)
+		reSelectionTaskPreviews[i].CreatorName = creatorName
+		reSelectionTaskPreviews[i].ProductName = productName
+		reSelectionTaskPreviews[i].ProductPrice = productPrice
+		reSelectionTaskPreviews[i].MainImage = mainImage
+	}
+	result = vo.ResultVO{
+		Page:     param.Page,
+		PageSize: param.PageSize,
+		Total:    total,
+		Data:     reSelectionTaskPreviews,
+	}
+	return result, nil
+}

+ 55 - 7
app/service/selection_info_service.go

@@ -3,7 +3,6 @@ package service
 import (
 	"encoding/json"
 	"errors"
-	"github.com/caixw/lib.go/conv"
 	"github.com/sirupsen/logrus"
 	"reflect"
 	"time"
@@ -56,7 +55,7 @@ func (s SelectionInfoService) CreateSelectionInfo(param *vo.SelectionInfoCreateP
 	// a) 生成选品id
 	selectionId := util.GetSelectionID()
 	// b) 查找关联商品信息
-	product, err := dao.ProductDAO{}.GetProductByID(conv.MustInt64(param.ProductId, 0))
+	product, err := dao.ProductDAO{}.GetProductByID(param.ProductId)
 	if err != nil {
 		return nil, err
 	}
@@ -69,6 +68,9 @@ func (s SelectionInfoService) CreateSelectionInfo(param *vo.SelectionInfoCreateP
 	// c) 选品名称
 	//selectionName := product.ProductName
 	// d)创建选品
+	// 获取定时任务配置
+	infoAutoTask := entity.InfoAutoTask{}
+	infoAutoTask = dao.InfoAutoTaskDao{}.GetAutoTaskLast(param.EnterpriseId)
 	t := time.Now()
 	newSelection := entity.SelectionInfo{
 		SelectionStatus:  1,
@@ -81,10 +83,7 @@ func (s SelectionInfoService) CreateSelectionInfo(param *vo.SelectionInfoCreateP
 		ProductPhotoSnap: string(productPhotosToJson),
 		CreatedAt:        t,
 		UpdatedAt:        t,
-		CommissionRate:   0,
-		EstimatedCost:    0,
-		TaskReward:       0,
-		SettlementAmount: 0,
+		AutoTaskID:       infoAutoTask.AutoTaskID,
 	}
 	err = dao.SelectionInfoDAO{}.CreateSelectionInfo(newSelection)
 	if err != nil {
@@ -409,7 +408,7 @@ func (s SelectionInfoService) GetSelectionTaskList(param *vo.SelectionSearchPara
 		param.PageSize = 10
 	}
 	var result vo.ResultVO
-	reSelectionTaskPreviews, total, err := (&dao.ProjectDAO{}).GetSelectionPreviews(param)
+	reSelectionTaskPreviews, total, err := (&dao.SelectionInfoDAO{}).GetSelectionPreviews(param)
 	if err != nil {
 		return result, err
 	}
@@ -464,3 +463,52 @@ func (s SelectionInfoService) DeleteSelection(selectionId string) (*string, erro
 	}
 	return res, nil
 }
+
+// 草稿箱——电商带货
+func (s SelectionInfoService) GetSelectionDraftList(param *vo.SelectionDraftParam) (vo.ResultVO, error) {
+	if param.Page == 0 {
+		param.Page = 1
+	}
+	if param.PageSize == 0 {
+		param.PageSize = 10
+	}
+	var result vo.ResultVO
+	reSelectionTaskPreviews, total, err := (&dao.SelectionInfoDAO{}).GetSelectionDraftList(param)
+	if err != nil {
+		return result, err
+	}
+	for i := range reSelectionTaskPreviews {
+		var creatorName string
+		var productName string
+		var productPrice float64
+		var mainImage string
+		if reSelectionTaskPreviews[i].SubAccountId == 0 {
+			enterprise, err := dao.EnterpriseDao{}.GetEnterprise(reSelectionTaskPreviews[i].EnterpriseId)
+			if err == nil && enterprise != nil {
+				creatorName = enterprise.BusinessName
+			}
+		} else {
+			subAccount, err := dao.SubAccountDao{}.GetSubAccount(reSelectionTaskPreviews[i].SubAccountId)
+			if err == nil && subAccount != nil {
+				creatorName = subAccount.SubAccountName
+			}
+		}
+		product, err := dao.ProductDAO{}.GetProductByID(reSelectionTaskPreviews[i].ProductId)
+		if err == nil && product != nil {
+			productName = product.ProductName
+			productPrice = product.ProductPrice
+		}
+		mainImage, err = dao.ProductPhotoDAO{}.GetMainPhotoByProductID(reSelectionTaskPreviews[i].ProductId)
+		reSelectionTaskPreviews[i].CreatorName = creatorName
+		reSelectionTaskPreviews[i].ProductName = productName
+		reSelectionTaskPreviews[i].ProductPrice = productPrice
+		reSelectionTaskPreviews[i].MainImage = mainImage
+	}
+	result = vo.ResultVO{
+		Page:     param.Page,
+		PageSize: param.PageSize,
+		Total:    total,
+		Data:     reSelectionTaskPreviews,
+	}
+	return result, nil
+}

+ 12 - 0
app/vo/project_draft_param.go

@@ -0,0 +1,12 @@
+package vo
+
+type ProjectDraftParam struct {
+	EnterpriseId    string `json:"enterprise_id"`
+	SubAccountId    int64  `json:"sub_account_id"`
+	Page            int    `json:"page"`
+	PageSize        int    `json:"page_size"`
+	ProjectPlatform int64  `json:"project_platform"` // 平台,1-7分别代表小红书、抖音、微博、快手、b站、大众点评、知乎
+	ProjectType     int64  `json:"project_type"`     // 项目类型 1全流程 2专项
+
+	//ProjectId string `json:"project_id"` // 任务ID
+}

+ 16 - 12
app/vo/re_project_task_preview.go

@@ -1,21 +1,25 @@
 package vo
 
+import "time"
+
 type ReProjectTaskPreview struct {
 	ProductId    int64   `json:"productId"`
 	MainImage    string  `json:"mainImage"`
 	ProductName  string  `json:"productName"`
 	ProductPrice float64 `json:"productPrice"`
 
-	EnterpriseId    string  `json:"enterpriseId"`
-	SubAccountId    int64   `json:"subAccountId"`
-	ProjectId       string  `json:"projectId"`
-	ProjectPlatform int64   `json:"projectPlatform"`
-	ProjectStatus   int64   `json:"projectStatus"`
-	EstimatedCost   float64 `json:"estimatedCost"`
-	ProjectForm     int64   `json:"projectForm"`
-	ContentType     int64   `json:"contentType"`
-	NeedReview      int64   `json:"needReview"`
-	NeedQuality     int64   `json:"needQuality"`
-	NeedCalculate   int64   `json:"needCalculate"`
-	CreatorName     string  `json:"creatorName"`
+	EnterpriseId    string    `json:"enterpriseId"`
+	SubAccountId    int64     `json:"subAccountId"`
+	ProjectId       string    `json:"projectId"`
+	ProjectPlatform int64     `json:"projectPlatform"`
+	ProjectStatus   int64     `json:"projectStatus"`
+	EstimatedCost   float64   `json:"estimatedCost"`
+	ProjectForm     int64     `json:"projectForm"`
+	ContentType     int64     `json:"contentType"`
+	NeedReview      int64     `json:"needReview"`
+	NeedQuality     int64     `json:"needQuality"`
+	NeedCalculate   int64     `json:"needCalculate"`
+	CreatorName     string    `json:"creatorName"`
+	ProjectType     int64     `json:"projectType"`
+	CreatedAt       time.Time `json:"createdAt"`
 }

+ 22 - 0
app/vo/re_task_default_public.go

@@ -0,0 +1,22 @@
+package vo
+
+type ReTaskDefaultPublic struct {
+	ProductId    int64   `json:"productId"`
+	MainImage    string  `json:"mainImage"`
+	ProductName  string  `json:"productName"`
+	ProductPrice float64 `json:"productPrice"`
+
+	EnterpriseId     string `json:"enterpriseId"`
+	SubAccountId     int64  `json:"subAccountId"`
+	TaskId           string `json:"taskId"`
+	TaskType         string `json:"taskType"` // 任务类型
+	Platform         int64  `json:"platform"`
+	TaskForm         int64  `json:"taskForm"`    // 任务形式
+	ContentType      int64  `json:"contentType"` // 内容形式
+	CreatorName      string `json:"creatorName"`
+	NoSketchNum      int64  `json:"sampleNum"` // 未传初稿
+	NoLinkNum        int64  `json:"reward"`    // 未发作品
+	NoDataNum        int64  `json:"enrollNum"` // 未传数据
+	NoCooperationNum int64  `json:"chooseNum"` // 终止合作
+
+}

+ 20 - 0
app/vo/re_task_default_target.go

@@ -0,0 +1,20 @@
+package vo
+
+type ReTaskDefaultTarget struct {
+	ProductId    int64   `json:"productId"`
+	MainImage    string  `json:"mainImage"`
+	ProductName  string  `json:"productName"`
+	ProductPrice float64 `json:"productPrice"`
+
+	EnterpriseId     string `json:"enterpriseId"`
+	SubAccountId     int64  `json:"subAccountId"`
+	TaskId           string `json:"taskId"`
+	TaskType         string `json:"taskType"` // 任务类型
+	Platform         int64  `json:"platform"`
+	TaskForm         int64  `json:"taskForm"`    // 任务形式
+	ContentType      int64  `json:"contentType"` // 内容形式
+	CreatorName      string `json:"creatorName"`
+	Tools            string `json:"tools"`     // 工具选择
+	NoCooperationNum int64  `json:"chooseNum"` // 终止合作
+
+}

+ 11 - 0
app/vo/selection_draft_param.go

@@ -0,0 +1,11 @@
+package vo
+
+type SelectionDraftParam struct {
+	EnterpriseId      string `json:"enterprise_id"`
+	SubAccountId      int64  `json:"sub_account_id"`
+	Page              int    `json:"page"`
+	PageSize          int    `json:"page_size"`
+	SelectionPlatform int64  `json:"selection_platform"` // 平台,1-7分别代表小红书、抖音、微博、快手、b站、大众点评、知乎
+
+	//SelectionId string `json:"selection_id"` // 任务ID
+}

+ 6 - 3
main.go

@@ -2,23 +2,26 @@ package main
 
 import (
 	"fmt"
+	"github.com/gin-gonic/gin"
 	"log"
+	"youngee_b_api/app/schedule"
 	"youngee_b_api/config"
 	_ "youngee_b_api/docs"
 	"youngee_b_api/route"
 	"youngee_b_api/service"
-
-	"github.com/gin-gonic/gin"
 )
 
 func main() {
 	r := gin.Default()
 	route.InitRoute(r)
 	config := config.Init()
+	// what?
 	mailConfig := "./config/mail.json"
 	service.SMTPMailServiceIstance.Init(mailConfig)
+
 	addr := fmt.Sprintf("%v:%v", config.Host, config.Port)
-	err := service.AutoTask()
+	//err := service.AutoTask()
+	err := schedule.AutoTask()
 	if err != nil {
 		log.Println("service AutoTask error:", err)
 	}

+ 3 - 0
route/init.go

@@ -187,6 +187,9 @@ func InitRoute(r *gin.Engine) {
 		task.POST("/project/task/list", controller.TaskController{}.ProjectTaskList)         // 公开种草任务列表
 		task.POST("/project/del", controller.TaskController{}.ProjectDel)                    // 删除种草任务
 
+		task.POST("/draft/selection/list", controller.TaskController{}.GetSelectionDraftList) // 草稿箱——电商带货列表
+		task.POST("/draft/project/list", controller.TaskController{}.GetProjectDraftList)     // 草稿箱——品牌种草列表
+
 	}
 
 }