package proj import ( projDao "dashoo.cn/micro/app/dao/proj" "dashoo.cn/micro/app/service" "database/sql" "fmt" "github.com/gogf/gf/container/gset" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/os/gcron" "github.com/gogf/gf/os/glog" "github.com/gogf/gf/os/gtime" "github.com/gogf/gf/text/gstr" "github.com/gogf/gf/util/gconv" "strings" ) // 初始化,创建每10分钟执行一次的定时任务 func init() { // 定时任务 spec := "0 0 9 * * *" // 每天凌晨9点执行 gcron.AddSingleton(spec, businessFollowRun) } // businessFollowRun 项目跟进超时任务逻辑 func businessFollowRun() { tenant := g.Config().GetString("micro_srv.tenant") if tenant == "" { glog.Error("定时任务租户码未设置,请前往配置") return } // 从配置中获取消息提醒设置 configs, err := g.DB(tenant).Model("sys_config").Where("config_key IN ('SalesDirector','SalesAssociate')").FindAll() if err != nil && err != sql.ErrNoRows { glog.Error(err) return } // 销售总监用户Id salesDirector := []string{} // 销售助理用户Id salesAssociate := []string{} for _, config := range configs { if config["config_key"].String() == "SalesDirector" { salesDirector = strings.Split(config["config_value"].String(), ",") } else if config["config_key"].String() == "SalesAssociate" { salesAssociate = strings.Split(config["config_value"].String(), ",") } } businessFollowOverdueSalesAssociate(tenant, []string{"13"}) if len(salesDirector) > 0 { go businessFollowOverdueSalesDirector(tenant, salesDirector) } if len(salesAssociate) > 0 { go businessFollowOverdueSalesDirector(tenant, salesAssociate) } go businessFollowOverdueSalesEngineer(tenant) } // 超期3天提醒销售总监 func businessFollowOverdueSalesDirector(tenant string, userIds []string) { now := gtime.Now().StartOfDay() LastWeekDay := now.AddDate(0, 0, -10) LastTwoWeekDay := now.AddDate(0, 0, -17) LastMonthDay := now.AddDate(0, -1, -3) businessACount, err := projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusA). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastWeekDay).Count() if err != nil { g.Log().Error("获取A类超期3天未跟进项目", err) } businessBCount, err := projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusB). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastTwoWeekDay).Count() if err != nil { g.Log().Error("获取B类超期3天未跟进项目", err) } businessCCount, err := projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusC). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastMonthDay).Count() if err != nil { g.Log().Error("获取C类超期3天未跟进项目", err) } var msg string if businessACount > 0 { msg += fmt.Sprintf("您有超期3天未跟进A类项目%v个,", businessACount) } if businessBCount > 0 { msg += fmt.Sprintf("您有超期3天未跟进B类项目%v个,", businessBCount) } if businessCCount > 0 { msg += fmt.Sprintf("您有超期3天未跟进C类项目%v个,", businessCCount) } if msg != "" { businessNotifyMessage(userIds, gstr.TrimRightStr(msg, ",")) } } // 超期1天后,超期3天 提醒销售助理 func businessFollowOverdueSalesAssociate(tenant string, userIds []string) { now := gtime.Now().StartOfDay() LastWeekDay := now.AddDate(0, 0, -8) LastTwoWeekDay := now.AddDate(0, 0, -15) LastMonthDay := now.AddDate(0, -1, -1) LastWeekTridDay := now.AddDate(0, 0, -10) LastTwoWeekTridDay := now.AddDate(0, 0, -17) LastMonthTridDay := now.AddDate(0, -1, -3) businessATridCount, err := projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusA). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastWeekDay).Count() if err != nil { g.Log().Error("获取A类超期3天未跟进项目", err) } businessBTridCount, err := projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusB). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastTwoWeekDay).Count() if err != nil { g.Log().Error("获取B类超期3天未跟进项目", err) } businessCTridCount, err := projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusC). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastMonthDay).Count() if err != nil { g.Log().Error("获取C类超期3天未跟进项目", err) } businessACount, err := projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusA). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastWeekDay).WhereGTE(projDao.ProjBusiness.C.FinalFollowTime, LastWeekTridDay). Count() if err != nil { g.Log().Error("获取A类超期1天未跟进项目", err) } businessBCount, err := projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusB). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastTwoWeekDay).WhereGTE(projDao.ProjBusiness.C.FinalFollowTime, LastTwoWeekTridDay). Count() if err != nil { g.Log().Error("获取B类超期1天未跟进项目", err) } businessCCount, err := projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusC). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastMonthDay).WhereGTE(projDao.ProjBusiness.C.FinalFollowTime, LastMonthTridDay). Count() if err != nil { g.Log().Error("获取C类超期1天未跟进项目", err) } var msg string if businessATridCount > 0 { msg += fmt.Sprintf("您有超期3天未跟进A类项目%v个,", businessATridCount) } if businessBTridCount > 0 { msg += fmt.Sprintf("您有超期3天未跟进B类项目%v个,", businessBTridCount) } if businessCTridCount > 0 { msg += fmt.Sprintf("您有超期3天未跟进C类项目%v个,", businessCTridCount) } if businessACount > 0 { msg += fmt.Sprintf("您有超期1天未跟进A类项目%v个,", businessACount) } if businessBCount > 0 { msg += fmt.Sprintf("您有超期1天未跟进B类项目%v个,", businessBCount) } if businessCCount > 0 { msg += fmt.Sprintf("您有超期1天未跟进C类项目%v个,", businessCCount) } if msg != "" { businessNotifyMessage(userIds, gstr.TrimRightStr(msg, ",")) } } type FollowOverdue struct { SaleId int64 `json:"saleId"` Count int64 `json:"count"` } // 在到达超期时间前3天进行提醒、当天进行提醒,这两次提醒只提醒销售工程师, 超期1天后提醒 func businessFollowOverdueSalesEngineer(tenant string) { now := gtime.Now().StartOfDay() // 超期一天 LastWeekOneDay := now.AddDate(0, 0, -8) LastTwoWeekOneDay := now.AddDate(0, 0, -15) LastMonthOneDay := now.AddDate(0, -1, -1) // 超期当天 LastWeekCurrentDay := now.AddDate(0, 0, -7) LastTwoWeekCurrentDay := now.AddDate(0, 0, -14) LastMonthCurrentDay := now.AddDate(0, -1, 0) // 在到达超期时间前3天进行提醒 LastWeekBeforeTridDay := now.AddDate(0, 0, -4) LastTwoWeekBeforeTridDay := now.AddDate(0, 0, -11) LastMonthBeforeTridDay := now.AddDate(0, -1, 3) LastWeekOneCount, LastTwoWeekOneCount, LastMonthOneCount := make([]FollowOverdue, 0), make([]FollowOverdue, 0), make([]FollowOverdue, 0) LastWeekCurrentCount, LastTwoWeekCurrentCount, LastMonthCurrentCount := make([]FollowOverdue, 0), make([]FollowOverdue, 0), make([]FollowOverdue, 0) LastWeekBeforeTridCount, LastTwoWeekBeforeTridCount, LastMonthBeforeTridCount := make([]FollowOverdue, 0), make([]FollowOverdue, 0), make([]FollowOverdue, 0) err := projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusA). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastWeekOneDay). Fields("sale_id, count(id) as count").Group("sale_id").OrderAsc("sale_id").Scan(&LastWeekOneCount) if err != nil { g.Log().Error("获取A类超期一天未跟进项目", err) } err = projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusB). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastTwoWeekOneDay). Fields("sale_id, count(id) as count").Group("sale_id").OrderAsc("sale_id").Scan(&LastTwoWeekOneCount) if err != nil { g.Log().Error("获取B类超期一天未跟进项目", err) } err = projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusC). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastMonthOneDay). Fields("sale_id, count(id) as count").Group("sale_id").OrderAsc("sale_id").Scan(&LastMonthOneCount) if err != nil { g.Log().Error("获取C类超期一天未跟进项目", err) } err = projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusA). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastWeekCurrentDay). WhereGTE(projDao.ProjBusiness.C.FinalFollowTime, LastWeekOneDay). Fields("sale_id, count(id) as count").Group("sale_id").OrderAsc("sale_id").Scan(&LastWeekCurrentCount) if err != nil { g.Log().Error("获取A类超期当天未跟进项目", err) } err = projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusB). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastTwoWeekCurrentDay). WhereGTE(projDao.ProjBusiness.C.FinalFollowTime, LastTwoWeekOneDay). Fields("sale_id, count(id) as count").Group("sale_id").OrderAsc("sale_id").Scan(&LastTwoWeekCurrentCount) if err != nil { g.Log().Error("获取B类超期当天未跟进项目", err) } err = projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusC). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastMonthCurrentDay). WhereGTE(projDao.ProjBusiness.C.FinalFollowTime, LastMonthOneDay). Fields("sale_id, count(id) as count").Group("sale_id").OrderAsc("sale_id").Scan(&LastMonthCurrentCount) if err != nil { g.Log().Error("获取C类超期当天未跟进项目", err) } err = projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusA). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastWeekBeforeTridDay). WhereGTE(projDao.ProjBusiness.C.FinalFollowTime, LastWeekCurrentDay). Fields("sale_id, count(id) as count").Group("sale_id").OrderAsc("sale_id").Scan(&LastWeekBeforeTridCount) if err != nil { g.Log().Error("获取A类超期当天未跟进项目", err) } err = projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusB). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastTwoWeekBeforeTridDay). WhereGTE(projDao.ProjBusiness.C.FinalFollowTime, LastTwoWeekCurrentDay). Fields("sale_id, count(id) as count").Group("sale_id").OrderAsc("sale_id").Scan(&LastTwoWeekBeforeTridCount) if err != nil { g.Log().Error("获取B类超期当天未跟进项目", err) } err = projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusC). WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastMonthBeforeTridDay). WhereGTE(projDao.ProjBusiness.C.FinalFollowTime, LastMonthCurrentDay). Fields("sale_id, count(id) as count").Group("sale_id").OrderAsc("sale_id").Scan(&LastMonthBeforeTridCount) if err != nil { g.Log().Error("获取C类超期当天未跟进项目", err) } allSaleIds := gset.NewStrSet(true) saleIds, lastWeekOneCountMap := handleSalesEngineerData(LastWeekOneCount) allSaleIds = allSaleIds.Union(saleIds) saleIds, LastTwoWeekOneCountMap := handleSalesEngineerData(LastTwoWeekOneCount) allSaleIds = allSaleIds.Union(saleIds) saleIds, LastMonthOneCountMap := handleSalesEngineerData(LastMonthOneCount) allSaleIds = allSaleIds.Union(saleIds) saleIds, LastWeekCurrentCountMap := handleSalesEngineerData(LastWeekCurrentCount) allSaleIds = allSaleIds.Union(saleIds) saleIds, LastTwoWeekCurrentCountMap := handleSalesEngineerData(LastTwoWeekCurrentCount) allSaleIds = allSaleIds.Union(saleIds) saleIds, LastMonthCurrentCountMap := handleSalesEngineerData(LastMonthCurrentCount) allSaleIds = allSaleIds.Union(saleIds) saleIds, LastWeekBeforeTridCountMap := handleSalesEngineerData(LastWeekBeforeTridCount) allSaleIds = allSaleIds.Union(saleIds) saleIds, LastTwoWeekBeforeTridCountMap := handleSalesEngineerData(LastTwoWeekBeforeTridCount) allSaleIds = allSaleIds.Union(saleIds) saleIds, LastMonthBeforeTridCountMap := handleSalesEngineerData(LastMonthBeforeTridCount) allSaleIds = allSaleIds.Union(saleIds) for _, saleId := range allSaleIds.Slice() { var msg string if lastWeekOneCountMap[saleId] != "" { msg += fmt.Sprintf("您有超期1天未跟进A类项目%v个,", lastWeekOneCountMap[saleId]) } if LastTwoWeekOneCountMap[saleId] != "" { msg += fmt.Sprintf("您有超期1天未跟进B类项目%v个,", LastTwoWeekOneCountMap[saleId]) } if LastMonthOneCountMap[saleId] != "" { msg += fmt.Sprintf("您有超期1天未跟进C类项目%v个,", LastMonthOneCountMap[saleId]) } if LastWeekCurrentCountMap[saleId] != "" { msg += fmt.Sprintf("您今天有超期未跟进A类项目%v个,", LastWeekCurrentCountMap[saleId]) } if LastTwoWeekCurrentCountMap[saleId] != "" { msg += fmt.Sprintf("您今天有超期未跟进B类项目%v个,", LastTwoWeekCurrentCountMap[saleId]) } if LastMonthCurrentCountMap[saleId] != "" { msg += fmt.Sprintf("您今天有超期未跟进C类项目%v个,", LastMonthCurrentCountMap[saleId]) } if LastWeekBeforeTridCountMap[saleId] != "" { msg += fmt.Sprintf("您3天后有超期未跟进A类项目%v个,", LastWeekBeforeTridCountMap[saleId]) } if LastTwoWeekBeforeTridCountMap[saleId] != "" { msg += fmt.Sprintf("您3天后有超期未跟进B类项目%v个,", LastTwoWeekBeforeTridCountMap[saleId]) } if LastMonthBeforeTridCountMap[saleId] != "" { msg += fmt.Sprintf("您3天后有超期未跟进C类项目%v个,", LastMonthBeforeTridCountMap[saleId]) } if msg != "" { businessNotifyMessage([]string{saleId}, gstr.TrimRightStr(msg, ",")) } } } func handleSalesEngineerData(countData []FollowOverdue) (saleIds *gset.StrSet, data g.MapStrStr) { saleIds = gset.NewStrSet(true) data = make(g.MapStrStr) for _, v := range countData { saleId := gconv.String(v.SaleId) saleIds.Add(saleId) data[saleId] = gconv.String(v.Count) } return } // 项目跟进的消息通知 func businessNotifyMessage(userIds []string, message string) { ids := strings.Join(userIds, ",") // 调用统一的消息通知方式 notifyMessage(ids, message) } // notifyMessage 发送消息通知 func notifyMessage(ids, message string) { msg := g.MapStrStr{ "msgTitle": "项目跟进超期提醒", "msgContent": message, "msgType": "20", "recvUserIds": ids, "msgStatus": "10", "sendType": "10,20,30,40", } if err := service.CreateSystemMessage(msg); err != nil { glog.Error("消息提醒异常:", err) } }