|
|
@@ -1,10 +1,13 @@
|
|
|
package proj
|
|
|
|
|
|
import (
|
|
|
+ "context"
|
|
|
projDao "dashoo.cn/micro/app/dao/proj"
|
|
|
+ model "dashoo.cn/micro/app/model/proj"
|
|
|
"dashoo.cn/micro/app/service"
|
|
|
"database/sql"
|
|
|
"fmt"
|
|
|
+ "github.com/360EntSecGroup-Skylar/excelize"
|
|
|
"github.com/gogf/gf/container/gset"
|
|
|
"github.com/gogf/gf/frame/g"
|
|
|
"github.com/gogf/gf/os/gcron"
|
|
|
@@ -12,7 +15,9 @@ import (
|
|
|
"github.com/gogf/gf/os/gtime"
|
|
|
"github.com/gogf/gf/text/gstr"
|
|
|
"github.com/gogf/gf/util/gconv"
|
|
|
+ "github.com/smallnest/rpcx/share"
|
|
|
"strings"
|
|
|
+ "time"
|
|
|
)
|
|
|
|
|
|
// 初始化,创建每10分钟执行一次的定时任务
|
|
|
@@ -20,6 +25,9 @@ func init() {
|
|
|
// 定时任务
|
|
|
spec := "0 0 9 * * *" // 每天凌晨9点执行
|
|
|
gcron.AddSingleton(spec, businessFollowRun)
|
|
|
+ //定时任务
|
|
|
+ specs := "0 0 0 * * 1 *" //每周一一点
|
|
|
+ gcron.AddSingleton(specs, businesspeopleUpReminder)
|
|
|
}
|
|
|
|
|
|
// businessFollowRun 项目跟进超时任务逻辑
|
|
|
@@ -164,6 +172,127 @@ func businessFollowOverdueSalesAssociate(tenant string, userIds []string) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// 项目每周进行一次超期三天未跟进统计表,每周给销售助理发一次邮件
|
|
|
+func businesspeopleUpReminder() {
|
|
|
+
|
|
|
+ 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
|
|
|
+ salesAssociate := []string{}
|
|
|
+ for _, config := range configs {
|
|
|
+ if config["config_key"].String() == "SalesAssociate" {
|
|
|
+ salesAssociate = strings.Split(config["config_value"].String(), ",")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var list []*model.ProjBusinessRes
|
|
|
+ var listA []*model.ProjBusinessRes
|
|
|
+ var listB []*model.ProjBusinessRes
|
|
|
+ var listC []*model.ProjBusinessRes
|
|
|
+ now := gtime.Now().StartOfDay()
|
|
|
+ LastWeekDay := now.AddDate(0, 0, -8)
|
|
|
+ LastTwoWeekDay := now.AddDate(0, 0, -15)
|
|
|
+ LastMonthDay := now.AddDate(0, -1, -1)
|
|
|
+ err = projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusA).
|
|
|
+ WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastWeekDay).OrderDesc("id").Scan(&listA)
|
|
|
+ if err != nil {
|
|
|
+ g.Log().Error("获取A类超期3天未跟进项目", err)
|
|
|
+ }
|
|
|
+ if len(listA) > 0 {
|
|
|
+ list = append(list, listA...)
|
|
|
+ }
|
|
|
+ err = projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusB).
|
|
|
+ WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastTwoWeekDay).OrderDesc("id").Scan(&listB)
|
|
|
+ if err != nil {
|
|
|
+ g.Log().Error("获取B类超期3天未跟进项目", err)
|
|
|
+ }
|
|
|
+ if len(listB) > 0 {
|
|
|
+ list = append(list, listB...)
|
|
|
+ }
|
|
|
+ err = projDao.NewProjBusinessDao(tenant).Where(projDao.ProjBusiness.C.NboType, StatusC).
|
|
|
+ WhereLTE(projDao.ProjBusiness.C.FinalFollowTime, LastMonthDay).OrderDesc("id").Scan(&listC)
|
|
|
+ if err != nil {
|
|
|
+ g.Log().Error("获取C类超期3天未跟进项目", err)
|
|
|
+ }
|
|
|
+ if len(listC) > 0 {
|
|
|
+ list = append(list, listC...)
|
|
|
+ }
|
|
|
+ if err != nil {
|
|
|
+ g.Log().Error("获取未跟进项目", err)
|
|
|
+ }
|
|
|
+ ctx := context.WithValue(context.TODO(), share.ReqMetaDataKey, map[string]string{"tenant": tenant})
|
|
|
+ rsp, err := service.GetDictDataByType(ctx, "proj_nbo_type")
|
|
|
+ if err != nil {
|
|
|
+ g.Log().Error("项目类别数据字典", err)
|
|
|
+ }
|
|
|
+ if err != nil {
|
|
|
+ g.Log().Error("获取未跟进项目", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var msg string
|
|
|
+ if len(list) > 0 {
|
|
|
+ msg += fmt.Sprintf("您有超期3天未跟进项目%v个,请登录系统查看", len(list))
|
|
|
+ }
|
|
|
+ f := excelize.NewFile()
|
|
|
+ f.MergeCell("Sheet1", "A1", "D1")
|
|
|
+ style, _ := f.NewStyle(`{"alignment":{"horizontal":"center"}}`)
|
|
|
+ f.SetCellValue("Sheet1", "A1", "超期三天未跟进项目")
|
|
|
+ f.SetCellStyle("sheet1", "A1", "D1", style)
|
|
|
+ f.SetColWidth("Sheet1", "A", "K", 20)
|
|
|
+ f.SetCellValue("Sheet1", "A2", "序号")
|
|
|
+ f.SetCellValue("Sheet1", "B2", "项目名称")
|
|
|
+ f.SetCellValue("Sheet1", "C2", "项目类别")
|
|
|
+ f.SetCellValue("Sheet1", "D2", "最新跟进时间")
|
|
|
+ line := 2
|
|
|
+ if len(list) > 0 {
|
|
|
+ for _, v := range list {
|
|
|
+ line++
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), gconv.String(line-2))
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), v.NboName)
|
|
|
+ if len(rsp) > 0 {
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), rsp[v.NboType])
|
|
|
+ } else {
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.NboType)
|
|
|
+ }
|
|
|
+ f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.FinalFollowTime)
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dir := g.Config().GetString("file.cronstatic")
|
|
|
+ filename := "项目跟进" + gconv.String(time.Now().UnixNano()) + ".xlsx"
|
|
|
+ path := dir + filename
|
|
|
+ if err = f.SaveAs(path); err != nil {
|
|
|
+ g.Log().Error("Excel保存失败", err)
|
|
|
+ }
|
|
|
+ if len(salesAssociate) > 0 {
|
|
|
+ for _, val := range salesAssociate {
|
|
|
+ if val == "" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ msgs := g.MapStrStr{
|
|
|
+ "msgTitle": "超期3天未跟进项目提醒",
|
|
|
+ "msgContent": msg,
|
|
|
+ "recvUserIds": "1",
|
|
|
+ "recvUser": "系统管理员",
|
|
|
+ "opnUrl": path,
|
|
|
+ }
|
|
|
+ if err = service.GSendMail(msgs); err != nil {
|
|
|
+ g.Log().Error("SendMail() error = %v", err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
type FollowOverdue struct {
|
|
|
SaleId int64 `json:"saleId"`
|
|
|
Count int64 `json:"count"`
|
|
|
@@ -337,3 +466,15 @@ func notifyMessage(ids, message string) {
|
|
|
glog.Error("消息提醒异常:", err)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+type alignment struct {
|
|
|
+ horizontal string `json:"horizontal"`
|
|
|
+ indent int `json:"indent"`
|
|
|
+ justifylastline bool `json:"justify_last_line"`
|
|
|
+ readingorder uint64 `json:"reading_order"`
|
|
|
+ relativeindent int `json:"relative_indent"`
|
|
|
+ shrinktofit bool `json:"shrink_to_fit"`
|
|
|
+ textrotation int `json:"text_rotation"`
|
|
|
+ vertical string `json:"vertical"`
|
|
|
+ wraptext bool `json:"wrap_text"`
|
|
|
+}
|